OpenCV 之 图像平滑

OpenCV 之 图像平滑

1  图像平滑

图像平滑,可用来对图像进行去噪 (noise reduction) 或 模糊化处理 (blurring),实际上图像平滑仍然属于图像空间滤波的一种 (低通滤波)

既然是滤波,则图像中任一点 (x, y),经过平滑滤波后的输出 g(x, y) 如下:

g(x,y)=∑s=−aa∑t=−bbw(s,t)f(x+s,y+t)g(x,y)=∑s=−aa∑t=−bbw(s,t)f(x+s,y+t)

以 3X3 的滤波器为例 (即 a=b=1),则矩阵 Mx 和 Mf 对应的元素乘积之和,就是 g(x, y)

其中,Mx=???w(−1,−1)w(0,−1)w(1,−1)w(−1,0)w(0,0)w(1,0)w(−1,1)w(1,1)w(1,1)???Mf=???f(x−1,y−1)f(x,y−1)f(x+1,y−1)f(x−1,y)f(x,y)f(x+1,y)f(x−1,y+1)f(x+1,y+1)f(x+1,y+1)???Mx=[w(−1,−1)w(−1,0)w(−1,1)w(0,−1)w(0,0)w(1,1)w(1,−1)w(1,0)w(1,1)]Mf=[f(x−1,y−1)f(x−1,y)f(x−1,y+1)f(x,y−1)f(x,y)f(x+1,y+1)f(x+1,y−1)f(x+1,y)f(x+1,y+1)]

2  OpenCV 函数

OpenCV 中主要有四个函数涉及到图像平滑,分别是盒式滤波 (box),高斯滤波 (Gaussian),中值滤波 (median),双边滤波 (bilateral)

2.1  盒式滤波

  输出图像的任一像素灰度值,等于其所有邻域像素灰度值的平均值

模糊化核为,K=α?????111111............111111?????K=α[11...1111...11...11...11]  其中,α={1ksize.weidth∗ksize.height1when normalize = trueotherwiseα={1ksize.weidth∗ksize.heightwhen normalize = true1otherwise

void cv::boxFilter (
    InputArray   src, // 输入图像
    OutputArray  dst, // 输出图像
    int    ddepth,      // 输出图像深度,-1 表示等于 src.depth()
    Size   ksize,       // 模糊化核 (kernel) 的大小
    Point  anchor = Point(-1,-1),       // 锚点位置,缺省值表示 anchor 位于模糊核的正中心
    bool   normalize = true,            // 是否归一化处理
    int    borderType = BORDER_DEFAULT  // 边界模式
)

取 ddepth = 1,normalize = true,则可以得到模糊化函数 (blur)

boxFilter( src, dst, -1, ksize, anchor, true, borderType );

模糊化函数 (blur),本质上是一个输入和输出图像深度 (ddepth) 相同,并且做归一化处理的盒式滤波器

void cv::blur (
    InputArray  src,
    OutputArray dst,          Size ksize,
    Point anchor = Point(-1,-1),
    int borderType = BORDER_DEFAULT
)  

2.2  中值滤波

  中值滤波最为简单,常用来消除椒盐噪声

输出图像中 (x, y) 点处的像素值,等于输入图像以 (x, y) 为中心点的邻域像素 (ksize x ksize) 平均值

void cv::medianBlur (
    InputArray   src,
    OutputArray  dst,
    int  ksize   // 滤波器孔径大小,一般为奇数且大于 1,比如 3, 5, 7, ...
)     

2.3  高斯滤波

高斯滤波最为有用,它是根据当前像素和邻域像素之间,空间距离的不同,计算得出一个高斯核 (邻域像素的加权系数),

然后,高斯核从左至右、从上到下遍历输入图像,与输入图像的像素值求卷积和,得到输出图像的各个像素值

G0(x,y)=Ae−(x−μx)22σ2x+−(y−μy)22σ2yG0(x,y)=Ae−(x−μx)22σx2+−(y−μy)22σy2

无须理会公式的复杂,只需要记住一点即可:邻域像素距离当前像素越远 (saptial space),则其相应的加权系数越小

为了便于直观理解,可看下面这个一维高斯核,推而广之将 G(x) 曲线以 x=0 这条轴为中心线,旋转360度可想象其二维高斯核

void cv::GaussianBlur (
    InputArray   src,
    OutputArray  dst,
    Size    ksize,       // 高斯核的大小
    double  sigmaX,      // 高斯核在x方向的标准差
    double  sigmaY = 0,  // 高斯核在y方向的标准差,缺省为 0,表示 sigmaY = sigmaX
    int     borderType = BORDER_DEFAULT
)  

  注意: 高斯核的大小 Size(width, height),w 和 h 二者不必相同但必须都是奇数,若都设为 0,则从 sigma 自动计算得出

2.4  双边滤波

上面三种方法都是低通滤波,因此在消除噪声的同时,也常会将边缘信息模糊化。双边滤波和高斯滤波类似,但是它将邻域像素的加权系数分为两部分,

第一部分与高斯滤波的完全相同,第二部分则考虑当前像素和邻域像素之间灰度值的差异,从而在消除噪声的基础上,也较好的保留了图像的边缘信息

void cv::bilateralFilter (
    InputArray    src,
    OutputArray   dst,
    int     d,    // 像素邻域直径,若为非正值,则从 sigmaSpace 自动计算得出
    double  sigmaColor,  // 颜色空间的标注方差
    double  sigmaSpace,  // 坐标空间的标准方差
    int     borderType = BORDER_DEFAULT
)

注意 1)  双边滤波相比以上三种滤波方法,其处理速度很慢,因此,一般建议取 d=5 用于实时图像处理,d=9 适合于非实时的图像领域

注意 2)  sigmaColor 和 sigmaSpace 可取相同值,一般在 10 ~ 150 之间,小于 10,则没什么效果,大于 150,则效果太强烈,看起来明显“卡通化”

