基于C++&OpenCV实现高斯滤波【数字图像处理】

用OpenCV实现图像的高斯滤波。


        



空间滤波 = 图像卷积

高斯滤波 = 以高斯函数为卷积核的图像卷积

二维高斯函数:

基于C++&OpenCV实现高斯滤波【数字图像处理】_第1张图片

5*5卷积核:

基于C++&OpenCV实现高斯滤波【数字图像处理】_第2张图片

注:卷积核要注意归一化。

最终效果如下:

1).sigma = 1.5时:

基于C++&OpenCV实现高斯滤波【数字图像处理】_第3张图片

2).sigma = 3.0时:

基于C++&OpenCV实现高斯滤波【数字图像处理】_第4张图片

3).sigma = 5.0时:

基于C++&OpenCV实现高斯滤波【数字图像处理】_第5张图片

可以发现,sigma值越大,滤波窗口越大,滤波效果越明显(图像越模糊钝化)。

实现代码如下:

#include
#include
#include
#include
#include
#include

using namespace std;
using namespace cv;

void Gaussian(const Mat &input, Mat &output, double sigma)
{
	int row = input.rows, col = input.cols;
	int window = (int)((6 * sigma - 1) / 2) * 2 + 1;
	double *temp = new double[window];

	//扩充边界
	Mat INPUT;
	copyMakeBorder(input, INPUT, window / 2, window / 2, window / 2, window / 2,BORDER_REFLECT_101);

	double sum = 0;
	for (int w = 0; w < window; w++)
	{
		int mid = w - window / 2;
		temp[w] = exp(-(mid*mid) / (2 * sigma*sigma));
		sum += temp[w];
	}

	//归一化滤波核,和为1
	for (int w = 0; w < window; w++)
	{
		temp[w] = temp[w] / sum;
	}

	//扩充边界之后的长宽
	int rows = row + window - 1;
	int cols = col + window - 1;

	//先对每行进行一维高斯滤波
	for (int y = window/2; y < row+window/2; y++)//行
	{
		for (int x = window/2; x < col+window/2; x++) //列
		{
			int num = 0;
			double pix[3] = { 0 };
			for (int k = x - window / 2; k < x + window / 2; k++)
			{
				for (int c = 0; c < INPUT.channels(); c++)
				{
					pix[c] += (INPUT.at(y, k)[c])*temp[num];   //列坐标<矩阵列数
				}
				num++;
			}
			for (int c = 0; c < INPUT.channels(); c++)
			{
				INPUT.at(y, x)[c] = pix[c];
			}
		}
	}
	
	//再对每列进行一维高斯滤波
	for (int x = window/2; x < col+window/2; x++) //列
	{
		for (int y = window/2; y < row+window/2; y++) //行
		{
			int num = 0;
			double pix[3] = { 0 };
			for (int k = y - window / 2; k < y + window / 2; k++)
			{
				for (int c = 0; c < INPUT.channels(); c++)
				{
					pix[c] += (INPUT.at(k, x)[c])*temp[num];
				}
				num++;
			}
			for (int c = 0; c < INPUT.channels(); c++)
			{
				INPUT.at(y, x)[c] = pix[c];
			}
		}
	}
	for (int y = 0; y < row; y++)
	{
		for (int x = 0; x < col; x++)
		{
			output.at(y, x) = INPUT.at(y + window / 2, x + window / 2);
		}
	}
}

int main()
{
	double sig = 1.5;
	Mat image = imread("C:\\Users\\Downloads\\mouse.jpg");
	Mat dst = Mat::zeros(image.rows, image.cols, image.type());
	imshow("primary", image);
	Gaussian(image, dst, sig);
	imshow("dst", dst);
	//system("pause");
	waitKey(0);
	return 0;
}
注:本文原创,请勿抄袭,如转载请注明出处。

你可能感兴趣的:(基于C++&OpenCV实现高斯滤波【数字图像处理】)