以下内容的解释来自于《Computer Vision: Algorithms and Applications》(机器视觉:算法和应用)的作者Richard Szeliski以及《LearningOpenCV》。
1、平滑滤波又称为模糊,是一种简单且常用的图像处理操作。
2、对图像进行平滑的原因有很多种,在这篇文章中我们强调平滑的目的是减少图像噪声。
3、为了对图像进行平滑操作,我们会对我们的图像使用一个滤波器。最常见的滤波器是线性滤波器,它的原理是:输出的像素值由输入的像素值的邻域()权重值决定。
称为滤波核,它仅仅是个滤波器系数。它形象的描述了滤波窗口在图像上滑动的过程。
滤波器有有好多种,在这里我们介绍最常用的:
1 标准滤波器(邻域平均法)
该滤波器是所有滤波器里最简单的一种,输出的像素值由输入的滤波核所覆盖的像素值均值决定(每个邻域像素对其贡献的权重是相同的)。
滤波核可描述为:
2 高斯滤波(Gaussian)
该滤波器有可能是最有用的。高斯滤波通过对输入矩阵的每个元素使用高斯核进行卷积运算,然后将卷积结果赋给输出像素就可以了。
图1 一维高斯分布
一维高斯分布就是正太分布,如图1所示。
假设图像是一维的,你可以注意到中间的元素具有最大的权重值。在它之间的邻域权重按空间距离衰减。
注意:
记住二维高斯滤波的表达式为:
表示均值,就是图1里的最高点在X轴的投影,表示方差。
3 中值滤波(Median)
中值滤波器浏览图片中的每个像素,用滤波核覆盖的所有像素(处于被滤波像素的方形邻域内)的中值来代表滤波输出值。
4 双边滤波器(Bilatteral)
到目前为止,我们介绍的滤波器的主要目的是平滑图像。然而,这些滤波器不仅可以溶解噪声,同时还会平滑掉边缘。为了防止这种情况,我们可以使用双边滤波器。
类似于高斯滤波器,双边滤波器也对邻域内的每个像素值赋予一个权重。这个权重有2部分内容组成。第一部分是高斯滤波器一样的权重组成,第二部分考虑被检测像素与邻域像素的亮度变化程度。
Code
//全局变量
int G_DELAY_CAPTION =1500;
int G_DELAY_BLUR=2000;
int G_MAX_KERNAL_LENGTH=31; //最大滤波窗ä
Mat G_src;
Mat G_dst;
char G_window_name[]="FilterDemo1";
//函数声明
int display_caption(char*caption);
int display_dst(int delay);
void main()
{
namedWindow(G_window_name);
//加载原图像数据
G_src=imread("E:\\common\\building.jpg",1);
if(display_caption("OriginalImage")!=0)
{
return;
}
G_dst=G_src.clone();
if(display_dst(G_DELAY_CAPTION)!=0)
{
return;
}
cout<<"均¨´值¦Ì滤?波¡§"<<endl;
//使用邻域平均滤波器
for(int i=1;i<G_MAX_KERNAL_LENGTH;i=i+2)
{
blur(G_src,G_dst,Size(i,i));
if(display_dst(G_DELAY_BLUR)!=0)
{
return ;
}
}
cout<<"高?斯1滤?波¡§"<<endl;
//高斯滤波
for(int i=1;i<G_MAX_KERNAL_LENGTH;i=i+2)
{
GaussianBlur(G_src,G_dst,Size(i,i),0,0);
if(display_dst(G_DELAY_BLUR)!=0)
{
return;
}
}
//中值滤波
cout<<"中D值¦Ì滤?波¡§"<<endl;
for(int i=1;i<G_MAX_KERNAL_LENGTH;i=i+2)
{
medianBlur(G_src,G_dst,i);
if(display_dst(G_DELAY_BLUR)!=0)
{
return;
}
}
//双边滤波
cout<<"双?边À?滤?波¡§"<<endl;
for(int i=1;i<G_MAX_KERNAL_LENGTH;i=i+2)
{
bilateralFilter(G_src,G_dst,i,i*2,i/2);
if(display_dst(G_DELAY_BLUR)!=0)
{
return;
}
}
}
int display_caption(char*caption)
{
G_dst=Mat::zeros(G_src.size(),G_src.type());
putText(G_dst,caption,Point(G_src.cols/4,G_src.rows/4),CV_FONT_HERSHEY_COMPLEX,1,Scalar(255,255,0));
imshow(G_window_name,G_dst);
int c=waitKey(G_DELAY_CAPTION);
if(c>=0)
{
return-1;
}
return0;
}
int display_dst(int delay)
{
imshow(G_window_name,G_dst);
int c=waitKey(delay);
if(c>=0)
{
return-1;
}
return0;
}
/*解释
1、均值滤波¡-- blur(G_src,G_dst,Size(i,i))
G_src:原始图像
G_dst:目标图像
Size:滤波核的大小,为奇数
point(-1,-1):指出锚点(被改变的像素点)在滤波邻域中的位置。如果该值为负数,则认为a滤波核的中心就是锚点。
2、GaussianBlur(G_src,G_dst,Size(i,i),0,0)
G_src:原始图像
G_dst:目标图像
Size(w,h):滤波核的大小,w和h必须要是奇数和¨正数,否则就会被默认为使用标准差x和标准差y
标准差x:如果该值为0,则被认为标准差x使用滤波核x结构
标准差y:如果该值为0,则被认为标准差y使用滤波核y结构
3、medianBlur(G_src,G_dst,i)
G_src:原始图像
G_dst:目标图像
i:滤波核大小,必须是奇数。
4、bilateralFilter(G_src,G_dst,i,i*2,i/2)
G_src:原始图像
G_dst:目标图像
d:每个像素邻域的直径
color:颜色空间的标准差
space:坐标空间的标准Á差
*/
理论:
以下内容的解释来自于《Computer Vision: Algorithms and Applications》(机器视觉:算法和应用)的作者Richard Szeliski以及《LearningOpenCV》。
1、平滑滤波又称为模糊,是一种简单且常用的图像处理操作。
2、对图像进行平滑的原因有很多种,在这篇文章中我们强调平滑的目的是减少图像噪声。
3、为了对图像进行平滑操作,我们会对我们的图像使用一个滤波器。最常见的滤波器是线性滤波器,它的原理是:输出的像素值由输入的像素值的邻域()权重值决定。
称为滤波核,它仅仅是个滤波器系数。它形象的描述了滤波窗口在图像上滑动的过程。
滤波器有有好多种,在这里我们介绍最常用的:
1 标准滤波器(邻域平均法)
该滤波器是所有滤波器里最简单的一种,输出的像素值由输入的滤波核所覆盖的像素值均值决定(每个邻域像素对其贡献的权重是相同的)。
滤波核可描述为:
2 高斯滤波(Gaussian)
该滤波器有可能是最有用的。高斯滤波通过对输入矩阵的每个元素使用高斯核进行卷积运算,然后将卷积结果赋给输出像素就可以了。
图1 一维高斯分布
一维高斯分布就是正太分布,如图1所示。
假设图像是一维的,你可以注意到中间的元素具有最大的权重值。在它之间的邻域权重按空间距离衰减。
注意:
记住二维高斯滤波的表达式为:
表示均值,就是图1里的最高点在X轴的投影,表示方差。
3 中值滤波(Median)
中值滤波器浏览图片中的每个像素,用滤波核覆盖的所有像素(处于被滤波像素的方形邻域内)的中值来代表滤波输出值。
4 双边滤波器(Bilatteral)
到目前为止,我们介绍的滤波器的主要目的是平滑图像。然而,这些滤波器不仅可以溶解噪声,同时还会平滑掉边缘。为了防止这种情况,我们可以使用双边滤波器。
类似于高斯滤波器,双边滤波器也对邻域内的每个像素值赋予一个权重。这个权重有2部分内容组成。第一部分是高斯滤波器一样的权重组成,第二部分考虑被检测像素与邻域像素的亮度变化程度。
Code
//全局变量
int G_DELAY_CAPTION =1500;
int G_DELAY_BLUR=2000;
int G_MAX_KERNAL_LENGTH=31; //最大滤波窗ä
Mat G_src;
Mat G_dst;
char G_window_name[]="FilterDemo1";
//函数声明
int display_caption(char*caption);
int display_dst(int delay);
void main()
{
namedWindow(G_window_name);
//加载原图像数据
G_src=imread("E:\\common\\building.jpg",1);
if(display_caption("OriginalImage")!=0)
{
return;
}
G_dst=G_src.clone();
if(display_dst(G_DELAY_CAPTION)!=0)
{
return;
}
cout<<"均¨´值¦Ì滤?波¡§"<<endl;
//使用邻域平均滤波器
for(int i=1;i<G_MAX_KERNAL_LENGTH;i=i+2)
{
blur(G_src,G_dst,Size(i,i));
if(display_dst(G_DELAY_BLUR)!=0)
{
return ;
}
}
cout<<"高?斯1滤?波¡§"<<endl;
//高斯滤波
for(int i=1;i<G_MAX_KERNAL_LENGTH;i=i+2)
{
GaussianBlur(G_src,G_dst,Size(i,i),0,0);
if(display_dst(G_DELAY_BLUR)!=0)
{
return;
}
}
//中值滤波
cout<<"中D值¦Ì滤?波¡§"<<endl;
for(int i=1;i<G_MAX_KERNAL_LENGTH;i=i+2)
{
medianBlur(G_src,G_dst,i);
if(display_dst(G_DELAY_BLUR)!=0)
{
return;
}
}
//双边滤波
cout<<"双?边À?滤?波¡§"<<endl;
for(int i=1;i<G_MAX_KERNAL_LENGTH;i=i+2)
{
bilateralFilter(G_src,G_dst,i,i*2,i/2);
if(display_dst(G_DELAY_BLUR)!=0)
{
return;
}
}
}
int display_caption(char*caption)
{
G_dst=Mat::zeros(G_src.size(),G_src.type());
putText(G_dst,caption,Point(G_src.cols/4,G_src.rows/4),CV_FONT_HERSHEY_COMPLEX,1,Scalar(255,255,0));
imshow(G_window_name,G_dst);
int c=waitKey(G_DELAY_CAPTION);
if(c>=0)
{
return-1;
}
return0;
}
int display_dst(int delay)
{
imshow(G_window_name,G_dst);
int c=waitKey(delay);
if(c>=0)
{
return-1;
}
return0;
}
/*解释
1、均值滤波¡-- blur(G_src,G_dst,Size(i,i))
G_src:原始图像
G_dst:目标图像
Size:滤波核的大小,为奇数
point(-1,-1):指出锚点(被改变的像素点)在滤波邻域中的位置。如果该值为负数,则认为a滤波核的中心就是锚点。
2、GaussianBlur(G_src,G_dst,Size(i,i),0,0)
G_src:原始图像
G_dst:目标图像
Size(w,h):滤波核的大小,w和h必须要是奇数和¨正数,否则就会被默认为使用标准差x和标准差y
标准差x:如果该值为0,则被认为标准差x使用滤波核x结构
标准差y:如果该值为0,则被认为标准差y使用滤波核y结构
3、medianBlur(G_src,G_dst,i)
G_src:原始图像
G_dst:目标图像
i:滤波核大小,必须是奇数。
4、bilateralFilter(G_src,G_dst,i,i*2,i/2)
G_src:原始图像
G_dst:目标图像
d:每个像素邻域的直径
color:颜色空间的标准差
space:坐标空间的标准Á差
*/