【OpenCV_09】平滑/模糊图片 Smooth / Blur Images及 彩色图转 灰度图和二值化

原创 2016年06月01日 10:02:02

这一节,谈一谈如何对图像进行平滑,也可以叫做模糊。平滑图像的主要目的是减少噪声,这样采用平滑图像来降低噪声是是非常常见的预处理方法。

1.归一化滤波平滑-Homogeneous Smoothing

2.高斯滤波平滑-Gaussian Smoothing

3.中值滤波平滑-Median Smoothing

4.双边滤波平滑-Bilateral Smoothing

平滑是通过滑动窗口(内核或过滤器)扫描整个图像窗口,计算每个像素的基于核的值的和重叠的原始图像的像素的值的值来完成。这个过程在数学上称为具有一些内核卷积的图像。上述4种不同平滑方法唯一的区别就是内核。


例如, 5 x 5的核用来平滑(模糊)下面图片, 归一化块滤波器"Normalized box filter".



而高斯平滑(模糊)采用5x5的内核是如下。这个内核被称为“高斯核” "Gaussian kernel"



下面是关于平滑核(滤波器)比较重要的几个方面。
  • 平滑核的行像素数及列像素数必须是奇数(e.g. - 3x3, 11x5, 7x7, etc)
  • 平滑核的size越大,计算时间越长。


归一化滤波平衡 Homogeneous Smoothing

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

选择核的大小是很关键,如果选择太大,比较细微的图像特征可能被平滑掉,图像看起来很模糊。如果核选择太小,就可能无法完全删除噪声。

核定义如下:



OpenCV 代码

