基于C++的均值滤波程序实现
参考:https://blog.csdn.net/qq_43702097/article/details/103906355
均值滤波原理
对图像处理进行均值滤波的方法:首先定义一个模板,一般为奇数模板,锚点为中心,以其中心点为当前像素的位置(x,y),以模板覆盖的所有像素的均值作为滤波后图像的像素值。
计算公式
模板图(3×3)
代码如下:
void myblur(const Mat& src, Mat& dst, Size ksize)
{
//若模板不是奇数模板,则报错退出
if (ksize.width % 2 == 0 || ksize.height % 2 == 0)
{
cout << "please input odd ksize!" << endl;
exit(-1);
}
//根据ksize大小扩充模板边界
int awidth = (ksize.width - 1) / 2;
int aheight = (ksize.height - 1) / 2;
Mat asrc;
copyMakeBorder(src, asrc, aheight, aheight, awidth, awidth, BORDER_DEFAULT);
//根据图像通道数遍历图像求均值
//通道数为1
if (src.channels() == 1)
{
for (int i = aheight; i < src.rows + aheight; i++)
{
for (int j = awidth; j < src.cols + awidth; j++)
{
int sum = 0;
int mean = 0;
for (int k = i - aheight; k <= i + aheight; k++)
{
for (int l = j - awidth; l <= j + awidth; l++)
{
sum += asrc.at<uchar>(k, l);
}
}
mean = sum / (ksize.width*ksize.height);
dst.at<uchar>(i - aheight, j - awidth) = mean;
}
}
}
//通道数为3
if (src.channels() == 3)
{
for (int i = aheight; i < src.rows + aheight; i++)
{
for (int j = awidth; j < src.cols + awidth; j++)
{
int sum[3] = { 0 };
int mean[3] = { 0 };
for (int k = i - aheight; k <= i + aheight; k++)
{
for (int l = j - awidth; l <= j + awidth; l++)
{
sum[0] += asrc.at<Vec3b>(k, l)[0];
sum[1] += asrc.at<Vec3b>(k, l)[1];
sum[2] += asrc.at<Vec3b>(k, l)[2];
}
}
for (int m = 0; m < 3; m++)
{
mean[m] = sum[m] / (ksize.width*ksize.height);
dst.at<Vec3b>(i - aheight, j - awidth)[m] = mean[m];
}
}
}
}
}
int main()
{
Mat src = imread("C:/Users/msi-/Desktop/picture/1.jpg");
Mat dst1, dst2;
dst1 = Mat::zeros(src.size(), src.type());
myblur(src, dst1, Size(3, 3));
imshow("myblur", dst1);
blur(src, dst2, Size(3, 3));
imshow("blur", dst2);
waitKey();
return 0;
}
初始图片
opencv自带blur函数滤波处理的图片
编写的代码处理的图片
可以看到效果差不多,但速度比自带的blur函数差多了,不过本文旨在搞懂原理,以后有时间可以深究一下源码。