All pastes #274700 Raw Edit

Untitled

public text v1 · immutable
·published 2006-12-10 22:10 UTC
rendered paste body
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;
		}
};