rendered paste bodyclass 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;
}
};