说明:

        本系列是我本人在学习人工智能的过程中的总结性文档,我的原则是尽量使用自己的语言来描述各种概念和原理,其中若有原文借鉴之处,我会尽量标明转载出处,若有遗漏,还请留言说明,文中内容若有不妥,还请斧正,不胜感激!

滤波系列详细说明:

本系列描述的 函数 和 类 用于对2D图片执行线性或非线性的各种滤波操作;在openCV中图片通常以 Mat 数据类型来表示;滤波的操作意味着对于源图(通常是矩形)中的每一个像素位置 ,它的临近的像素值被考率且用于目标像素的计算。在线性滤波器的实例中,滤波的过程为:具有权重的像素值的加和。在形态的操作中,滤波的过程为:提取最大或最小的像素值;计算的像素值被存储在目标图像的相同位置处。输出的图像和原图像具有相同的尺寸;该功能支持多-通道数组,每一个通道被独立处理;输出图像具有与原图像相同的通道数。

        本章节描述的函数和类的另一个常见特征为:

不同于简单的算数功能,这里描述的函数和类需要推断一些不存在的像素点的值;

        比如,举例来说,你想要使用一个高斯  滤波器来平滑一个图片,那么当处理图片最左侧的各行像素点时,你需要知道该像素点左侧的“像素点的值”(但该点并不存在,该点已经超出了图片的范围),你可以让这些不存在的像素点的像素值同实际存在的像素点的像素值一样(重复边界-推断法),或者假设所有这些不存在的像素点的像素值为0(常量边界-推断法),等等。OpenCV让你能够制定边界推断法。

bilateralFilter():

函数原型:C++

void cv::bilateralFilter(InputArray src,

OutputArray dst,

int d,

double sigmaColor,

double sigmaSpace,

int borderType=BORDER_DEFAULT)

函数原型:python

cv.bilateralFilter(src,d,sigmaCOlor,sigmaSpace[,dst[,borderType]])->dst

        说明:对图像应用双边过滤器。

双边过滤器可以有效的去除噪点,同时又保持边界的清晰同大多数过滤器相比其计算速度较慢此过滤器不能原位工作

        参数说明:

 src :原图像,8-bit 或者 浮点,单通道 或者 3通道 图像;dst : 目标图像,同原图像具有相同的尺寸和类型;d :过滤操作中的每一个像素的邻域直径,,如果其为非正数,该过滤器从坐标空间计算,大的过滤器(比如d>5)是非常慢的,所以对于实时应用而言推荐d=5,对于离线的应用,需要较强的噪点过滤能力,可以设置d=9sigmaColor: 过滤器 在颜色空间的 sigma 值,大的参数值意味着像素值邻域内的父像素值将会混合在一起,得到一个较大范围的半等色区域;sigmaSpace:过滤器在坐标空间的 sigma值,大的参数值意味着父像素将会彼此影响,只要他们的颜色足够接近,当 d >0 时 该d参数指定邻域的大小而不考虑sigmaSpace参数,否则,d正比于sigmaSpace。Sigma 值:对于相似性,如果两个 sigma 的值较小,比如  <10,你可以设置两者相同,过滤器的效果不明显;当两个 sigma 的值较大,比如 >150 ,两个sigma的值具有强烈的效果,使得图片看起来更加“卡通化”。borderType:边界模式,用于扩展的图像外部的像素。

        c++实例:

#include

#include

#include

#include

using namespace cv;

int DELAY_CAPTION=1500;

int MAX_KERNEL_SIZE=31;

Mat src;

Mat dst;

char window_name[]="Smoothing Demo";

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));

return display_dst(DELAY_CAPTION);

}

int display_dst(int delay)

{

imshow(window_name,dst);

int c=waitKey(delay);

if(c>=0)

{

return -1;

}

return 0;

}

int main(int argc,char** argv)

