边缘检测的三种算法介绍

边缘检测的三种算法介绍

边缘检测算法是一个传统的CV问题,传统的CV方法有canny算法。引入机器学习,深度学习的方法后,又有了structure forests,以及HED算法。


canny 算子


canny算法是一种multi-stage 的算法,其处理图片的过程分为如下五个步骤:

1. Noise Reduction

图片中的高频信息指颜色快速变化,低频信息指颜色平缓的变化。边缘检测过程中需要检测的图片边缘属于高频信息。而图片中噪声部分也属于高频信息,因此我们需要对图像进行去噪处理。常用的是使用5*5的高斯滤波核来平滑图像,滤波核的数量呈高斯分布。

2. Finding Intensity Gradient of the Image

计算像素梯度的幅值以及方向,常用的算子有Rober,sobel,计算水平及垂直方向的差分。找出梯度较大的区域,这部分区域属于图像增强的区域,此时得到的边缘信息比较粗大。

3.Non-Maximun Suppression

非极大值抑制属于一种边缘细化的方法,梯度大的位置有可能为边缘,在这些位置沿着梯度方向,找到像素点的局部最大值,并将非最大值抑制。

4.Double Threhold

双阀值方法,设置一个maxval,以及minval,梯度大于maxval则为强边缘,梯度值介于maxval与minval则为弱边缘点,小于minval为抑制点。

5.Edge tracking by hysteresis

滞后边缘追踪,主要处理梯度值位于maxval,minval中的一些像素点。由于边缘是连续的,因此可以认为弱边缘如果为真实边缘则和强边缘是联通的,可由此判断其是否为真实边缘。


python实现代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('doge.jpg',0)
edges = cv2.Canny(img,100,200) #参数:图片,minval,maxval,kernel = 3

plt.subplot(121) #121表示行数,列数,图片的序号即共一行两列,第一张图
plt.imshow(img,cmap='gray') #cmap :colormap 设置颜色
plt.title('original image'),plt.xticks([]),plt.yticks([]) #坐标轴起点,终点的值
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('edge image'),plt.xticks([]),plt.yticks([])

plt.show()

Fast Edge Detection Using Structured Forests


该方法是一个局部检测的方法,利用supervised learning判断每个像素是否是edge,因此缺乏一致性。文章的做法是将pixel扩展为patch,从patch找到一个隐状态,作者通过clustering设计了一个映射,即patch->pattern(如线条等),随后通过对pattern进行学习得到结果。

实现代码如下:

import cv2
import matplotlib.pyplot as plt
import numpy as np

filename = 'img/doge.jpg'
image = cv2.imread(filename,1)
cur_path = "E:/workSpace/AI/edgeDetection/"
model_path = cur_path + "resources/model.yml.gz"
if image.size == 0:
    print('cannot read file')
    exit(0)
img = np.float32(image)
img = img*(1.0/255.0)
retval = cv2.ximgproc.createStructuredEdgeDetection(model_path)
a = retval.detectEdges(img)
plt.subplot(121)
plt.imshow(image,cmap='gray')
plt.subplot(122)
plt.imshow(a,cmap= 'gray')
plt.show()

Holistically-Nested Edge Detection(HED)


该文章为翻译为中文为“整体嵌套边缘检测”,即相对于Fast Edge 来说更能体现整体信息对边缘信息的反映。

  • Holistically :表示边缘预测结果是基于端对端的
  • Nested:生成的Edge过程中,将许多尺度不同的图片进行fusion得到结果。

作者在VGG-Net的基础上进行修改,在每个卷积层的后边加入一层 side output layer,在每个side output layer 上进行deep supervision learning,有助于结果向边缘检测方向进行。每个side output layer 将得到一个edge map,如下图:

可以看出浅层越能检测出很细节的边缘信息,越深层越能体现一些语义分割上的信息,与ground truth 比较接近。最后通过一个fusion layer将各个edge map 进行融合,在这个fusion layer中对所有的edge map 都进行loss,以及bp等操作(multi-loss)。

代码链接:tensorpack-HED

结果如下:


算法比较


这是我最想记录的一部分内容,也是我记这一篇笔记的初衷。


canny算子,由算法步骤可以看出canny算子更注重像素梯度变化所体现的出来的边缘信息,不考虑实际物体,同时损失了图片的空间信息,对于一些边缘颜色与背景颜色相近的图片,很可能会丢失掉边缘信息。

canny处理边缘颜色与背景颜色相似的图片效果:

Fast edge算法使用随机森林来生成边缘信息,针对图片窗口(patch)区域进行边缘的提取,利用ground true,能够体现实际的物体,可以反映出图片的空间信息。

效果如下:

HED使用VGG改造的网络,针对整张图片提取特征信息,通过多尺度融合,multi-loss等方式。同样可以反映边缘的特征信息。效果如下:

事实上,对于边缘信息不明显的图片,三种算法的检测效果都不太好。留待以后思考。

编辑于 2018-04-15