高斯滤波(Gauss Filter)是线性滤波中的一种。在OpenCV图像滤波处理中,高斯滤波用于平滑图像,或者说是图像模糊处理,因此高斯滤波是低通的。其广泛的应用在图像处理的减噪过程中,尤其是被高斯噪声所污染的图像上。
高斯滤波的基本思想是: 图像上的每一个像素点的值,都由其本身和邻域内其他像素点的值经过加权平均后得到。其具体操作是,用一个核(又称为卷积核、掩模、矩阵)扫描图像中每一个像素点,将邻域内各个像素值与对应位置的权值相称并求和。从数学的角度来看,高斯滤波的过程是图像与高斯正态分布做卷积操作。
注意: 高斯滤波是将二维高斯正态分布放在图像矩阵上做卷积运算。考虑的是邻域内像素值的空间距离关系,因此对彩色图像处理时应分通道进行操作,也就是说操作的图像原矩阵时用单通道数据,最后合并为彩色图像。

一、几个概念

1. 什么是低通滤波、平滑图像、图像模糊处理?
平滑图像与图像模糊处理是相同的含义。平滑处理即是通过操作后,使得图像的像素值与邻域内其他像素值的的变化程度减小。在一张图像上,边缘的像素值是变化程度最剧烈的地方,而其他相对平缓。因此,平滑图像最直观的表现是图像的上物体的边缘轮廓变得模糊。

低通滤波是指仅允许低频率信号通过。一张图像上的大部分能量聚集在低频和中频上,而高频大多是图像中物体的边缘部分,也有可能是高频噪声点。在单通道中,各像素点的取值都在(0~255)中,因此,低通滤波通过一定的阙值设置,有去除高频信号和平缓边缘的效果。

2. 什么是核(又称为卷积核、掩模、矩阵)?
核的本质其实就是一个大小固定、由数值参数组成的数学矩阵,例如一个3*3的核就是一个3*3的矩阵,而矩阵中的数据则为权值。

3. 什么是卷积运算?
卷积运算是指输入图像中某一像素点的邻域的各个值(包括该点)与卷积算子中的值做矩阵相乘运算,最后得到输出值。
卷积算子的公式:


g(i,j) 代表原图像矩阵上的(i,j)点的值,它是输出值。
f(i-k,j-l) 代表原图像矩阵上(i,j)点的邻域中的对应点的值。
h(k,,l) 代表与f(i-k , j-l)这个值在核对应位置的点的值
请看下图:这里用的是f(i-k,j-l)h(k,l)

由上图我们看到,矩阵f是将要进行操作的图像矩阵,当前的(i,j)是(2,2)点。h为核,其以中心(0,0)为参考点。因此f矩阵对应范围即为f(2,2)的邻域。矩阵g为图像输出矩阵,g(2,2)的值为输出值。
注意:卷积算子和相关算子在核上是180度翻转的矩阵,请不要搞混

4.核(卷积核、掩模、矩阵等)
在3的卷积运算中,用到的公式是:
g(i, j) = ∑ f(i-k, j-l)h(k, l) 。其中 k,l代表核上的坐标。而核的坐标明显与数组下标不一致。因此,我们需要做一个转换以满足用数组下标来访问该核的数据。
假设有3*3数组a,它与核的对应关系为
a(0, 0) ===> h(-1, -1) a(0, 1) ===> h(-1, 0) a(0, 2) ===> h(-1, 1)
a(1, 0) ===> h(0, -1) a(1, 1) ===> h(0, 0) a(1, 2) ===> h(0, 1)
a(2, 0) ===> h(1, -1) a(2, 1) ===> h(1, 0) a(2, 2) ===> h(1, 1)
对于3*3数组,其下标是0开始的,假设该数组的参考点(ai, aj)为中心,则有
g(i, j) = ∑ f(i-(k-ai), j-(l-aj))h(k, l)
带入数组参考点(1, 1),则有
g(i, j) = ∑ f(i-(k-1), j-(l-1))h(k, l)
此时,k,l可以从0开始取值

5.图像通道分离与合并(cv::Mat)

    // src 原图像,多通道// [1] 彩色图片通道分离std::vector<cv::Mat> channels;cv::split(&src, channels);// [3] 滤波// OpenCV中操作// channels[0]  ==>  B通道// channels[1]  ==>  G通道// channels[2]  ==>  R通道// 省略对各个通道的处理// [4] 合并返回cv::merge(channels, *dst);