{

namedWindow(window_name,WINDOW_AUTOSIZE);

const char* filename=argc>=2?argv[1]:"lenna.jpg";

src=imread(samples::findFile(filename),IMREAD_COLOR);

for(int i=1;i

{

bilateralFilter(src,dst,i,i*2,i/2);

}

display_caption("Done!");

return 0;

}

原理介绍

        过滤可能是对图片处理和计算机视觉的最基础操作。在术语“过滤”的广泛含义中,在给定位置进行图片值的过滤是在输入图片的给定位置的一个小的邻域区间内的像素值的函数。比如,高斯-低通滤波在像素值的邻域区间内计算具有权重的平均值,这里权重值随着距离邻域中心距离的减小而减小。虽然可以给出权重降低的书面和量化的解释,给人的直觉为图像随着空间的变化变化的比较缓慢,所以邻近的像素值很大的可能具有相似的像素值,因此对他们取均值是合适的。噪点的像素值破环了这个邻域区间像素变化缓慢的特性,且同正常的信号值具有更小的相关性,所以在信号被存储后噪点被平均化了。

        随空间变化缓慢的假设在图片的边界处是不正确的,因此在边界处的线性低通-滤波将会使得图像变得模糊。在进行平滑区域内的均值化处理时,我们如何阻止图片边界处的均值化损失?业内人士也做出了很多的努力和尝试,有机会会详细介绍。

        各向异性扩散是一个流行的回答:在每一个像素点测量局部图像的变化,像素的值被来自于临近区域的像素值平均,该临近区域的大小和形状依赖于局部变化特性。扩散方法平均化该扩展的临近区域通过计算偏微分方程,且因此而继承了迭代性。迭代可能产生稳定性的问题,且以来于计算架构和效率。

        bilateralFilter是一个非迭代的简单方案用于边界保护平滑。虽然我们宣称该方法同神经生理学观察没有关系,但我们还是指出我们的方案可以通过一个同神经类似的方法单层实现对每一个图像的操作。

        更进一步,我们的方案允许显式的实施任何想要的光度距离概念。这对于过滤彩色图片是相当重要的。如果彩色图像的三波段是从一个到另一个单独被过滤的,那么接近图像边缘的颜色被破坏。事实上,不同的波段具有不同的对比度级别,且他们是分别被平滑的。独立的平滑操作扰乱了颜色的平衡,且出现了不期望的颜色合成。另一方面,双边过滤器可以一次操作三个波段,且可以明确的告知用户哪些颜色是相似的而其他的那些是不相似的。仅对认知相似的颜色一起进行平均操作,且上述提到的那些副作用不见了。

        双边过滤的底层思想是对一张图片做一定像素值范围内的过滤操作正如那些传统过滤器在像素坐标区域内所做的过滤操作一样。

        两个像素可以彼此接近:

占据临近的空间位置像素值彼此相似

        可能以一种感知意义上的方式彼此接近,接近指的是区域的附近,范围附近的相似。传统的滤波是区域滤波,并通过给像素值分配权重来加强近似,这些权重系数的值随着距离的增加而减小。类似的我们定义范围滤波,该滤波方法用权重系数平均图片值,这些权重系数随着相似性的变弱而减小。范围滤波是非线性的,因为权重依赖于图像的强度分布和颜色。从计算方面讲该方法并不比标准不可分滤波方法更复杂。最重要的是,范围滤波保存边缘。

        空间的局部性是一个本质的概念,事实上,我们展示的范围滤波方法仅仅扭曲图片的颜色映射。然后我们合并范围滤波和区域滤波,试验的结果表明该合并操作更为有趣。我们将此合并的滤波方法称为双边滤波。

        因为双边滤波采用一个明确的概念:那就是在图像函数的区域内和范围内的距离,这两个距离的概念可以被定义在任何函数中。特别的,双边滤波可以被应用于彩色图片就像他被应用于黑白图片一样早。CIE-Lab 色彩空间赋予颜色空间以颜色相似性测量的感知意义,在CIE-Lab色彩空间中短的欧拉距离同人类颜色识别能力强烈关联。因此,如果在我们的双边滤波器中使用这种度量,图片被平滑且边缘被保留,且以一种适合人类感知的方式。仅仅视觉上像素的颜色被平均,且仅仅视觉可见的边缘被保留。

        Bilateral filtering是一个简单的,非迭代方案的边缘保护平滑方法。

以一个非线性临近图像值合并的方式,双边过滤器在平滑图像的同时保留边界;该方法是非迭代的,局部的和简单的;该方法基于几何的接近性和光度的相似性合并灰度级或者颜色;在区域滤波和范围滤波中,该方法更倾向于临近的图像值而不是较远的图像值;同独立的操作彩色图片的三波段滤波器的对比发现:双边滤波器可以加强CIE-Lab颜色空间底层的感知度量;以人类感知的方式平滑颜色和保存边界;同标准的过滤器相比,双边过滤器沿着彩色图片的边缘不产生幻色现象且减少原始图像中出现的幻色现象。

算法思想

        一个低通区域滤波器应用于图片,产生一个输出图像  按照以下公式定义:

        这里测量几何上的接近性,在中心 x 和附近点  之间,

        f 和 h 强调输入和输入的图像可能是多频段的事实。

        如果低通滤波的方法用于保留低通信号的直流分量,我们得到:

        如果滤波器是平移不变的,仅是矢量差值  的函数,且  是一个常数。

        范围滤波的定义类似区域滤波:

        

        这里  测量中心像素  和附近点  像素的光度相似性,因此相似函数 s 在图像 f 的范围内起作用。而接近函数 c 在图像 f 的 区域内起作用。归一化系数为:

        同接近函数 c 对比,相似性函数 s 的归一化依赖于图像 f 。我们说相似性函数 s 是无偏的,如果他仅仅依赖于差值  .

         图像强度的空间分布在范围滤波的过程中并不起作用。然而整个图片的结合并强度反倒是有些借鉴意义,这是因为远离x的图像值的分布应当不影响x的当前图像值,还有,第三部分中我们将展示范围滤波自己仅仅改变图像的颜色映射,因此用处不大。合适的解决方案是合并区域滤波和范围滤波,也就是既强调几何局部性也强调光度分布局部性。两者合并的滤波方法可以表示为:

        

        标准化系数为:

        

        合并的区域滤波和范围滤波标记为双边滤波,他以一个相似性的像素值和区域内的像素值的均值替代了位置x处的像素值。在平滑的区域内部,小邻域内的像素值是彼此相似的,且归一化的相似性函数   接近于1。因此,双边滤波器本质上起了一个标准的区域滤波器的作用,且通过平均化的操作去除了小的,以及由噪声引起的与像素值关联性较小的差异。当双边滤波器位置处于一个边界附近亮边的像素上时,相似性函数 s 假设在相同亮边一侧的像素值接近1,而在另外一侧的暗区像素值接近于0,归一化项  确保所有像素值的累加和为1.结果是,过滤器以一个临近区域的明亮的像素的平均值在中心位置处替换了原像素的值,并且忽略了暗像素的值。相反的,当过滤器位于一个暗的像素上时,明亮的像素被忽略。得益于双边过滤器的区域分量,在边界处具有一个好的过滤效果,同时得益于双边过滤器的范围分量,同时保留了清晰的边界。

源码

void bilateralFilter(InputArray _src,outpuArray _dst,int d,double sigmaColor,

double sigmaSpace,int borderType)

{

CV_INSTRUMENT_REGION();//用于追踪函数的宏

CA_Assert(!_src.empty());//判断源文件是否为空

_dst.create(_src.size(),_src.type());//创建目标图像以便放置数据

//如果是单通道图像,运行ocl_bilateralFilter_8u

CV_OCL_RUN(_src.dims()<=2 && _dst.isUMat(),ocl_bilateralFilter_8u(_src,_dst,d,sigmaColor,sigmaSpace,borderType));

Mat src=_src.getMat(),dst=_dst.getMat();

//如果系统安装了IPP库则运行

CV_IPP_RUN_FAST(ipp_bilateralFilter(_src,_dst,d,sigmaColor,sigmaSpace,borderType));

if(src.depth()==CV_8U)

{

bilateralFilter_8u(src,dst,d,sigmaColor,sigmaSpace,borderType);

}

else if(src.depth()==CV_32F)

{

bilateralFilter_32f(src,dst,d,sigmaColor,sigmaSpace,borderType);

}

else

{

CV_Error(CV_StsUnsupportedFormat,"Bilateral filtering is only implemented for 8u and 32f images");

}

}

        更详细的内容,请查看源码!

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。