学习OpenCV范例(十)——图像平滑处理
2014-03-16 23:34
525 查看
接下来的范例学习都集中在图像处理方面的学习,首先学习的是图像的平滑处理,相信学过图像处理的同学都不陌生,图像的平滑处理很普遍,最主要的功能就是去噪声,在OpenCV中最经常使用的平滑处理有四种:均值滤波,中值滤波,高斯滤波,双边滤波,在OpenCV1版本中用到的函数是smooth函数,四种处理都包含在smooth函数中,而在OpenCV2版本中被分开了,分别是blur,medianblur,GaussianBlur,bilateralFilter,现在让我们来好好看一下这四个函数吧。
h(k,l) 称为 核, 它仅仅是一个加权系数。
不妨把 滤波器 想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口滑过图像。
所有像素加权系数相等)。
核如下:
。
均值滤波器对噪音图像特别是有大的孤立点的图像特别敏感,即是有较少数量点存在较大差异也会导致平均值的明显波动,而中值滤波可以通过选择中间值避免这些点的影响。
一维高斯函数:
从上图可以看出中间像素的加权系数是最大的,
周边像素的加权系数随着它们远离中间像素的距离增大而逐渐减小。
2维高斯函数可以表达为 :
其中 μ为均值 (峰值对应位置), σ
代表标准差 (变量 x 和 变量 y 各有一个均值,也各有一个标准差)
由于真实的像素点在空间中是缓慢变化的,因此邻近的像素变化不会很明显。但是随机很大的几个点就可能形成很大的像素差。就是因为这一点,高斯滤波器在保留信号的情况下可以减少噪音。但是仍然不可避免会磨平边缘,只不过效果会比均值和中值滤波器的好。
这些加权系数包含两个部分, 第一部分加权方式与高斯滤波一样,第二部分的权重则取决于该邻域像素与当前像素的灰度差值。它可以在减少噪声的同时,最大程度的保护了边缘,但是需要更多的处理时间。可以把双边滤波器视为高斯平滑,对相似的像素赋予较高的权值,对不相似的像素赋予较低的权值。
密码:cool
结构:
dst :目标图像,和源图像有同样的size和type
ksize :核的大小
anchor :核的中心 默认值为Point(-1,-1),是核的中点
borderType:边缘点插值类型
核如下:
结构:
dst : 目标图像,和源图像有同样的size和type
ksize : 正方形的边长. 边长必须是奇数而且大于1
中值滤波器将像素领域内灰度的中值代替该像素的值,如果是多通道的图像,则每个通道单独处理,支持in_place操作(输入图像指针与输出图像指针是同一个指针)。
结构:
dst :目标图像,和源图像有同样的size和type
ksize :高斯核大小,ksize.width 和ksize.height可以不同,但是都必须是正整数而且是奇数,也可以是O,如果是0的话,它的值 由sigmaX和sigmaY决定
sigmaX : X方向上的标准差
sigmaY :Y方向上的标准差,如果Y方向为0,则被设置和X方向一样,如果X和Y方向都为0,则它们由ksize.width和ksize.height计 算得到,建议全部都给定数值。
borderType:边缘点插值类型
具有标准sigma值的3*3,5*5和7*7比其他核具有更优的性能,支持in_place操作。
结构:
dst :目标图像,和源图像有同样的size和type
d :每个像素领域的直径,如果为负数,则由sigmaSpace确定
sigmaColor :颜色空间的标准偏差
sigmaSpace :坐标空间的标准偏差
borderType:边缘点插值类型
有关滤波详细的说明和代码解析可以转到/article/7834379.html
1、原理
平滑处理时需要用到一个 滤波器 。 最常用的滤波器是 线性 滤波器,线性滤波处理的输出像素值 (i.e. g(i,j)) 是输入像素值 (i.e. f(i+k,j+l))的加权和 :h(k,l) 称为 核, 它仅仅是一个加权系数。
不妨把 滤波器 想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口滑过图像。
①、均值滤波器
最简单的滤波器, 输出像素值是核窗口内像素值的 均值 (所有像素加权系数相等)。
核如下:
②、中值滤波器
中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替。
均值滤波器对噪音图像特别是有大的孤立点的图像特别敏感,即是有较少数量点存在较大差异也会导致平均值的明显波动,而中值滤波可以通过选择中间值避免这些点的影响。
③、高斯滤波器
最有用的滤波器 (尽管不是最快的)。 高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值。一维高斯函数:
从上图可以看出中间像素的加权系数是最大的,
周边像素的加权系数随着它们远离中间像素的距离增大而逐渐减小。
2维高斯函数可以表达为 :
其中 μ为均值 (峰值对应位置), σ
代表标准差 (变量 x 和 变量 y 各有一个均值,也各有一个标准差)
由于真实的像素点在空间中是缓慢变化的,因此邻近的像素变化不会很明显。但是随机很大的几个点就可能形成很大的像素差。就是因为这一点,高斯滤波器在保留信号的情况下可以减少噪音。但是仍然不可避免会磨平边缘,只不过效果会比均值和中值滤波器的好。
④、双边滤波器
双边滤波器类似于高斯滤波器,双边滤波器也给每一个邻域像素分配一个加权系数。这些加权系数包含两个部分, 第一部分加权方式与高斯滤波一样,第二部分的权重则取决于该邻域像素与当前像素的灰度差值。它可以在减少噪声的同时,最大程度的保护了边缘,但是需要更多的处理时间。可以把双边滤波器视为高斯平滑,对相似的像素赋予较高的权值,对不相似的像素赋予较低的权值。
2、代码实现
#include "stdafx.h" /** * file Smoothing.cpp * brief Sample code for simple filters * author OpenCV team */ #include <iostream> #include <vector> #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/features2d/features2d.hpp" using namespace std; using namespace cv; /// Global Variables int DELAY_CAPTION = 1500; int DELAY_BLUR = 100; int MAX_KERNEL_LENGTH = 31; Mat src; Mat dst; char window_name[] = "Smoothing Demo"; /// Function headers int display_caption( const char* caption ); int display_dst( int delay ); /** * function main */ int main( void ) { namedWindow( window_name, WINDOW_AUTOSIZE ); /// Load the source image src = imread( "lena.png", 1 ); if( display_caption( "Original Image" ) != 0 ) { return 0; } dst = src.clone(); if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; } /// Applying Homogeneous blur 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; } } /// Applying Gaussian blur 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; } } /// Applying Median blur 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; } } /// Applying Bilateral Filter 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; } } /// Wait until user press a key display_caption( "End: Press a key!" ); waitKey(0); return 0; } /** * @function display_caption */ int display_caption( const char* caption ) { dst = Mat::zeros( src.size(), src.type() ); putText( dst, caption, Point( src.cols/4, src.rows/2), FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) ); imshow( window_name, dst ); int c = waitKey( DELAY_CAPTION ); if( c >= 0 ) { return -1; } return 0; } /** * @function display_dst */ int display_dst( int delay ) { imshow( window_name, dst ); int c = waitKey ( delay ); if( c >= 0 ) { return -1; } return 0; }
3、运行结果
密码:cool
4、用到的类和函数
blur:
功能:均值滤波结构:
void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )src :源图像
dst :目标图像,和源图像有同样的size和type
ksize :核的大小
anchor :核的中心 默认值为Point(-1,-1),是核的中点
borderType:边缘点插值类型
核如下:
medianBlur:
功能:中值滤波结构:
void medianBlur(InputArray src, OutputArray dst, int ksize)src :源图像可以是单通道、三通道、四通道的图像,当ksize是3或5的时候,图像的深度应该是CV_8U , CV_16U , or CV_32F,对 于更大的ksize,那么图像的深度只能是CV_8U
dst : 目标图像,和源图像有同样的size和type
ksize : 正方形的边长. 边长必须是奇数而且大于1
中值滤波器将像素领域内灰度的中值代替该像素的值,如果是多通道的图像,则每个通道单独处理,支持in_place操作(输入图像指针与输出图像指针是同一个指针)。
GaussianBlur:
功能:高斯滤波器结构:
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )src :源图像.
dst :目标图像,和源图像有同样的size和type
ksize :高斯核大小,ksize.width 和ksize.height可以不同,但是都必须是正整数而且是奇数,也可以是O,如果是0的话,它的值 由sigmaX和sigmaY决定
sigmaX : X方向上的标准差
sigmaY :Y方向上的标准差,如果Y方向为0,则被设置和X方向一样,如果X和Y方向都为0,则它们由ksize.width和ksize.height计 算得到,建议全部都给定数值。
borderType:边缘点插值类型
具有标准sigma值的3*3,5*5和7*7比其他核具有更优的性能,支持in_place操作。
bilateralFilter:
功能:双边滤波器结构:
void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )src :源图像为单通道或3通道的8比特图像
dst :目标图像,和源图像有同样的size和type
d :每个像素领域的直径,如果为负数,则由sigmaSpace确定
sigmaColor :颜色空间的标准偏差
sigmaSpace :坐标空间的标准偏差
borderType:边缘点插值类型
有关滤波详细的说明和代码解析可以转到/article/7834379.html
相关文章推荐
- OpenCv学习笔记之图像平滑处理
- OpenCV学习笔记(4)——平滑处理图像
- opencv2函数学习之blur,GaussianBlur,medianBlur和bilateralFilter:实现图像平滑处理
- Opencv学习笔记(四)--图像处理平滑,锐化操作
- opencv学习笔记6 图像平滑处理cvSmooth
- openCV学习笔记(二)------图像平滑处理和边缘检测
- 学习Opencv2之载入一幅图像并进行平滑处理
- OpenCV学习笔记02--利用滚动条控制视频;高斯滤波处理图像。
- (未实用 需多个函数配套使用)opencv3.0 函数学习 10——morphologyEx 形态学图像处理:开运算、闭运算、形态学梯度、顶帽、黑帽合辑
- Python OpenCV学习笔记之:图像滤波处理
- OpenCV系统学习:二、基本图像处理函数
- OpenCV自带例子(七)图像平滑处理
- OpenCV学习笔记(七)—— OpenCV for Android实时图像处理
- opencv学习(3)——高斯平滑图像
- opencv图像平滑处理
- 【OpenCV学习】图像的形态处理学
- OpenCV学习笔记(8)VS2008 MFC下使用OpenCV2.0进行简单图像处理
- OpenCV学习笔记(七)—— OpenCV for Android实时图像处理
- opencv 2 图像平滑处理
- 学习【OpenCV入门教程之十】 形态学图像处理(一):膨胀与腐蚀----思维导图笔记