目录
1 理论
下面是边缘检测的五个步骤
- 第一步滤波,之前提到过,此处canny边缘检测使用的是高斯滤波
- 第二步计算梯度,之前提到过,强度是该店的梯度值,方向是纵向与横向组成的方向
- 第三步抑制,使用 非极大值 方法,消除核内其他的梯度,取强度最高的梯度
- 非极大值抑制,我举个例子,现在做人脸识别,中间圆的是人脸,然后现在识别出红,蓝,黄,三个位置的框子,红色是人脸的概率99%,蓝色97%,黄色96%,非极大值抑制会将蓝色与黄色的框子抑制掉
- 第四步在确认边界时,有一些不是图片的边界,这个时候我们使用 双阈值 筛掉它
- 第五步再次抑制其他的若边缘最终完成边缘检测
1.1 第一步 高斯滤波
核不是固定的,是根据高斯分布走的,归一化是让值都小于1
1.2 第二步 梯度强度与方向
使用sobel算子
是该点梯度的方向
1.3 第三步 非极大值抑制
一共有两种方法
1.3.1 第一种方法
我们现在算出来c点的梯度强度,c点的梯度方向是橘黄色线向上的方向,我们现在要确定C点是不是梯度强度最大的点,我们要和C点的临近点比较,临近点除了C周围的八个像素点还有两个在C梯度方向上两个点,也就是说临近点是上图所示的除C外所有的黑点
C周围的八个像素点都可以使用sobel算子算出梯度强度,其余两个点(B和J)我们使用线性插值法进行计算
线性插值法是这样计算的,点B的位置是处于A和D之间的,那么我们给梯度强度A与梯度强度D两个权重,两个权重相加为1,乘以权重之后加和
梯度强度B = W * 梯度强度A + (1-W) * 梯度强度D
之后我们在说W怎么算,以我上面这个式子举例
W = B到A的距离 / A到D的距离
- 如果我的(1-W)放在了梯度强度A的前面,那么我的W = B到D的距离 / A到D的距离
我们计算出所有的临近值梯度取最大的就行了
1.3.2 第二种方法
我只对要进行最大值抑制点的八个方向的距离梯度方向最近的方向做非最大抑制,这八个方向分别是正东西南北,正东北西北东南西南,采用这八个方向也就是只考虑该点的另外八个临近像素点的梯度强度
比如我们上面这个图,那就只需要做ID这个方向,只计算ID这两个像素点的梯度强度
1.4 第四步 双阈值检测
maxVal和minVal需要我们手动指定
我们上面这个图的A点处理为边界,C点与边界点A点是相连(图像中边界线条的相连)的,且C点大于minVal,所以我们保留C点(判定C点为边界点),B点与边界点A不相连,且小于MaxVal,所以我们舍弃掉B点(判定B点不为边界点)
2 代码实现 Canny()
我们先设置两组maxVal与minVal
- 第一组 80,150
- 第二组 50,100
- minVal设置的值越小被认定为边界的点就越多,越大被认定为边界的点就越少
- maxVal越大被认定为边界的点就越少,越小被认定为边界的点就越多
- minVal与maxVal没有一个固定最好的值,最好的值是根据自己的任务推出来的
我们以之前的猫做例子
左边是80,150;右边是50,100