模糊原理
Smooth/Blur(平滑和模糊) 是图像处理中最简单和常用的操作之一。
使用该操作的原因之一就是为了给图像预处理时候降低噪声,把噪声与周围的数值平均一下就可以平滑噪声。
使用Smooth/Blur操作背后是数学的卷积计算,下面我们先来看一下卷积计算相关的知识:
卷积:通过两个函数f 和g 生成第三个函数的一种数学算子,表征函数f 与g经过翻转和平移的重叠部分的面积。
计算公式为:
其中:f()表示一副图像,i、j表示图像的行和列,h(k,l)表示卷积算子(卷积核)(也可以叫掩膜),k,l又可以叫窗口大小(掩膜的大小,比如3*3),g()表示输出的像素值;f()的第一行,第一列数据不要,边缘像素怎么处理后续会有介绍
通常这些卷积算子计算都是线性操作,所以又叫线性滤波
如下图:假设有6x6的图像像素点矩阵(灰色) ,黄色3x3是卷积算子
卷积过程:6x6上面有个3x3的窗口,这个3x3的窗口从左向右,从上向下移动
黄色的卷积算子乘以图像对应的像素点后,将得到的像素点值加在一起,取平均值赋给中心红色像素,作为卷积处理后的新的像素值
更形象的卷积过程如下面gif所示:
具体卷积计算过程
假设有一个卷积核(卷积算子)h,就一般为33的矩阵:
有一个待处理矩阵x:
hx的计算过程分为三步
第一步,将卷积核翻转180°,也就是成为了
第二步,将卷积核h的中心对准x的第一个元素,然后对应元素相乘后相加,没有元素的地方补0。
这样结果Y中的第一个元素值Y11=10+20+10+00+01+02±10±25±1*6=-16
第三步每个元素都像这样计算出来就可以得到一个输出矩阵,就是卷积结果
以此类推的计算每个元素。
最后结果为:
模糊分类
方框滤波
方框滤波内容请参考我的另一篇博文:
https://yangyongli.blog.csdn.net/article/details/121265592
归一化盒子滤波(均值滤波)
归一化盒子滤波(均值滤波): 就是上面的卷积计算,卷积算子(掩膜)中的格子权重都是1,所以卷积和之后还要除以卷积因子的大小取均值
公式
用到的API:
blur( Mat src, Mat dst, Size(xradius, yradius), Point(-1,-1) );
高斯滤波
高斯滤波: 相比于均值滤波,权重是不一样,但是权重和为1,所以计算卷积和之后不用取均值了。
公式:
用到API:
void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0 );
中值滤波与双边滤波
中值滤波与双边滤波内容请参考我的另一篇博文:
https://yangyongli.blog.csdn.net/article/details/121261236
代码示例
#include <iostream> #include <math.h> #include <opencv2/opencv.hpp> #include<opencv2/highgui.hpp> #include <opencv2/highgui/highgui_c.h> using namespace cv; int main(int argc, char** argv) { Mat src, dst; src = imread("./test2.jpg"); if (!src.data) { printf("could not load image...\n"); return -1; } char input_title[] = "input image"; char output_title[] = "blur image"; namedWindow(input_title, CV_WINDOW_AUTOSIZE); namedWindow(output_title, CV_WINDOW_AUTOSIZE); imshow(input_title, src); blur(src, dst, Size(11, 11), Point(-1, -1)); imshow(output_title, dst); Mat gblur; GaussianBlur(src, gblur, Size(11, 11), 11, 11); imshow("gaussian blur", gblur); waitKey(0); return 0; }