你可以看到在 边缘 ,相素值显著的 改变 了。表示这一 改变 的一个方法是使用 导数 。 梯度值的大变预示着图像中内容的显著变化。
用更加形象的图像来解释,假设我们有一张一维图形。下图中灰度值的”跃升”表示边缘的存在:
使用一阶微分求导我们可以更加清晰的看到边缘”跃升”的存在(这里显示为高峰值)
从上例中我们可以推论检测边缘可以通过定位梯度值大于邻域的相素的方法找到(或者推广到大于一个阀值)
Sobel 算子 Sobel 算子是一个离散微分算子 (discrete differentiation operator)。 它用来计算图像灰度函数的近似梯度。Sobel 算子结合了高斯平滑和微分求导。假设被作用图像为 :
在两个方向求导:
水平变化: 将 与一个奇数大小的内核 进行卷积。比如,当内核大小为3时, 的计算结果为:
垂直变化: 将:math:I 与一个奇数大小的内核 进行卷积。比如,当内核大小为3时, 的计算结果为:
在图像的每一点,结合以上两个结果求出近似 梯度:
有时也用下面更简单公式代替:
CV_EXPORTS_W 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 ); src和dst分别是待转的图像(src)和待转图像转换后的图像(dst);code是一个掩码,表示由src到dst之间是怎么转的,比如是彩色转为灰度,还是彩色转为HSI模式;最后的dstCn表示dst图像的波段数,这个值默认是0,它可以从参数code中推断。
code的模式包括:
CV_RGB2GRAY:<彩色图像---灰度图像>
CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB
CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB
CV_EXPORTS_W 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:输出的边缘检测结果图像,Mat型,大小与原图像相同。 int 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 注:ddepth =-1时,代表输出图像与输入图像相同的深度。 int dx:int类型dx,x 方向上的差分阶数,1或0 int dy:int类型dy,y 方向上的差分阶数,1或0 其中,dx=1,dy=0,表示计算X方向的导数,检测出的是垂直方向上的边缘;dx=0,dy=1,表示计算Y方向的导数,检测出的是水平方向上的边缘。 int ksize:为进行边缘检测时的模板大小为ksize*ksize,取值为1、3、5和7,其中默认值为3。特殊情况:ksize=1时,采用的模板为3*1或1*3。 scale 有些地方说是图片的深度变化比例 暂信(即将原深度为【0,1】变至【0,255】则scale应为255) delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中 这篇就差不多到这吧 还有两个函数是转化为绝对值的和求和的 就不写了 直接学后面的内容