3  代码示例

3.1 OpenCV

  OpenCV 中的示例,通过逐渐增大像素邻域的大小 Size(w, h),将上述滤波过程动态化,非常形象的展示了邻域大小对滤波效果的影响

代码摘抄

 

3.2  滤波对比

实际中,可直接调用以上四个滤波函数,代码如下:

 1 #include "opencv2/imgproc/imgproc.hpp"
 2 #include "opencv2/highgui/highgui.hpp"
 3
 4 using namespace std;
 5 using namespace cv;
 6
 7 int main()
 8 {
 9     Mat src = imread("E:/smooth/bird.jpg");
10     if(src.empty())    return -1;
11
12     namedWindow("original", CV_WINDOW_AUTOSIZE);
13     namedWindow("blur", CV_WINDOW_AUTOSIZE);
14     namedWindow("GaussianBlur", CV_WINDOW_AUTOSIZE);
15     namedWindow("medianBlur", CV_WINDOW_AUTOSIZE);
16     namedWindow("bilateralFilter", CV_WINDOW_AUTOSIZE);
17
18     imshow("original", src);
19
20     Mat dst;
21
22     blur(src, dst, Size(3,3));
23     imshow("blur", dst);
24
25     medianBlur(src,dst,3);
26     imshow("medianBlur",dst);
27
28     GaussianBlur(src,dst,Size(3,3),0);
29     imshow("GaussianBlur",dst);
30
31     bilateralFilter(src,dst,9,50,50);
32     imshow("bilateralFilter",dst);
33
34     waitKey(0);
35     return 0;
36 }

四种滤波方法的效果图,如下所示:

参考资料

<Digital Image Processing_3rd> chapter 3

<Learning OpenCV_2nd>

<OpenCV Tutorials> imgproc module - Smoothing Images

时间: 2024-08-04 08:21:29

OpenCV 之 图像平滑的相关文章

OpenCV&amp;&amp;python_图像平滑(Smoothing Images)

Goals 学习用不同低通滤波方法模糊图像(Blur imagess with various low pass filter) 用用定制的滤波器处理图像(Apply custom-made filters to images (2D convolution)) 高通滤波与低通滤波 images can be filtered with various low-pass filters (LPF), high-pass filters (HPF), etc.  A LPF helps in re

OpenCV 之 边缘检测

