OpenCV实现的高斯滤波探究_1(《学习OpenCV》练习题第五章第三题ab部分)
2013-11-17 22:50
267 查看
首先看下OpenCV官方文档对于cvSmooth各个参数的解释:
Smoothstheimageinoneofseveralways.
C:voidcvSmooth(constCvArr*src,CvArr*dst,intsmoothtype=CV_GAUSSIAN,intparam1=3,intparam2=0,doubleparam3=0,doubleparam4=0)
其对于每个参数的解释如下:
param1–Thefirstparameterofthesmoothingoperation,theaperturewidth.Mustbeapositiveoddnumber(1,3,5,...)
param2–Thesecondparameterofthesmoothingoperation,theapertureheight.IgnoredbyCV_MEDIANandCV_BILATERALmethods.Inthecaseofsimplescaled/non-scaledandGaussianblurifparam2iszero,itissettoparam1.Otherwiseitmustbeapositiveoddnumber.
param3–InthecaseofaGaussianparameterthisparametermayspecifyGaussian
(standarddeviation).Ifitiszero,itiscalculatedfromthekernelsize:
Usingstandardsigmaforsmallkernels(
to
)givesbetterspeed.Ifparam3isnotzero,whileparam1andparam2arezeros,thekernelsizeiscalculatedfromthesigma(toprovideaccurateenoughoperation).
对于参数smoothtype为CV_GAUSSIAN的高斯滤波来讲,param1和param2是高斯滤波核(Gaussiankernel)的尺寸,param3为高斯核的标准差(详见博文:/article/5977894.html)。文档里已经说了当param3或者param4为零的时候,如何根据核的大小算出标准差,那么就如本题的情况,在param1和param2为零即变换核的高宽都为零的时候,如何根据param3和param4算出param1和param2呢?在OpenCV的smooth.cpp文件中有个createGaussianFilter函数,下面的代码即为当只提供标准差(平行向或者竖直向)的时候,如何算出核的大小,代码:
这里的sigma1即为param3,sigma2即为param4,可以看出,当图像的数据类型为8为无符号型时,核的大小(直径)为6*sigma+1,大概OpenCV认为半径为3*sigma的窗口就是高斯函数能量最集中的区域。至于在图像数据类型不为CV_8U的时候为什么核就变成了8*sigma+1就不得而知了。
下面回到本题。
我用来做变换的原始图像为:
param1=param2=9的结果图像(这时候的param3为1):
param1=param2=0的结果图像(这时候的param3为1):
上面这两幅图的视觉效果差不多,事实是这两幅图像完全一样,其峰值信噪比为正无穷大。
为什么?
上面已经说了当核大小为零的时候,OpenCV会根据你提供的sigma大小来得出核的大小,这里的sigma为1,所以得到的核大小应该是7(即param1=param2=7)
那么,核大小为9和核大小为7的高斯滤波出来的结果为什么会一模一样?
在smooth.cpp文件中的createGaussianFilter函数中,有两个矩阵(数据类型为Mat)kx和ky,在size=param1=param2的时候,这两个矩阵一样,且矩阵的大小为size行1列,因此在param1=param2=9,param3=1的时候这两个矩阵为(前面的括号表示行列索引,后面为该位置的数值):
其对应的高斯变换核为:
在param1=param2=7,param3=1的时候这两个矩阵为:
其对应的高斯变换核为:
可以看出,这两个矩阵除了第一个多了最外面的上面两行和左右两列外,里面是一模一样的,同时,多出来的行或者列除了一个数值为0.0001外,其余基本是零。这也就解释了核大小为9和核大小为7的高斯滤波出来的结果几乎是一模一样的(我这儿的例子是完全一模一样)。
param1=param2=9的结果图像(这时候的param3为4):
param1=param2=0的结果图像(这时候的param3为4):
可以看出这两个结果的视觉效果就不一样了,下面这个比上面那个药更模糊一点,事实也证明了这点,这两张图像的PSNR为26.565127。
在param1=param2=0,param3=4的时候,其参与运算的核大小是25(4*6+1),因此与核大小为9的结果当然有差别。
param1=param2=9的结果图像(这时候的param3为6):
param1=param2=0的结果图像(这时候的param3为6):
这两副图像的PSNR为22.688340,也属于差距比较大的两张图像。
可以得出,第二副图像变换核大小为37,与核大小为9的变换核滤波出来的结果当然有很大区别。
总结:1.在OpenCV所实现的高斯滤波中,param1或者param2为零(即变换核为0的时候),将根据param3或者param4的值算出变换核的大小;对于8位单通道图像,算法是size=6*sigma+1;
2.在产生高斯变换核的标准差(sigma)指定时,如果两个核大小差不多,很有可能出来的滤波结果图几乎完全一模一样;
3.在标准差固定时,变换核越大,滤波出来的图像越模糊,丢失的细节也就越多;
4.在变换核的尺寸固定时,标准差(即sigma,param3)越大,滤波出来的图像越模糊,丢失的细节也就越多。
Smoothstheimageinoneofseveralways.
C:voidcvSmooth(constCvArr*src,CvArr*dst,intsmoothtype=CV_GAUSSIAN,intparam1=3,intparam2=0,doubleparam3=0,doubleparam4=0)
其对于每个参数的解释如下:
param1–Thefirstparameterofthesmoothingoperation,theaperturewidth.Mustbeapositiveoddnumber(1,3,5,...)
param2–Thesecondparameterofthesmoothingoperation,theapertureheight.IgnoredbyCV_MEDIANandCV_BILATERALmethods.Inthecaseofsimplescaled/non-scaledandGaussianblurifparam2iszero,itissettoparam1.Otherwiseitmustbeapositiveoddnumber.
param3–InthecaseofaGaussianparameterthisparametermayspecifyGaussian
(standarddeviation).Ifitiszero,itiscalculatedfromthekernelsize:
Usingstandardsigmaforsmallkernels(
to
)givesbetterspeed.Ifparam3isnotzero,whileparam1andparam2arezeros,thekernelsizeiscalculatedfromthesigma(toprovideaccurateenoughoperation).
对于参数smoothtype为CV_GAUSSIAN的高斯滤波来讲,param1和param2是高斯滤波核(Gaussiankernel)的尺寸,param3为高斯核的标准差(详见博文:
//automaticdetectionofkernelsizefromsigma if(ksize.width<=0&&sigma1>0) ksize.width=cvRound(sigma1*(depth==CV_8U?3:4)*2+1)|1; if(ksize.height<=0&&sigma2>0) ksize.height=cvRound(sigma2*(depth==CV_8U?3:4)*2+1)|1;
这里的sigma1即为param3,sigma2即为param4,可以看出,当图像的数据类型为8为无符号型时,核的大小(直径)为6*sigma+1,大概OpenCV认为半径为3*sigma的窗口就是高斯函数能量最集中的区域。至于在图像数据类型不为CV_8U的时候为什么核就变成了8*sigma+1就不得而知了。
下面回到本题。
我用来做变换的原始图像为:
param1=param2=9的结果图像(这时候的param3为1):
param1=param2=0的结果图像(这时候的param3为1):
上面这两幅图的视觉效果差不多,事实是这两幅图像完全一样,其峰值信噪比为正无穷大。
为什么?
上面已经说了当核大小为零的时候,OpenCV会根据你提供的sigma大小来得出核的大小,这里的sigma为1,所以得到的核大小应该是7(即param1=param2=7)
那么,核大小为9和核大小为7的高斯滤波出来的结果为什么会一模一样?
在smooth.cpp文件中的createGaussianFilter函数中,有两个矩阵(数据类型为Mat)kx和ky,在size=param1=param2的时候,这两个矩阵一样,且矩阵的大小为size行1列,因此在param1=param2=9,param3=1的时候这两个矩阵为(前面的括号表示行列索引,后面为该位置的数值):
(0,0)-0.000134
(1,0)-0.004432
(2,0)-0.053991
(3,0)-0.241971
(4,0)-0.398943
(5,0)-0.241971
(6,0)-0.053991
(7,0)-0.004432
(8,0)-0.000134
其对应的高斯变换核为:
在param1=param2=7,param3=1的时候这两个矩阵为:
(0,0)-0.004432
(1,0)-0.053991
(2,0)-0.241971
(3,0)-0.398943
(4,0)-0.241971
(5,0)-0.053991
(6,0)-0.004432
其对应的高斯变换核为:
可以看出,这两个矩阵除了第一个多了最外面的上面两行和左右两列外,里面是一模一样的,同时,多出来的行或者列除了一个数值为0.0001外,其余基本是零。这也就解释了核大小为9和核大小为7的高斯滤波出来的结果几乎是一模一样的(我这儿的例子是完全一模一样)。
param1=param2=9的结果图像(这时候的param3为4):
param1=param2=0的结果图像(这时候的param3为4):
可以看出这两个结果的视觉效果就不一样了,下面这个比上面那个药更模糊一点,事实也证明了这点,这两张图像的PSNR为26.565127。
在param1=param2=0,param3=4的时候,其参与运算的核大小是25(4*6+1),因此与核大小为9的结果当然有差别。
param1=param2=9的结果图像(这时候的param3为6):
param1=param2=0的结果图像(这时候的param3为6):
这两副图像的PSNR为22.688340,也属于差距比较大的两张图像。
可以得出,第二副图像变换核大小为37,与核大小为9的变换核滤波出来的结果当然有很大区别。
总结:1.在OpenCV所实现的高斯滤波中,param1或者param2为零(即变换核为0的时候),将根据param3或者param4的值算出变换核的大小;对于8位单通道图像,算法是size=6*sigma+1;
2.在产生高斯变换核的标准差(sigma)指定时,如果两个核大小差不多,很有可能出来的滤波结果图几乎完全一模一样;
3.在标准差固定时,变换核越大,滤波出来的图像越模糊,丢失的细节也就越多;
4.在变换核的尺寸固定时,标准差(即sigma,param3)越大,滤波出来的图像越模糊,丢失的细节也就越多。
相关文章推荐
- Linux命令-----grep不查找隐藏文件夹的方法
- Grep命令详解
- 大型网站架构不得不考虑的10个问题
- Linux命令--sort
- 对.net系统架构改造的一点经验和教训
- 大型网站架构演变
- Port 80 in use by "Unable to open process" with PID 4
- 浅谈大型web系统架构(一)
- Linux命令--tail
- 一个自动打包的shell
- Linux基础知识之挂载
- 第四个程序opengl简单的动画效果。
- 导出某个OU账户
- linux僵死进程
- STL中copy算法
- hadoop 2.0 native
- hadoop 2.0 lzo 问题
- Linux之进程的终止
- emacs配置
- linux下安装gcc编译器