数字图像处理滤波器(2)

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include
#include
using namespace cv;
using namespace std;

void GaussianFilter(const unsigned char src_data[], unsigned char dst_data[], int cols, int rows, double sigma)
{
//对利用可分离性求二维高斯滤波,先横向一维高斯滤波,然后纵向一维高斯滤波。
int i, j, m, n;
float sum = 0;
int center = (int)(3 * sigma);//3sigma原则确定滤波器尺寸
int length = 2 * center + 1;
float* kernel = new float[length];
double sigma2 = sigma*sigma;
for (i = 0; i{
double r = center - i;
kernel[i] = (float)(exp(-0.5*r*r / sigma2));//高斯核函数
sum += kernel[i];
}
for (i = 0; i{
kernel[i] /= sum;//归一化,使得高斯滤波器的元素系数之和为1
}
unsigned char *tmp = new unsigned char[rows*cols];//tmp保存经过横向高斯滤波后的结果
memcpy(tmp, src_data, rows*cols);
//进行横向的一维高斯滤波
for (i = 0; i < rows; ++i)
{
for (j = center; j < cols - center; ++j)
{
sum = 0;
for (n = -center; n <= center; ++n)
{
sum += src_data[i*cols + j + n] * kernel[n + center];
}
tmp[i*cols + j] = cvRound(sum);
}
}
//进行纵向的一维高斯滤波,采用的滤波器和横向的滤波器相同
for (i = center; i < rows - center; ++i)
{
for (j = 0; j < cols; ++j)
{
sum = 0;
for (m = -center; m <= center; ++m)
{
sum += tmp[(i + m)*cols + j] * kernel[m + center];
}
dst_data[i*cols + j] = cvRound(sum);
}
}
delete tmp;
}
void Change(const unsigned char src_data[], unsigned char dst_data[], int cols, int rows, double sigmax,double sigmay)
{
//对利用可分离性求二维高斯滤波,先横向一维高斯滤波,然后纵向一维高斯滤波。
int i, j, m, n;
float sumx = 0,sumy=0;
int centerx = (int)(3 * sigmax);//3sigma原则确定滤波器尺寸
int centery = (int)(3 * sigmay);
int lengthx = 2 * centerx + 1;
int lengthy = 2 * centery + 1;
float* kernelx = new float[lengthx];
float* kernely = new float[lengthy];
double sigma2x = sigmax*sigmax;
double sigma2y = sigmay*sigmay;
for (i = 0; i{
double rx = centerx - i;
kernelx[i] = (float)(exp(-0.5*rx*rx / sigma2x));//高斯核函数
sumx += kernelx[i];
}
for (i = 0; i{
double ry = centery - i;
kernely[i] = (float)(exp(-0.5*ry*ry / sigma2y));//高斯核函数
sumy += kernely[i];
}
for (i = 0; i{
kernelx[i] /= sumx;//归一化,使得高斯滤波器的元素系数之和为1
}
for (i = 0; i{
kernely[i] /= sumy;//归一化,使得高斯滤波器的元素系数之和为1
}
unsigned char *tmp = new unsigned char[rows*cols];//tmp保存经过横向高斯滤波后的结果
memcpy(tmp, src_data, rows*cols);
//进行横向的一维高斯滤波
for (i = 0; i < rows; ++i)


{
for (j = centerx; j < cols - centerx; ++j)
{
sumx = 0;
for (n = -centerx; n <= centerx; ++n)
{
sumx += src_data[i*cols + j + n] * kernelx[n + centerx];
}
tmp[i*cols + j] = cvRound(sumx);
}
}
//进行纵向的一维高斯滤波,采用的滤波器和横向的滤波器相同
for (i = centery; i < rows - centery; ++i)
{
for (j = 0; j < cols; ++j)
{
sumy = 0;
for (m = -centery; m <= centery; ++m)
{
sumy += tmp[(i + m)*cols + j] * kernely[m + centery];
}
dst_data[i*cols + j] = cvRound(sumy);
}
}
delete tmp;
}
int main(int argc, char** argv)
{
Mat src, dst;
char* source_window = "Source image";
char* gaussian_window = "gaussian Image";
char* Change_window = "Change Image";
src = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
namedWindow(source_window, CV_WINDOW_AUTOSIZE);
imshow(source_window, src);

src.copyTo(dst);
GaussianFilter(src.data, dst.data, src.cols, src.rows, 2);
namedWindow(gaussian_window, CV_WINDOW_AUTOSIZE);
imshow(gaussian_window, dst);

src.copyTo(dst);
Change(src.data, dst.data, src.cols, src.rows, 2, 10);
namedWindow(Change_window, CV_WINDOW_AUTOSIZE);
imshow(Change_window, dst);
waitKey(0);
return 0;
}

相关文档
最新文档