上一篇 <OpenCV 之 图像平滑> 中,提到的图像平滑,从信号处理的角度来看,实际上是一种低通滤波器. 本篇中,数字图像的边缘,因为通常都是像素值变化剧烈的区域 (“高频”),故可将边缘检测视为“高通滤波” OpenCV 中,边缘检测常用的是索贝尔算子 (Sobel) 和拉普拉斯算子 (Laplace),分别是对图像求一阶导和二阶导 1  索贝尔算子 (Sobel) 1.1  计算过程 假定输入图像矩阵为 I,卷积核大小为 3x3,则水平一阶导数 Gx 和垂直一阶导数 Gy 分别为: $\

OpenCV图像处理篇之图像平滑

图像平滑算法 图像平滑与图像模糊是同一概念,主要用于图像的去噪.平滑要使用滤波器,为不改变图像的相位信息,一般使用线性滤波器,其统一形式如下: 其中h称为滤波器的核函数,说白了就是权值.不同的核函数代表不同的滤波器,有不同的用途. 在图像处理中,常见的滤波器包括: 归一化滤波器(Homogeneous blur) 也是均值滤波器,用输出像素点核窗口内的像素均值代替输出点像素值. 高斯滤波器(Guassian blur) 是实际中最常用的滤波器,高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积

OpenCV图像平滑处理

图像平滑处理 目标 本教程教您怎样使用各种线性滤波器对图像进行平滑处理,相关OpenCV函数如下: blur GaussianBlur medianBlur bilateralFilter 原理 Note 以下原理来源于Richard Szeliski 的著作 Computer Vision: Algorithms and Applications 以及 Learning OpenCV 平滑 也称 模糊, 是一项简单且使用频率很高的图像处理方法. 平滑处理的用途有很多, 但是在本教程中我们仅仅关

图像平滑技术之盒滤波、均值滤波、中值滤波、高斯滤波、双边滤波的原理概要及OpenCV代码实现

图像平滑是指直接对源图像的每个像素数据做邻域运算以达到平滑图像的目的.实质上主要就是通达卷积核算子实现的,卷积核算子的相关知识大家可以参考我写的博文http://blog.csdn.net/wenhao_ir/article/details/51691410 图像平滑也称为模糊或滤波,是图像处理中常用的技术之一,进行平滑处理时需要用到滤波器核(其实就是卷积核算子),根据滤波器核函数来实现不同的滤波技术.下面介绍几种 常用的图像平滑方法的大概原理及OpenCV下的实现代码. 一.盒滤波(均值滤波)

OpenCV笔记(七)——图像平滑的四种方法

Opencv中处理图像平滑的手段主要有4种:箱式滤波器.高斯滤波器.中值滤波器.双边滤波器. 1. 箱式滤波器 Normalized Box Filter 箱式滤波器将当前像素的值替换为所有kernel范围内像素的值的平均值.公式如下: 如果是3x3的核,则它对应的核是1/9 * [1, 1, 1; 1, 1, 1; 1, 1, 1] OpenCV中的函数为: void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=

八.使用OpenCv图像平滑操作

1.cvSmooth函数 函数 cvSmooth 可使用简单模糊.简单无缩放变换的模糊.中值模糊.高斯模糊.双边滤波的不论什么一种方法平滑图像.每一种方法都有自己的特点以及局限. 没有缩放的图像平滑仅支持单通道图像,而且支持8位到16位的转换(与cvSoble和cvaplace相似)和32位浮点数到32位浮点数的变换格式. 简单模糊和高斯模糊支持 1- 或 3-通道, 8-比特 和 32-比特 浮点图像. 这两种方法能够(in-place)方式处理图像. 中值和双向滤波工作于 1- 或 3-通道

OpenCV学习笔记——图像平滑处理

1.blur 归一化滤波器Blurs an image using the normalized box filter.C++: void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT ) Parameters:src – input image; it can have any number of channels, which

openCV—Python(9)—— 图像平滑与滤波

一.函数简介 1.blur-图像均值平滑滤波 函数原型:blur(src, ksize, dst=None, anchor=None, borderType=None) src:图像矩阵 ksize:滤波窗口尺寸 2.GaussianBlur-图像高斯平滑滤波 函数原型:GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None) src:图像矩阵 ksize:滤波窗口尺寸 sigmaX:标准差 3.median