在图像处理中我们时常需要将物体分割出来,或者区分前后景,等等。

在这些问题中,边缘似乎是不可避免的问题,如何取一个你认为对的“边缘”是至关重要的。

综上提出了“如何取边缘”的问题。

那么,首先为了解题,我们需要知道何谓“边缘”,换言之,边缘是怎么定义的。

当然,“边缘”定义在不同情况下有很多分歧。一般的,最常用的是阶梯型边缘

举一些简单的例子:

Java cv识别边缘 提取图片_阶梯型边缘

 (a)图:是理想情况,在一点突变。

(b)图:现实情况,具有一定坡度缓慢变化。

Java cv识别边缘 提取图片_阶梯型边缘_02

 可以这么理解:边缘在白色边缘像素的绝对左侧,当相机采样向左侧移动时,边缘向右移动。

现在的边缘就变成了白色像素和黑色像素的加权平均值。

Java cv识别边缘 提取图片_边缘检测_03

 

Java cv识别边缘 提取图片_边缘响应_04


Java cv识别边缘 提取图片_Java cv识别边缘 提取图片_05

分别是白色区域像素值和黑色区域的灰度值。

Java cv识别边缘 提取图片_Java cv识别边缘 提取图片_06


Java cv识别边缘 提取图片_卷积_07

分别是白色区域面积和黑色区域面积。

 

因为,边缘是由灰阶值的变化定义的。导数算子对其敏感,适用于检测边缘。

而图像像素点是离散的,不连续不可导的定理,高中就知道。所以,在图像处理中用差分运算代替导数。

Java cv识别边缘 提取图片_边缘检测_08

Java cv识别边缘 提取图片_边缘响应_09

上述等式其实是连续情况演变而来,但对于离散的数据,却存在较大问题。其实这种表达是计算中间像素

Java cv识别边缘 提取图片_Java cv识别边缘 提取图片_10

的斜率。

这里有价值深入讲一下,对于离散的像素点,如果按照上面的等式计算结果作为(x,y)的导数,那么结果就会有两个,也就是所求点作为(x,y) 和 (x-1,y-1)的时候。

为了防止歧义,将式子演变为如下:

Java cv识别边缘 提取图片_边缘响应_11

Java cv识别边缘 提取图片_边缘检测_12

不考虑(x,y)像素值。

引入衡量边缘的值:边缘响应

数学描述如下:

Java cv识别边缘 提取图片_阶梯型边缘_13

同样,转变为离散表达:

Java cv识别边缘 提取图片_边缘检测_14

 

最基本的理论知识理解了后,来看看主流的基于模板的边缘检测

模板也称“卷积掩模”。

可以这么理解,原先的x方向的边缘响应,和y方向的边缘响应,都是真正意义上的x,y方向,即一条直线(一维)

一、Sobel边缘检测器

x方向的边缘响应,利用三个方向(两条对角线,一条x直线方向)作为x方向的边缘响应,记作Sx,同理y方向的边缘响应,记作Sy。

他们就是长成如下样子:

Java cv识别边缘 提取图片_阶梯型边缘_15

Java cv识别边缘 提取图片_边缘响应_16

我们可以看到,在水平或垂直方向的权重大于对角线。

判别边缘还是用上面的

Java cv识别边缘 提取图片_阶梯型边缘_17

公式计算。

二、Marr-Hildreth边缘检测器。

设计思路:

①图像与高斯滤波函数进行卷积

②之后与拉普拉斯算子进行卷积

也称作Log(Laplacian of the Gaussian高斯拉普拉斯算子)

三、Canny Edge边缘检测器

精华在于它的非极大抑制,滞后双阈值化。

后续我回添加上自己实现的canny算法,当然你可以更改其中的边缘算子,达到不同效果。

 

 

这一章是归纳出现下常用的边缘识别方法,后续持续更新。。。