/* src: input image kSize: window size used by local average return: filtered image */ Mat Dip2::averageFilter(Mat& src, int kSize){ Mat kernel = Mat(kSize, kSize, CV_32FC1, 1.0/(kSize * kSize)); Mat copy = src.clone(); Mat result = spatialConvolution(copy, kernel); return result; }
/* in input image size size of filter kernel spatial true if convolution shall be performed in spatial domain, false otherwise return smoothed image */ Mat Dip3::mySmooth(Mat& in, int size, bool spatial){ // create filter kernel Mat kernel = createGaussianKernel(size); // perform convoltion if (spatial) return spatialConvolution(in, kernel); else return frequencyConvolution(in, kernel); }
/* src: input image kSize: window size used by local average return: filtered image */ Mat Dip2::averageFilter(Mat& src, int kSize){ Mat kernel = Mat::ones( kSize, kSize, src.type()); Mat outputImage = spatialConvolution(src, kernel); return outputImage / (float)(kSize * kSize); }
// checks basic properties of the convolution result void Dip2::test_spatialConvolution(void){ Mat input = Mat::ones(9,9, CV_32FC1); input.at<float>(4,4) = 255; Mat kernel = Mat(3,3, CV_32FC1, 1./9.); Mat output = spatialConvolution(input, kernel); if ( (input.cols != output.cols) || (input.rows != output.rows) ){ cout << "ERROR: Dip2::spatialConvolution(): input.size != output.size --> Wrong border handling?" << endl; return; } if ( (sum(output.row(0) < 0).val[0] > 0) || (sum(output.row(0) > 255).val[0] > 0) || (sum(output.row(8) < 0).val[0] > 0) || (sum(output.row(8) > 255).val[0] > 0) || (sum(output.col(0) < 0).val[0] > 0) || (sum(output.col(0) > 255).val[0] > 0) || (sum(output.col(8) < 0).val[0] > 0) || (sum(output.col(8) > 255).val[0] > 0) ){ cout << "ERROR: Dip2::spatialConvolution(): Border of convolution result contains too large/small values --> Wrong border handling?" << endl; return; }else{ if ( (sum(output < 0).val[0] > 0) || (sum(output > 255).val[0] > 0) ){ cout << "ERROR: Dip2::spatialConvolution(): Convolution result contains too large/small values!" << endl; return; } } float ref[9][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, (8+255)/9., (8+255)/9., (8+255)/9., 1, 1, 0}, {0, 1, 1, (8+255)/9., (8+255)/9., (8+255)/9., 1, 1, 0}, {0, 1, 1, (8+255)/9., (8+255)/9., (8+255)/9., 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}}; for(int y=1; y<8; y++){ for(int x=1; x<8; x++){ if (abs(output.at<float>(y,x) - ref[y][x]) > 0.0001){ cout << "ERROR: Dip2::spatialConvolution(): Convolution result contains wrong values!" << endl; return; } } } input.setTo(0); input.at<float>(4,4) = 255; kernel.setTo(0); kernel.at<float>(0,0) = -1; output = spatialConvolution(input, kernel); if ( abs(output.at<float>(5,5) + 255.) < 0.0001 ){ cout << "ERROR: Dip2::spatialConvolution(): Is filter kernel \"flipped\" during convolution? (Check lecture/exercise slides)" << endl; return; } if ( ( abs(output.at<float>(2,2) + 255.) < 0.0001 ) || ( abs(output.at<float>(4,4) + 255.) < 0.0001 ) ){ cout << "ERROR: Dip2::spatialConvolution(): Is anchor point of convolution the centre of the filter kernel? (Check lecture/exercise slides)" << endl; return; } cout << "Message: Dip2::spatialConvolution() seems to be correct" << endl; }