OpenCV图像平滑处理

图像平滑处理

目标

本教程教您怎样使用各种线性滤波器对图像进行平滑处理,相关OpenCV函数如下:

原理

Note

以下原理来源于Richard Szeliski 的著作 Computer Vision: Algorithms and Applications 以及 Learning OpenCV

  • 平滑 也称 模糊, 是一项简单且使用频率很高的图像处理方法。
  • 平滑处理的用途有很多, 但是在本教程中我们仅仅关注它减少噪声的功用 (其他用途在以后的教程中会接触到)。
  • 平滑处理时需要用到一个 滤波器 。 最常用的滤波器是 线性 滤波器,线性滤波处理的输出像素值 (i.e. ) 是输入像素值 (i.e. )的加权和 :

     称为 , 它仅仅是一个加权系数。

    不妨把 滤波器 想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口滑过图像。

  • 滤波器的种类有很多, 这里仅仅提及最常用的:

归一化块滤波器 (Normalized Box Filter)

  • 最简单的滤波器, 输出像素值是核窗口内像素值的 均值 ( 所有像素加权系数相等)
  • 核如下:

高斯滤波器 (Gaussian Filter)

  • 最有用的滤波器 (尽管不是最快的)。 高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值。
  • 还记得1维高斯函数的样子吗?

    假设图像是1维的,那么观察上图,不难发现中间像素的加权系数是最大的, 周边像素的加权系数随着它们远离中间像素的距离增大而逐渐减小。

Note

2维高斯函数可以表达为 :

其中  为均值 (峰值对应位置),  代表标准差 (变量  和 变量  各有一个均值,也各有一个标准差)

中值滤波器 (Median Filter)

中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替 。

双边滤波 (Bilateral Filter)

  • 目前我们了解的滤波器都是为了 平滑 图像, 问题是有些时候这些滤波器不仅仅削弱了噪声, 连带着把边缘也给磨掉了。 为避免这样的情形 (至少在一定程度上 ), 我们可以使用双边滤波。
  • 类似于高斯滤波器,双边滤波器也给每一个邻域像素分配一个加权系数。 这些加权系数包含两个部分, 第一部分加权方式与高斯滤波一样,第二部分的权重则取决于该邻域像素与当前像素的灰度差值。
  • 详细的解释可以查看 链接

源码

  • 本程序做什么?

    • 装载一张图像
    • 使用4种不同滤波器 (见原理部分) 并显示平滑图像
  • 下载代码: 点击 这里
  • 代码一瞥:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std;
using namespace cv;

/// 全局变量
int DELAY_CAPTION = 1500;
int DELAY_BLUR = 100;
int MAX_KERNEL_LENGTH = 31;

Mat src; Mat dst;
char window_name[] = "Filter Demo 1";

/// 函数申明
int display_caption( char* caption );
int display_dst( int delay );

/**
 *  main 函数
 */
 int main( int argc, char** argv )
 {
   namedWindow( window_name, CV_WINDOW_AUTOSIZE );

   /// 载入原图像
   src = imread( "../images/lena.jpg", 1 );

   if( display_caption( "Original Image" ) != 0 ) { return 0; }

   dst = src.clone();
   if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; }

   /// 使用 均值平滑
   if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }

   for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
       { blur( src, dst, Size( i, i ), Point(-1,-1) );
         if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }

    /// 使用高斯平滑
    if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { GaussianBlur( src, dst, Size( i, i ), 0, 0 );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }

     /// 使用中值平滑
     if( display_caption( "Median Blur" ) != 0 ) { return 0; }

     for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
         { medianBlur ( src, dst, i );
           if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }

     /// 使用双边平滑
     if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }

     for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
         { bilateralFilter ( src, dst, i, i*2, i/2 );
           if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }

     /// 等待用户输入
     display_caption( "End: Press a key!" );

     waitKey(0);
     return 0;
 }

 int display_caption( char* caption )
 {
   dst = Mat::zeros( src.size(), src.type() );
   putText( dst, caption,
            Point( src.cols/4, src.rows/2),
            CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );

   imshow( window_name, dst );
   int c = waitKey( DELAY_CAPTION );
   if( c >= 0 ) { return -1; }
   return 0;
  }

  int display_dst( int delay )
  {
    imshow( window_name, dst );
    int c = waitKey ( delay );
    if( c >= 0 ) { return -1; }
    return 0;
  }

解释

  1. 下面看一看有关平滑的OpenCV函数,其余部分大家已经很熟了。
  2. 归一化块滤波器:

    OpenCV函数 blur 执行了归一化块平滑操作。

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { blur( src, dst, Size( i, i ), Point(-1,-1) );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    

    我们输入4个实参 (详细的解释请参考 Reference):

    • src: 输入图像
    • dst: 输出图像
    • Size( w,h ): 定义内核大小( w 像素宽度, h 像素高度)
    • Point(-1, -1): 指定锚点位置(被平滑点), 如果是负值,取核的中心为锚点。
  3. 高斯滤波器:

    OpenCV函数 GaussianBlur 执行高斯平滑 :

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { GaussianBlur( src, dst, Size( i, i ), 0, 0 );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    

我们输入4个实参 (详细的解释请参考 Reference):

  • src: 输入图像
  • dst: 输出图像
  • Size(w, h): 定义内核的大小(需要考虑的邻域范围)。  和  必须是正奇数,否则将使用  和  参数来计算内核大小。
  • : x 方向标准方差, 如果是  则  使用内核大小计算得到。
  • : y 方向标准方差, 如果是  则  使用内核大小计算得到。.
  1. 中值滤波器:

    OpenCV函数 medianBlur 执行中值滤波操作:

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { medianBlur ( src, dst, i );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    

    我们用了3个参数:

    • src: 输入图像
    • dst: 输出图像, 必须与 src 相同类型
    • i: 内核大小 (只需一个值,因为我们使用正方形窗口),必须为奇数。
  2. 双边滤波器

    OpenCV函数 bilateralFilter 执行双边滤波操作:

    for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
        { bilateralFilter ( src, dst, i, i*2, i/2 );
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
    

    我们使用了5个参数:

    • src: 输入图像
    • dst: 输出图像
    • d: 像素的邻域直径
    • : 颜色空间的标准方差
    • : 坐标空间的标准方差(像素单位)

结果

  • 程序显示了原始图像( lena.jpg) 和使用4种滤波器之后的效果图。
  • 这里显示的是使用 中值滤波 之后的效果图:

翻译者

[email protected] OpenCV中文网站 <[email protected]>

from: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html#smoothing

时间: 2024-10-07 14:21:31

OpenCV图像平滑处理的相关文章

八.使用OpenCv图像平滑操作

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

OpenCV图像处理篇之图像平滑

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

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 和

图像平滑技术之盒滤波、均值滤波、中值滤波、高斯滤波、双边滤波的原理概要及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&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学习笔记——图像平滑处理

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

OpenCV 学习(利用滤波器进行边缘提取)

OpenCV 学习(利用滤波器进行边缘提取) 通过低通滤波器,我们可以将图像平滑,相反的,利用高通滤波器可以提取出图像的边缘. Sobel 滤波器 Sobel 滤波器是一种有方向性的滤波器,可以作用在 X 方向或 Y 方向. 关于这种滤波器的理论介绍可以参考: https://en.wikipedia.org/wiki/Sobel_operator 函数原型如下: void Sobel( InputArray src, OutputArray dst, int ddepth, int dx, i