二、高斯函数

高斯滤波,顾名思义,这是一个建立在高斯正态分布基础上的滤波器。首先我们来了解高斯函数。(图片来源于网络)
一维高斯函数:
可以看到,G(x)的跟sigma的取值有极大的关系。sigma取值越大,图像越平缓,sigma取值越小,图像越尖锐。

二维高斯函数:
二维高斯是构建高斯滤波器的基础。可以看到,G(x,y)在x轴y轴上的分布是一个突起的帽子的形状。这里的sigma可以看作两个值,一个是x轴上的分量sigmaX,另一个是y轴上的分量sigmaY。对图像处理可以直接使用sigma并对图像的行列操作,也可以用sigmaX对图像的行操作,再用sigmaY对图像的列操作。它们是等价的。
当sigmaX和sigmaY取值越大,整个形状趋近于扁平;当sigmaX和sigmaY取值越小,整个形状越突起。

高斯滤波原理就是将上图的二维正态分布应用在二维的矩阵上,G(x,y)的值就是矩阵上的权值,将得到的权值进行归一化,将权值的范围约束在[0,1]之间,并且所有的值的总和为1。
假设一个3*3的核,sigma取值1.5以及sigma取5.0,归一化后其权值分布分别是:

假设一个5*5的核,sigma取值1.5以及sigma取5.0,经归一化后其权值分布分别是:

可以看到,权值的分布是以中间高四周低来分布的。并且距离中心越远,其对中心点的影响就越小,权值也就越小。
因此可以总结:
(1)在核大小固定的情况下,sigma值越大,权值分布越平缓。因此,邻域各个点的值对输出值的影响越大,最终结果造成图像越模糊。
(2)在核大小固定的情况下,sigma值越小,权值分布越突起。因此,邻域各个点的值对输出值的影响越小,图像变化也越小。假如中心点权值为1,其他点权值为0,那么最终结果是图像没有任何变化。
(3)sigma固定时,核越大图像越模糊。
(4)sigma固定时,核越小图像变化越小。

三、高斯滤波器实现

首先看效果:
对于椒盐图作处理

对于高斯噪声图作处理

(1)main函数:读取图片 ==> 高斯滤波 ==> 结果显示