下面的OpenCV 的代码中,核大小从1x1增加到29x29.可以观察到图像平滑程度随着核增大的变化程度。平滑图像的核的大小显示在被平滑图像上。

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main( int argc, char** argv )
{
 //create 2 empty windows
 namedWindow( "Original Image" , CV_WINDOW_AUTOSIZE );
 namedWindow( "Smoothed Image" , CV_WINDOW_AUTOSIZE );

 // Load an image from file
 Mat src = imread( "MyPic.JPG", 1 );

 //show the loaded image
 imshow( "Original Image", src );

 Mat dst;
 char zBuffer[35];

 for ( int i = 1; i < 31; i = i + 2 )
 { 
      //copy the text to the "zBuffer"
      _snprintf_s(zBuffer, 35,"Kernel Size : %d x %d", i, i);

      //smooth the image in the "src" and save it to "dst"
      blur( src, dst, Size( i, i ) );

      //put the text in the "zBuffer" to the "dst" image
      putText( dst, zBuffer, Point( src.cols/4, src.rows/8), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );

      //show the blurred image with the text
      imshow( "Smoothed Image", dst );

      //wait for 2 seconds
      int c = waitKey(2000);

      //if the "esc" key is pressed during the wait, return
      if (c == 27)
      {
           return 0;
      }
 }

 //make the "dst" image, black
 dst = Mat::zeros( src.size(), src.type() );

 //copy the text to the "zBuffer"
 _snprintf_s(zBuffer, 35,"Press Any Key to Exit");

 //put the text in the "zBuffer" to the "dst" image
 putText( dst, zBuffer, Point( src.cols/4,  src.rows / 2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );

 //show the black image with the text
 imshow( "Smoothed Image", dst );
 
 //wait for a key press infinitely
 waitKey(0);
     
 return 0;

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////








 
平滑图像 -可以看到随着平滑核增大,图像逐渐变得模糊

新OpenCV函数详解

void blur( InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType = BORDER_DEFAULT )
  • src - 源图像. (图像位深必须是; CV_8U, CV_16S, CV_16U, CV_32F or CV_64F)
  • dst - 输出图像 (必须与源图像大小及位深一致)
  • ksize - 核大小
  • anchor - 点(-1,-1)的值意味着anchor是核中心的值。如果愿意可以自己定义自己的点。
  • borderType - Y可以定义不同的边界插入方法,这个值仅仅影响边缘的像素。 (可选参数: BORDER_DEFAULT, BORDER_REFLECT, BORDER_REPLICATE, BORDER_TRANSPARENT, BORDER_REFLECT_101 )

  • void putText( Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false )
这个OpenCV 函数在图像上显示文字
  • img - 欲显示文字的图片
  • text - 欲在图片显示的文字
  • org - 文本字符串在图像的左下角
  • fontFace - 字体类型 (可选字体有: FONT_HERSHEY_SIMPLEX, FONT_HERSHEY_PLAIN, FONT_HERSHEY_DUPLEX, FONT_HERSHEY_COMPLEX, FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL, FONT_HERSHEY_SCRIPT_SIMPLEX or FONT_HERSHEY_SCRIPT_COMPLEX. 上面任何一个字体可以与FONT_ITALIC"按位与"(bitwise or)可以得到斜体字)
  • fontScale - 缩放因子(如果设为1,默认大小)
  • color - 文本以BGR颜色定义
  • thickness - 字粗
  • lineType - 线类型
  • bottomLeftOrigin - 如果为true,原点设置在左下角。否则原点设定在左上角

  • static MatExpr zeros(Size size, int type)
    这个OpenCV的函数将返回指定的大小和类型的数组与零值
  • size - 数组大小( e.g - Size(no. of columns, no. of rows)  )
  • type -数组元素类型


Gaussian Smoothing


"高斯平滑" 也叫 "高斯模糊" 或 "高斯过滤".是比较常用的一个平滑方法。是比较常见的平滑方法。也用于去除图像噪声。高斯核滑动扫描图像来对图像进行平滑。
内核的大小和在X和Y方向上的高斯分布的标准偏差应慎重选择。

OpenCV 代码

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main( int argc, char** argv )
{
 //create 2 empty windows
 namedWindow( "Original Image" , CV_WINDOW_AUTOSIZE );
 namedWindow( "Smoothed Image" , CV_WINDOW_AUTOSIZE );

 // Load an image from file
 Mat src = imread( "MyPic.JPG", CV_LOAD_IMAGE_UNCHANGED );

 //show the loaded image
 imshow( "Original Image", src );

 Mat dst;
 char zBuffer[35];

 for ( int i = 1; i  <  31; i = i + 2 )
 { 
  //copy the text to the "zBuffer"
  _snprintf_s(zBuffer, 35,"Kernel Size : %d x %d", i, i);

  //smooth the image using Gaussian kernel in the "src" and save it to "dst"
  GaussianBlur( src, dst, Size( i, i ), 0, 0 );

  //put the text in the "zBuffer" to the "dst" image
  putText( dst, zBuffer, Point( src.cols/4, src.rows/8), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255), 2 );

  //show the blurred image with the text
  imshow( "Smoothed Image", dst );

  //wait for 2 seconds
  int c = waitKey(2000);

  //if the "esc" key is pressed during the wait, return
  if (c == 27)
  {
   return 0;
  }
 }

 //make the "dst" image, black
 dst = Mat::zeros( src.size(), src.type() );

 //copy the text to the "zBuffer"
 _snprintf_s(zBuffer, 35,"Press Any Key to Exit");

 //put the text in the "zBuffer" to the "dst" image
 putText( dst, zBuffer, Point( src.cols/4,  src.rows / 2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );

 //show the black image with the text
 imshow( "Smoothed Image", dst );
 
 //wait for a key press infinitely
 waitKey(0);
     
 return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////







 
采用高斯模糊后得到的图像
新出现的OpenCV函数
上面例子中OpenCV几乎都在之前例子中见到过。
  • void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )
这个OpenCV函数中高斯模糊的核的定义,图像的所有通道都独立的进行处理。

  • src - 源图像 (图像位深定义CV_8U, CV_16S, CV_16U, CV_32F or CV_64F)
  • dst -  输出图像 (与输入图像位深及大小必须一致)
  • ksize - 高斯平滑核大小 (核大小必须为正奇数)
  • sigmaX - 在X方向的标准偏差。如果使用0,它会自动从内核尺寸计算
  • sigmaY - 在Y方向的标准偏差。如果使用0,它会取和sigmaX一样的值. 
  • borderType - 可以定义各种边界插值方法。该值只影响在边界的像素。 ( k; BORDER_DEFAULT,可选参数 BORDER_REFLECT, BORDER_REPLICATE, BORDER_TRANSPARENT, BORDER_REFLECT_101 )


Median Smoothing


“平均平滑处理”也被称为“中间模糊处理”或“值滤波”。这也是一种常见的平滑技术。输入图像进行卷积用中值的内核。中值滤波是广泛用于边缘检测算法,因为在某些情况下,它保留边缘的同时去除噪声。

OpenCV Code

代码和上面的代码只有一行不一样。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int main( int argc, char** argv )
{
 //create 2 empty windows
 namedWindow( "Original Image" , CV_WINDOW_AUTOSIZE );
 namedWindow( "Smoothed Image" , CV_WINDOW_AUTOSIZE );

 // Load an image from file
 Mat src = imread( "MyPic.JPG", CV_LOAD_IMAGE_UNCHANGED );

 //show the loaded image
 imshow( "Original Image", src );

 Mat dst;
 char zBuffer[35];

 for ( int i = 1; i  <  31; i = i + 2 )
 { 
  //copy the text to the "zBuffer"
  _snprintf_s(zBuffer, 35,"Kernel Size : %d x %d", i, i);

  //smooth the image using Median kernel in the "src" and save it to "dst"
  medianBlur( src, dst, i );

  //put the text in the "zBuffer" to the "dst" image
  putText( dst, zBuffer, Point( src.cols/4, src.rows/8), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255), 2 );

  //show the blurred image with the text
  imshow( "Smoothed Image", dst );

  //wait for 2 seconds
  int c = waitKey(2000);

  //if the "esc" key is pressed during the wait, return
  if (c == 27)
  {
   return 0;
  }
 }

 //make the "dst" image, black
 dst = Mat::zeros( src.size(), src.type() );

 //copy the text to the "zBuffer"
 _snprintf_s(zBuffer, 35,"Press Any Key to Exit");

 //put the text in the "zBuffer" to the "dst" image
 putText( dst, zBuffer, Point( src.cols/4,  src.rows / 2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );

 //show the black image with the text
 imshow( "Smoothed Image", dst );
 
 //wait for a key press infinitely
 waitKey(0);
     
 return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


New OpenCV Functions

  • void medianBlur( InputArray src, OutputArray dst, int ksize )

所有的通道图像平滑都是独立的
  • src - 输入源图像 ( images with 1, 3 or 4 channels / Image depth should be CV_8U for any value of "ksize". If "ksize" equals 3 or 5, image depths of CV_16U and CV_32F are also supported.
  • dst - 输出图像 (需与源图像大小和位深一致)
  • ksize - 滤波器的大小 ( 必须是奇数且大于1 ) (注意 - 滤波器的尺寸大小为ksize ksize)

双边平滑 Bilateral Smoothing


“双边平滑处理”也被称为“双边模糊处理”或“双边滤波”。这是最先进的过滤器,以平滑图像和减少噪音。同时去除噪声上述所有过滤器会抚平的边缘。但该过滤器能够减少图像的噪声,同时保留边缘。这种类型的过滤器的缺点是,它需要较长的时间来处理。

OpenCV 代码
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main( int argc, char** argv )
{
 //create 2 empty windows
 namedWindow( "Original Image" , CV_WINDOW_AUTOSIZE );
 namedWindow( "Smoothed Image" , CV_WINDOW_AUTOSIZE );

 // Load an image from file
 Mat src = imread( "MyPic.JPG", CV_LOAD_IMAGE_UNCHANGED );

 //show the loaded image
 imshow( "Original Image", src );

 Mat dst;
 char zBuffer[35];

 for ( int i = 1; i  <  31; i = i + 2 )
 { 
  //copy the text to the "zBuffer"
  _snprintf_s(zBuffer, 35,"Kernel Size : %d x %d", i, i);

  //smooth the image using Bilateral filter in the "src" and save it to "dst"  bilateralFilter( src, dst, i, i, i);

  //put the text in the "zBuffer" to the "dst" image
  putText( dst, zBuffer, Point( src.cols/4, src.rows/8), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255), 2 );

  //show the blurred image with the text
  imshow( "Smoothed Image", dst );

  //wait for 2 seconds
  int c = waitKey(2000);

  //if the "esc" key is pressed during the wait, return
  if (c == 27)
  {
   return 0;
  }
 }

 //make the "dst" image, black
 dst = Mat::zeros( src.size(), src.type() );

 //copy the text to the "zBuffer"
 _snprintf_s(zBuffer, 35,"Press Any Key to Exit");

 //put the text in the "zBuffer" to the "dst" image
 putText( dst, zBuffer, Point( src.cols/4,  src.rows / 2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );

 //show the black image with the text
 imshow( "Smoothed Image", dst );
 
 //wait for a key press infinitely
 waitKey(0);
     
 return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

新出现的OpenCV 函数
  • void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
此OpenCV的功能筛选使用双边内核的图像。每个通道独立进行处理。此方法不到位工作。实时应用,“d”的值建议使用一个小于5值。
  • src - 输入图像 (单通道或者三通道图像)
  • dst - 输出图像(与输入图像属性一致)
  • - 像素领域直径
  • sigmaColor - 在颜色空间的sigma
  • sigmaSpace - 在坐标空间的sigma
  • borderType 可以定义各种边界插值方法。该值只影响在边界的像素。(可选参数如下: BORDER_DEFAULT, BORDER_REFLECT, BORDER_REPLICATE, BORDER_TRANSPARENT, BORDER_REFLECT_101 )
版权声明:本文为博主原创文章,未经博主允许不得转载。

Smooth 函数 平滑处理函数 OpenCV

OpenCV Smooth 函数 各种方法的图像平滑 void cvSmooth( const CvArr* src, CvArr* dst, int smoothtype=CV_GAUS...

OpenCV之cvSmooth函数平滑滤波

1、cvSmooth函数用法  定义原型    void cvSmooth( const CvArr* src, CvArr* dst,int smoothtype=CV_GAUSSIAN...

八.使用OpenCv对图像进行平滑操作

IplImage* CaptureImg() { IplImage* pImg = NULL; CvCapture* pCam = NULL; pCam = cvCreateCameraCap...

OpenCV图像处理篇之图像平滑

图像平滑算法图像平滑与图像模糊是同一概念,主要用于图像的去噪。平滑要使用滤波器,为不改变图像的相位信息,一般使用线性滤波器,其统一形式如下:其中h称为滤波器的核函数,说白了就是权值。不同的核函数代表不...

opencv3的图像模糊处理

#include using namespace std; using namespace cv;//包含cv命名空间 int main() { Mat src_img = imread("C:...

OpenCV-图像模糊

OpenCV-图像模糊在之前我们介绍了opencv图像的基本操作,这里介绍一下利用OpenCV进行图像模糊的几个函数:1、blur( src, dst, Size( i, i ), Point(-1,...
  • ahafg
  • ahafg
  • 2015年10月22日 21:42
  • 3041

Opencv学习笔记(四)--图像处理平滑,锐化操作

图像平滑算法图像平滑与图像模糊是同一概念,主要用于图像的去噪。平滑要使用滤波器,为不改变图像的相位信息,一般使用线性滤波器。几种不同的平滑方法:1. 归一化滤波器 Blurs an image us...

如何使用OpenCV的处理图像,文字变得锐利和清晰?(How to use OpenCV to process image so that the text become sharp and clea

问 题 Wanted to achieve something like this: http://www.leptonica.com/binarization.html ...

关于高斯模糊与opencv中的GaussianBlur函数

在上次的opencv源码解析之滤波前言1中,按照opencv_tutorials.pdf中的滤波部分试了下常用的4种滤波器的使用方法。在opencv的C++中,这4个函数分别为:blur,Gaussi...

我的OpenCV学习笔记(2):opencv中的模糊算法

模糊算法在图像处理时的使用再平常不过,有必要彻底的了解OpenCV中自带的所有模糊算法。 OpenCV中自带了4种模糊算法: blur(均值模糊)GaussianBlur(高斯模糊) ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【OpenCV_09】平滑/模糊图片 Smooth / Blur Images及 彩色图转 灰度图和二值化
举报原因:
原因补充:

(最多只允许输入30个字)