图像处理开发需求、图像处理接私活挣零花钱,请加微信/QQ 2487872782
图像处理开发资料、图像处理技术交流请加QQ群,群号 271891601
图像边缘检测的概念我就不多说了,可以参考上一篇博文(/wenhao_ir/article/details/51743382)或者查阅相关资料。
在这里,说下Sobel算子进行边缘检测和上一篇博文中提到的“利用图像在水平和垂直方向上的差分运算对图像进行边缘检测”的相似处和区别!
1 sobel算子也同上一篇博文中提到的边缘检测算法一样,在水平和垂直方向两个方向上作边缘检测运算。
2sobel算子利用的是滑动窗口(即卷积核)的方法进行边缘检测,虽然也是求像素点上下,左右的差值,但是它是加了权重的。
3sobel算对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。
再来说下函数Scharr
当Sobel核因子大小为3时,内核因子的计算可能会产生一定的误差,此时,OpenCV中我提供一个更精确的肉核心因子及Scharr函数,其计算的时间复杂度与Sobel相当。(不过,根据实际的程序来观察,我观察其效果还不如Sobel的三阶内核啊,大家等会儿可以看运行结果)
下面来解释下Sobel的函数原型:
void Sobel( InputArray src, OutputArray dst, int ddepth,int dx, int dy, int ksize=3,double scale=1, double delta=0,int borderType=BORDER_DEFAULT );
第一个参数,InputArray 类型的src,为输入图像,填Mat类型即可。
第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
第三个参数,int类型的ddepth,输出图像的深度,支持如下src.depth()和ddepth的组合:
若src.depth() = CV_8U, 取ddepth =-1/CV_16S/CV_32F/CV_64F
若src.depth() = CV_16U/CV_16S, 取ddepth =-1/CV_32F/CV_64F
若src.depth() = CV_32F, 取ddepth =-1/CV_32F/CV_64F
若src.depth() = CV_64F, 取ddepth = -1/CV_64F
第四个参数,int类型dx,x 方向上的差分阶数。(官方文档上也是这么说的,但是你看最后的结果明显是y方向上的差分阶数才对啊)
第五个参数,int类型dy,y方向上的差分阶数。(官方文档上也是这么说的,但是你看最后的结果明显是x方向上的差分阶数才对啊)
第六个参数,int类型ksize,有默认值3,表示Sobel核的大小;必须取1,3,5或7。
第七个参数,double类型的scale,计算导数值时可选的缩放因子,默认值是1,表示默认情况下是没有应用缩放的。我们可以在文档中查阅getDerivKernels的相关介绍,来得到这个参数的更多信息。
第八个参数,double类型的delta,表示在结果存入目标图(第二个参数dst)之前可选的delta值,有默认值0。【具体这个值有什么作用,我还不清楚】
第九个参数, int类型的borderType,我们的老朋友了(万年是最后一个参数),边界模式,默认值为BORDER_DEFAULT。这个参数我在前面的博文(/wenhao_ir/article/details/51699064)中已经讲过,这里不再赘述了!
Scharr函数只是比Sobel函数少了个ksize的参数,原因是它的ksize是定值3,所以当然不需要了!
下面上源程序:
源代码请参见博文0032-使用OpenCV对图像作边缘检测(Canny、Sobel、Laplace)_清溪算法-CSDN博客
图像处理开发需求、图像处理接私活挣零花钱,请加微信/QQ 2487872782
图像处理开发资料、图像处理技术交流请加QQ群,群号 271891601