📄 filter.cpp
字号:
#include <math.h>
#include <cv.h>
#include <highgui.h>
#define AVERAGE_FILTER 0
#define GAUSSIAN_FILTER 1
#define BILATERAL_FILTER 2
//#define CV_IMAGE_ELEM( image, elemtype, row, col ) \ (((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)])
int main(int argc, char *argv[])
{
IplImage* inputImage = cvLoadImage( "Original.bmp", 1 );
IplImage* outputImage = cvCloneImage( inputImage );
//IplImage* outputImageCV = cvCloneImage ( inputImage );
cvNamedWindow("INPUT", CV_WINDOW_AUTOSIZE);
cvNamedWindow("OUTPUT", CV_WINDOW_AUTOSIZE);
//cvNamedWindow("OUTPUT-CV", CV_WINDOW_AUTOSIZE);
const int windowSize = 3;
const int center = windowSize / 2;
const int filter = GAUSSIAN_FILTER;
const int sigma1 = 1;
const int sigma2 = 50;
const int WIDTH = inputImage->width;
const int HEIGHT = inputImage->height;
double div = 0;
double divR = 0;
double divG = 0;
double divB = 0;
double kernel[windowSize][windowSize];
double kernelR[windowSize][windowSize];
double kernelG[windowSize][windowSize];
double kernelB[windowSize][windowSize];
//init Kernel
for ( int row = -center; row <= center; row++ ) {
for ( int col = -center; col <= center; col++ ) {
kernel[row+center][col+center] = 0.0;
if ( filter == AVERAGE_FILTER ) {
kernel[row+center][col+center] = 1.0;
} else if ( filter == GAUSSIAN_FILTER ) {
kernel[row+center][col+center] = 1.0 / (pow(sigma1,2.0)*2*CV_PI) * exp ( -0.5 * pow(sqrt(pow(col, 2.0) + pow(row, 2.0))/sigma1, 2) );
}
div += kernel[row+center][col+center];
}
}
//convolution
for ( int r = 0; r < HEIGHT; r++ ) {
for ( int c = 0; c < WIDTH; c++ ) {
if ( filter == BILATERAL_FILTER ) {
//init the kernel for current position
divR = 0;
divG = 0;
divB = 0;
for ( int row = -center; row <= center; row++ ) {
for ( int col = -center; col <= center; col++ ) {
double tempValueG = 0;
double tempValueR = 0;
double tempValueB = 0;
if ( (r + row >= 0 && r + row < HEIGHT) && (c + col>= 0 && c + col < WIDTH)){
tempValueR = CV_IMAGE_ELEM( inputImage, UCHAR, r + row,(c + col)*3+2 );
tempValueG = CV_IMAGE_ELEM( inputImage, UCHAR, r + row,(c + col)*3+1);
tempValueB = CV_IMAGE_ELEM( inputImage, UCHAR, r + row,(c + col)*3 );
}
double domain = 1.0 / (pow(sigma1,2.0)*2*CV_PI) * exp ( -0.5 * pow(sqrt(pow(col, 2.0) + pow(row, 2.0))/sigma1, 2) );
double rangeR = 1.0 / (sigma2*sqrt(2*CV_PI)) * exp ( -0.5 * pow(( tempValueR - CV_IMAGE_ELEM( inputImage, UCHAR, r, c*3+2) )/sigma2, 2));
double rangeG = 1.0 / (sigma2*sqrt(2*CV_PI)) * exp ( -0.5 * pow(( tempValueG - CV_IMAGE_ELEM( inputImage, UCHAR, r, c*3+1) )/sigma2, 2));
double rangeB = 1.0 / (sigma2*sqrt(2*CV_PI)) * exp ( -0.5 * pow(( tempValueB - CV_IMAGE_ELEM( inputImage, UCHAR, r, c*3) )/sigma2, 2));
kernelR[row+center][col+center] = domain * rangeR;
kernelG[row+center][col+center] = domain * rangeG;
kernelB[row+center][col+center] = domain * rangeB;
divR += kernelR[row+center][col+center];
divG += kernelG[row+center][col+center];
divB += kernelB[row+center][col+center];
}
}
}
double tempG = 0;
double tempR = 0;
double tempB = 0;
if(filter == BILATERAL_FILTER){
for ( int row = -center; row <= center; row++ ) {
for ( int col = -center; col <= center; col++ ) {
double tempValueR = 0;
double tempValueG = 0;
double tempValueB = 0;
if ( (r + row >= 0 && r + row < HEIGHT) && (c + col>= 0 && c +
col < WIDTH)){
tempValueR = CV_IMAGE_ELEM( inputImage, UCHAR, r + row, (c + col)*3+2 );
tempValueG = CV_IMAGE_ELEM( inputImage, UCHAR, r + row, (c + col)*3+1 );
tempValueB = CV_IMAGE_ELEM( inputImage, UCHAR, r + row, (c + col)*3 );}
tempR += tempValueR * kernelR[row+center][col+center] * 1.0;
tempG += tempValueG * kernelG[row+center][col+center] * 1.0;
tempB += tempValueB * kernelB[row+center][col+center] * 1.0;
}
}
tempR = tempR / divR;
tempG = tempG / divG;
tempB = tempB / divB;
}else{
for ( int row = -center; row <= center; row++ ) {
for ( int col = -center; col <= center; col++ ) {
double tempValueR = 0;
double tempValueG = 0;
double tempValueB = 0;
if ( (r + row >= 0 && r + row < HEIGHT) && (c + col>= 0 && c +
col < WIDTH)){
tempValueR = CV_IMAGE_ELEM( inputImage, UCHAR, r + row, (c + col)*3+2 );
tempValueG = CV_IMAGE_ELEM( inputImage, UCHAR, r + row, (c + col)*3+1 );
tempValueB = CV_IMAGE_ELEM( inputImage, UCHAR, r + row, (c + col)*3 );}
tempR += tempValueR * kernel[row+center][col+center] * 1.0;
tempG += tempValueG * kernel[row+center][col+center] * 1.0;
tempB += tempValueB * kernel[row+center][col+center] * 1.0;
}
}
tempR = tempR / div;
tempG = tempG / div;
tempB = tempB / div;
}
CV_IMAGE_ELEM( outputImage, UCHAR, r,c*3+2 ) = (char) tempR;
CV_IMAGE_ELEM( outputImage, UCHAR, r,c*3+1 ) = (char) tempG;
CV_IMAGE_ELEM( outputImage, UCHAR, r,c*3 ) = (char) tempB;
}
}
//using OpenCV
//cvSmooth ( inputImage, outputImageCV, CV_BILATERAL, windowSize );
//cvSaveImage ( "output_blur.jpg", outputImage );
//cvSaveImage ( "output_cv_blur.jpg", outputImageCV );
cvShowImage( "INPUT", inputImage );
cvShowImage( "OUTPUT", outputImage );
//cvShowImage( "OUTPUT-CV", outputImageCV );
cvWaitKey(-1);
cvDestroyWindow( "INPUT" );
cvDestroyWindow( "OUTPUT" );
//cvDestroyWindow( "OUTPUT-CV" );
cvReleaseImage ( &inputImage );
cvReleaseImage ( &outputImage );
//cvReleaseImage ( &outputImageCV );
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -