经过平滑滤波后的输出 g(x经过平滑滤波后底出口 g(x经过平滑滤波后的出口 g(x

1  图像平滑

1  图像平滑

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

710官方网站 1

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  // 边界模式
)

710官方网站 2

  取 ddepth = 1,normalize = true,则足以拿走模糊化函数 (blur)

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

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

710官方网站 3

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

710官方网站 4

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度过可想象那个二维高斯核

    710官方网站 5

710官方网站 6

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

710官方网站 7

  注意: 高斯核的轻重缓急 Size(width, height),w 和
双方不必千篇一律只是要还是奇数,若都使为 0,则从 sigma 自动测算得出

2.4  双边滤波

 
上面三种办法都是小通滤波,因此在摒除噪声的还要,也每每会以边缘信息模糊化。双边滤波和高斯滤波类似,但是其用邻域像从的加权系数分为两部分,

 
第一有的及高斯滤波的完全相同,第二有则设想当下像素和邻域像素之间灰度值的反差,从而在拔除噪声的底蕴及,也比较好的保存了图像的边缘信息

710官方网站 8

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

710官方网站 9

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

   注意 2)  sigmaColor 和 sigmaSpace 可取相同值,一般在 10 ~ 150
之间
,小于 10,则没什么效果,大于
150,则效果最好明白,看起肯定“卡通化”

 

3  代码示例

3.1 OpenCV

  OpenCV 中之示范,通过逐渐增大如从邻域的轻重缓急 Size(w,
h),将上述滤波过程动态化,非常像的来得了邻域大小对滤波效果的熏陶

  代码摘抄:

710官方网站 10 View Code

3.2  滤波对比

  实际被,可径直调用以上四独滤波函数,代码如下:

710官方网站 11

 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 }

710官方网站 12

  四种滤波方法的职能图,如下所示:

  710官方网站 13

参考资料

 <Digital Image Processing_3rd> chapter 3

 <Learning OpenCV_2nd>

 <OpenCV Tutorials> imgproc module – Smoothing Images

 

 

 

 

1.1  公式

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

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

$\quad g(x, y) = \sum \limits_{s=-a}^a \: \sum \limits_{t=-b}^b
{w(s, t)\:f(x+s, y+t)} $

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

  其中,$ M_x = \begin{bmatrix} 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) \\
\end{bmatrix} \qquad M_f = \begin{bmatrix} 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) \\ \end{bmatrix}$

1.1  公式

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

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

$\quad g(x, y) = \sum \limits_{s=-a}^a \: \sum \limits_{t=-b}^b
{w(s, t)\:f(x+s, y+t)} $

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

  其中,$ M_x = \begin{bmatrix} 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) \\
\end{bmatrix} \qquad M_f = \begin{bmatrix} 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) \\ \end{bmatrix}$

1.2  图形

  以上公式的形象诠释,如下所示:

  710官方网站 14

 

1.2  图形

  以上公式的像诠释,如下所示:

  710官方网站 15

 

2  OpenCV 函数

  OpenCV 中重要性发生四单函数,分别是盒式滤波 (box),高斯滤波
(Gaussian),中值滤波 (median),双边滤波 (bilateral)

2  OpenCV 函数

  OpenCV 中主要出四独函数,分别是盒式滤波 (box),高斯滤波
(Gaussian),中值滤波 (median),双边滤波 (bilateral)

2.1  盒式滤波

2.1  盒式滤波

 2.1.1 boxFilter

 输出图像的甭管一诸如素灰度值,等于夫具有邻域像素灰度值的平均值

  模糊化核为,$ K = \alpha \begin{bmatrix}  1 & 1 & … & 1 & 1 \\ 1
& 1 & … & 1 & 1 \\ \: & \: & … & & & \\ 1 & 1 & … & 1 & 1
\end{bmatrix} $  其中,$\alpha = \begin{cases} \frac{1}{ksize.width
* ksize.height} & \text{when normalize = true} \\  1 &
\text{otherwise} \\ \end{cases} $

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  // 边界模式
)

 2.1.1 boxFilter

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

  模糊化核为,$ K = \alpha \begin{bmatrix}  1 & 1 & … & 1 & 1 \\ 1
& 1 & … & 1 & 1 \\ \: & \: & … & & & \\ 1 & 1 & … & 1 & 1
\end{bmatrix} $  其中,$\alpha = \begin{cases} \frac{1}{ksize.width
* ksize.height} & \text{when normalize = true} \\  1 &
\text{otherwise} \\ \end{cases} $

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  // 边界模式
)

2.1.2  blur

  取 ddepth = -1,normalize = true,则可由 boxFilter 得到模糊化函数
(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.1.2  blur

  取 ddepth = -1,normalize = true,尽管只是由 boxFilter 得到模糊化函数
(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  中值滤波

  中值滤波最为简练,常用来打消椒盐噪声。输出图像 g (x, y) 
的比如说素值,等于为输入图像 f (x, y) 为中心点的邻域像素 (ksize x ksize)
平均值

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

2.2  中值滤波

  中值滤波最为简单,常用来解椒盐噪声。出口图像 g (x, y) 
的如素值,等于为输入图像 f (x, y) 为中心点的邻域像素 (ksize x ksize)
平均值

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

2.3  高斯滤波

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

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

  $\quad G_{0}(x, y) = A e^{ \dfrac{ -(x – \mu_{x})^{2} }{
2\sigma^{2}_{x} } + \dfrac{ -(y – \mu_{y})^{2} }{ 2\sigma^{2}_{y}
} } $

  无须理会公式的纷繁,只待牢记一点即可:邻域像从距离时诸如素越远
(saptial space),则该对应的加权系数越小

  为了有利于直观了解,可圈下面是一维高斯复核,推而广之将 G(x) 曲线以 x=0
这条轴为主干线,旋转360度可想象那个二维高斯核

    710官方网站 16

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.3  高斯滤波

 
高斯滤波最为可行,它是依据目前像素和邻域像素之间,空间距离的不等,计算得出一个高斯核
(邻域像从的加权系数),

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

  $\quad G_{0}(x, y) = A e^{ \dfrac{ -(x – \mu_{x})^{2} }{
2\sigma^{2}_{x} } + \dfrac{ -(y – \mu_{y})^{2} }{ 2\sigma^{2}_{y}
} } $

  无须理会公式的错综复杂,只待牢记一点即可:邻域像从距离时诸如素越远
(saptial space),则该对应的加权系数越小

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

    710官方网站 17

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,则效果太明确,看起肯定“卡通化”

 

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  代码示例

3.1 OpenCV

  OpenCV 中的示范,通过逐步增大如从邻域的轻重缓急 Size(w,
h),将上述滤波过程动态化,非常像的显示了邻域大小对滤波效果的震慑

 
代码摘抄:

710官方网站 18710官方网站 19

  1 /**
  2  * file Smoothing.cpp
  3  * brief Sample code for simple filters
  4  * author OpenCV team
  5  */
  6 #include <iostream>
  7 #include <vector>
  8 
  9 #include "opencv2/imgproc/imgproc.hpp"
 10 #include "opencv2/imgcodecs.hpp"
 11 #include "opencv2/highgui/highgui.hpp"
 12 #include "opencv2/features2d/features2d.hpp"
 13 
 14 using namespace std;
 15 using namespace cv;
 16 
 17 /// Global Variables
 18 int DELAY_CAPTION = 1500;
 19 int DELAY_BLUR = 100;
 20 int MAX_KERNEL_LENGTH = 31;
 21 
 22 Mat src; Mat dst;
 23 char window_name[] = "Smoothing Demo";
 24 
 25 /// Function headers
 26 int display_caption( const char* caption );
 27 int display_dst( int delay );
 28 
 29 
 30 /**
 31  * function main
 32  */
 33 int main( void )
 34 {
 35   namedWindow( window_name, WINDOW_AUTOSIZE );
 36 
 37   /// Load the source image
 38   src = imread( "../data/lena.jpg", 1 );
 39 
 40   if( display_caption( "Original Image" ) != 0 ) { return 0; }
 41 
 42   dst = src.clone();
 43   if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; }
 44 
 45 
 46   /// Applying Homogeneous blur
 47   if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }
 48 
 49   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
 50       { blur( src, dst, Size( i, i ), Point(-1,-1) );
 51         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 52 
 53 
 54   /// Applying Gaussian blur
 55   if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }
 56 
 57   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
 58       { GaussianBlur( src, dst, Size( i, i ), 0, 0 );
 59         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 60 
 61 
 62   /// Applying Median blur
 63   if( display_caption( "Median Blur" ) != 0 ) { return 0; }
 64 
 65   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
 66       { medianBlur ( src, dst, i );
 67         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 68 
 69 
 70   /// Applying Bilateral Filter
 71   if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }
 72 
 73   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
 74       { bilateralFilter ( src, dst, i, i*2, i/2 );
 75         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 76 
 77   /// Wait until user press a key
 78   display_caption( "End: Press a key!" );
 79 
 80   waitKey(0);
 81 
 82   return 0;
 83 }
 84 
 85 /**
 86  * @function display_caption
 87  */
 88 int display_caption( const char* caption )
 89 {
 90   dst = Mat::zeros( src.size(), src.type() );
 91   putText( dst, caption,
 92            Point( src.cols/4, src.rows/2),
 93            FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );
 94 
 95   imshow( window_name, dst );
 96   int c = waitKey( DELAY_CAPTION );
 97   if( c >= 0 ) { return -1; }
 98   return 0;
 99 }
100 
101 /**
102  * @function display_dst
103  */
104 int display_dst( int delay )
105 {
106   imshow( window_name, dst );
107   int c = waitKey ( delay );
108   if( c >= 0 ) { return -1; }
109   return 0;
110 }

View Code

3.1 OpenCV

  OpenCV 中之以身作则,通过逐步增大如从邻域的大大小小 Size(w,
h),将上述滤波过程动态化,非常像之展示了邻域大小对滤波效果的震慑

 
代码摘抄:

710官方网站 20710官方网站 21

  1 /**
  2  * file Smoothing.cpp
  3  * brief Sample code for simple filters
  4  * author OpenCV team
  5  */
  6 #include <iostream>
  7 #include <vector>
  8 
  9 #include "opencv2/imgproc/imgproc.hpp"
 10 #include "opencv2/imgcodecs.hpp"
 11 #include "opencv2/highgui/highgui.hpp"
 12 #include "opencv2/features2d/features2d.hpp"
 13 
 14 using namespace std;
 15 using namespace cv;
 16 
 17 /// Global Variables
 18 int DELAY_CAPTION = 1500;
 19 int DELAY_BLUR = 100;
 20 int MAX_KERNEL_LENGTH = 31;
 21 
 22 Mat src; Mat dst;
 23 char window_name[] = "Smoothing Demo";
 24 
 25 /// Function headers
 26 int display_caption( const char* caption );
 27 int display_dst( int delay );
 28 
 29 
 30 /**
 31  * function main
 32  */
 33 int main( void )
 34 {
 35   namedWindow( window_name, WINDOW_AUTOSIZE );
 36 
 37   /// Load the source image
 38   src = imread( "../data/lena.jpg", 1 );
 39 
 40   if( display_caption( "Original Image" ) != 0 ) { return 0; }
 41 
 42   dst = src.clone();
 43   if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; }
 44 
 45 
 46   /// Applying Homogeneous blur
 47   if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }
 48 
 49   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
 50       { blur( src, dst, Size( i, i ), Point(-1,-1) );
 51         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 52 
 53 
 54   /// Applying Gaussian blur
 55   if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }
 56 
 57   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
 58       { GaussianBlur( src, dst, Size( i, i ), 0, 0 );
 59         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 60 
 61 
 62   /// Applying Median blur
 63   if( display_caption( "Median Blur" ) != 0 ) { return 0; }
 64 
 65   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
 66       { medianBlur ( src, dst, i );
 67         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 68 
 69 
 70   /// Applying Bilateral Filter
 71   if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }
 72 
 73   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
 74       { bilateralFilter ( src, dst, i, i*2, i/2 );
 75         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 76 
 77   /// Wait until user press a key
 78   display_caption( "End: Press a key!" );
 79 
 80   waitKey(0);
 81 
 82   return 0;
 83 }
 84 
 85 /**
 86  * @function display_caption
 87  */
 88 int display_caption( const char* caption )
 89 {
 90   dst = Mat::zeros( src.size(), src.type() );
 91   putText( dst, caption,
 92            Point( src.cols/4, src.rows/2),
 93            FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );
 94 
 95   imshow( window_name, dst );
 96   int c = waitKey( DELAY_CAPTION );
 97   if( c >= 0 ) { return -1; }
 98   return 0;
 99 }
100 
101 /**
102  * @function display_dst
103  */
104 int display_dst( int delay )
105 {
106   imshow( window_name, dst );
107   int c = waitKey ( delay );
108   if( c >= 0 ) { return -1; }
109   return 0;
110 }

View Code

3.2  滤波对比

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

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

  四栽滤波方法的意义图,如下所示:

  710官方网站 22

3.2  滤波对比

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

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

  四种植滤波方法的功能图,如下所示:

  710官方网站 23

参考资料

 <Digital Image Processing> 3rd, chapter 3

 <Learning OpenCV3>

 OpenCV Tutorials \ Image Processing (imgproc module) \ Smoothing
Images

 贪图如卷积与滤波的一对知识点,zouxy09

 

参考资料

 <Digital Image Processing> 3rd, chapter 3

 <Learning OpenCV3>

 OpenCV Tutorials \ Image Processing (imgproc module) \ Smoothing
Images

 希冀如卷积与滤波的组成部分知识点,zouxy09

 

相关文章