int main(void)
{// [1] src读入图片cv::Mat src = cv::imread("Median_pic.jpg");// [2] dst目标图片cv::Mat dst;// [3] 高斯滤波  sigma越大越平越模糊myGaussianFilter(&src, &dst, 5, 1.5f);// [4] 窗体显示cv::imshow("src", src);cv::imshow("dst", dst);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

(2)彩色图像通道分离处理,每个通道都进行高斯滤波,最后合并

void myGaussianFilter(cv::Mat *src, cv::Mat *dst, int n, double sigma)
{// [1] 初始化*dst = (*src).clone();// [2] 彩色图片通道分离std::vector<cv::Mat> channels;cv::split(*src, channels);// [3] 滤波// [3-1] 确定高斯正态矩阵double **array = getGaussianArray(n, sigma);// [3-2] 高斯滤波处理for (int i = 0; i < 3; i++) {gaussian(&channels[i], array, n);}// [4] 合并返回cv::merge(channels, *dst);return ;
}

(3)生成高斯正态分布核(卷积核,掩模等)

/* 获取高斯分布数组               (核大小, sigma值) */
double **getGaussianArray(int arr_size, double sigma)
{int i, j;// [1] 初始化权值数组double **array = new double*[arr_size];for (i = 0; i < arr_size; i++) {array[i] = new double[arr_size];}// [2] 高斯分布计算int center_i, center_j;center_i = center_j = arr_size / 2;double pi = 3.141592653589793;double sum = 0.0f;// [2-1] 高斯函数for (i = 0; i < arr_size; i++ ) {for (j = 0; j < arr_size; j++) {array[i][j] = //后面进行归一化,这部分可以不用//0.5f *pi*(sigma*sigma) * exp( -(1.0f)* ( ((i-center_i)*(i-center_i)+(j-center_j)*(j-center_j)) /(2.0f*sigma*sigma) ));sum += array[i][j];}}// [2-2] 归一化求权值for (i = 0; i < arr_size; i++) {for (j = 0; j < arr_size; j++) {array[i][j] /= sum;printf(" [%.15f] ", array[i][j]);}printf("\n");}return array;
}

(4)进行高斯滤波操作

/* 高斯滤波 (待处理单通道图片, 高斯分布数组, 高斯数组大小(核大小) ) */
void gaussian(cv::Mat *_src, double **_array, int _size)
{cv::Mat temp = (*_src).clone();// [1] 扫描for (int i = 0; i < (*_src).rows; i++) {for (int j = 0; j < (*_src).cols; j++) {// [2] 忽略边缘if (i > (_size / 2) - 1 && j > (_size / 2) - 1 &&i < (*_src).rows - (_size / 2) && j < (*_src).cols - (_size / 2)) {// [3] 找到图像输入点f(i,j),以输入点为中心与核中心对齐//     核心为中心参考点 卷积算子=>高斯矩阵180度转向计算//     x y 代表卷积核的权值坐标   i j 代表图像输入点坐标//     卷积算子     (f*g)(i,j) = f(i-k,j-l)g(k,l)          f代表图像输入 g代表核//     带入核参考点 (f*g)(i,j) = f(i-(k-ai), j-(l-aj))g(k,l)   ai,aj 核参考点//     加权求和  注意:核的坐标以左上0,0起点double sum = 0.0;for (int k = 0; k < _size; k++) {for (int l = 0; l < _size; l++) {sum += (*_src).ptr<uchar>(i-k+(_size/2))[j-l+(_size/2)] * _array[k][l];}}// 放入中间结果,计算所得的值与没有计算的值不能混用temp.ptr<uchar>(i)[j] = sum;}}}// 放入原图(*_src) = temp.clone();
}

OpenCV高斯滤波器详解及代码实现相关推荐

  1. 【OpenCV 4开发详解】高斯滤波

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  2. gammatone 滤波器详解及其MATLAB代码实现

    一.GammaTone 滤波器详解 定义: 外界语音信号进入耳蜗的基底膜后,将依据频率进行分解并产生行波震动,从而刺激听觉感受细胞[1].GammaTone 滤波器是一组用来模拟耳蜗频率分解特点的滤波 ...

  3. 【OpenCV 4开发详解】图像二值化

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  4. 【OpenCV 4开发详解】Canny算法

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  5. 【OpenCV 4开发详解】Laplacian算子

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  6. 【OpenCV 4开发详解】Scharr算子

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  7. 【OpenCV 4开发详解】Sobel算子

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  8. 【OpenCV 4开发详解】边缘检测原理

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  9. 【OpenCV 4开发详解】中值滤波

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

最新文章

  1. 人,与动物的本质区别,在哲学里说是制造和使用工具
  2. java获取当月有几天_你真的能在JAVA开发这条路上面一直坚持下去吗?
  3. 新上市Lighthouse专用芯片TS3633规格介绍
  4. 使用 jQuery UI Widget Factory 编写有状态的插件(Stateful Plugins)
  5. 吴恩达“机器学习”——学习笔记二
  6. ipsec加密技术谁提出的_如何提出技术问题以获得高质量的答案
  7. 一定要陪一个男人创业,你会和他一样快速成长,并内心变得强大
  8. java jsfl是什么_java基础之IO2
  9. java 并发编程实战代码_「Java并发编程实战」对象的组合
  10. iPad mini Retina越狱小结【2014年02月06日 - 初稿】
  11. python做服务器接口-用Python实现简单的服务器【新手必学】
  12. 一文读懂方向导数与梯度
  13. Python-Selenium Webdriver+google chrome浏览器爬取中国知网的文献之二
  14. Python 笑脸抓拍
  15. 软件设计师中级-数据库设计
  16. python画成绩正态分布图_正态分布为何如此重要?
  17. 第二次作业-产品分析
  18. 怎么打开国外分享的BOX链接
  19. 阿里巴巴区签约重庆,这些合作亮点你不得不知!
  20. Blob分析---ball.hdev

热门文章

  1. 好工具推荐系列:Linux远程连接,终端工具,SSH和SFTP
  2. R语言滞后差分diff()函数
  3. 用matlab验证时域卷积,用MATLAB实现信号的时域卷积
  4. Tomcat7 session 持久化关闭
  5. 公开数据集集合MedMNIST和Chest x-rays14
  6. maxwell详细介绍
  7. 三菱伺服图纸,三菱驱动器图纸
  8. AD 2020 入门教程
  9. 数据库-面试题-MySQL数据库的优化方法
  10. 双反馈直流matlab仿真,双闭环直流调速系统设计及matlab仿真验证(