class Filter { public: int **filterData; int width, height; double normCoeff; Filter(string filename) { normCoeff = 1.0; ifstream filterFile(filename.c_str()); // read in dimensions filterFile >> width >> height; // allocate a 2D array for the data filterData = (int **)malloc(sizeof(int *)*height); for(int i = 0; i < height; i++) { filterData[i] = (int *)malloc(sizeof(int)*width); } // read in the data for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { filterFile >> filterData[i][j]; } } } Filter(bool isPrewitt, bool x) { // Prewitt/Sobel constructor normCoeff = 1.0; width = 3; height = 3; // allocate a 2D array for the data filterData = (int **)malloc(sizeof(int *)*height); for(int i = 0; i < height; i++) { // zero-filled filterData[i] = (int *)calloc(width, sizeof(int)); } // set the data if(x) { // Prewitt X for(int i = 0; i < height; i++) { filterData[i][0] = -1; filterData[i][width-1] = 1; } if(!isPrewitt) { // modify to Sobel filterData[1][0] = -2; filterData[1][2] = 2; } } else { // Prewitt Y for(int i = 0; i < width; i++) { filterData[0][i] = 1; filterData[height-1][i] = -1; } if(!isPrewitt) { // modify to Sobel filterData[0][1] = 2; filterData[2][1] = -2; } } } Filter(double sigma) { // Gaussian filter constructor normCoeff = 1.0; int N_0 = (int)(2*abs(2*sigma)+1); width = N_0; height = N_0; int c_x = (width-1)/2; int c_y = (height-1)/2; // allocate a 2D array for the data filterData = (int **)malloc(sizeof(int *)*height); for(int i = 0; i < height; i++) { filterData[i] = (int *)calloc(width,sizeof(int)); } // fill in the data for(int y = -c_y; y <= c_y; y++) { for(int x = -c_x; x <= c_x; x++) { double gauss = (1/(2*PI*pow(sigma,2.0))) * exp(-((pow((double)x,2.0)+pow((double)y,2.0))/(2*pow(sigma,2.0)))); filterData[x+c_x][y+c_y] = (int)((255.0*gauss)+0.5); } } setNormalize(); } ~Filter() { for(int i = 0; i < height; i++) { free(filterData[i]); } free(filterData); } void print() { cout << width << "\t" << height << endl; for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { cout << filterData[i][j] << "\t"; } cout << endl; } } void setNormalize() { int sum = 0; for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { sum += filterData[i][j]; } } if(sum != 1) { // need to normalize normCoeff = 1.0/(double)(sum); } } IplImage *apply(IplImage *input) { IplImage *output = cvCreateImage(cvSize(input->widthStep, input->height), IPL_DEPTH_8U, 1); uint8 *inData = (uint8 *)input->imageData; uint8 *outData = (uint8 *)output->imageData; int c_x = (width-1)/2; int c_y = (height-1)/2; for(int y=0;y < output->height;++y) { for(int x=0; x < output->width; ++x ) { int sum = 0; for(int k = -c_y; k <= c_y; k++) { for(int l = -c_x; l <= c_x; l++) { if(filterData[k+c_y][l+c_x] != 0) { sum += filterData[k+c_y][l+c_x] * getValue(input,x+l,y+k); } } } int tval = (int)abs((normCoeff * (double)sum)); if(tval > 255) { // overflow tval = 255; } else if(tval < 0) { // underflow tval = 0; } outData[(y * output->widthStep) + x] = tval; } } return output; } };