Skip to content

边缘检测方法:LSD

介绍一种边缘检测方法:LSD,来自以下文章,它可以在 OpenCV 中使用,具体用法在另一篇笔记中。

  • LSD: a Line Segment Detector

首先是总体逻辑先过一遍,先不纠结各个步骤具体是如何做的。

总体流程

流程一:先对图像求梯度,得到方向,然后把大致接近的方向组合在一起。如下图所示(先不纠结如何实现),便于讲述,每一组叫做 Line Support Region。

流程二:然后对每个组合求一个最小外接矩形,看看里面的点有多少是和矩形的方向一致的,比如下图,就只有 8 个点是和矩形的方向一致的,这些点叫做 aligned points。

流程三:判断上面说的符合矩形方向的点数量够不够,即这个矩形是否可以作为最终直线。

流程四:如果不够则把矩形删掉一个点,继续上述操作。

流程一:求解 Line Support Region

每个点梯度计算,有大小和方向。梯度小的点往往出现在平滑区域,或者仅仅是噪声。即不是我们想要的直线,为了避免干扰,梯度值小于 \(\rho\) 的像素会被标记,不参与后面的计算。

然后开始依次遍历那些未标记的点,遍历顺序是梯度从大到小,其中作者用的桶排序,也符合常规做法。

假设现在从像素点 \(p\) 开始找新的 Line Support Region,先计算 \(p\) 的八联通这个八个点的梯度方向是否和 当前 Line Support Region 的方向 在容忍度 \(\tau\) 内,其中论文中 \(\tau = 22.5 \degree = \pi / 8\)

当前 Line Support Region 的方向计算如下,即把里面的像素点各自 \(\sin\)\(\cos\) 求和,然后求 \(\arctan\)

如果符合条件,就加入那个点,并且做一个标记,然后重复上面步骤。

流程二:求解最小矩形及其 aligned points 数量

求最小外接矩形这是经典问题,这里不赘述。这里快速提一下,如下图是矩阵中心:

这个矩形的方向则是用轮廓的矩,求下面的矩阵的最小特征值对应的特征向量,就是矩形的方向:

然后 aligned points 数量也很朴素:遍历比较呗,比较当前遍历的点的梯度方向和上面的矩形方向是否在容忍度 \(\tau\) 内。

虽然我们在流程一中加入点的时候,考虑的容忍度也是 \(\tau\),但是这里比较的是最终矩形的方向,而不是流程一中逐渐更新的 Line Support Region 的方向(流程一中用 \(\arctan\) 计算的公式)。

流程三:判断矩形是否可以作为最终直线

作者用了一个叫做 NFA 的指标,这个指标在另一个方法 EDLines 中也会用到。

NFA, the Number of False Alarms,假阳性率,计算公式如下:

其中 \(N\)\(M\)图片的大小,\(n\) 是当前矩形的像素数量,\(p\) 叫做精确度,默认值设为 \(\tau / \pi\)\(k\) 是符合条件的像素点数量,而这个条件阈值就是 \(p\pi\)

这个方法也叫做 Helmholtz principle,从上面公式也能看出是否能作为最终直线甚至和图像大小有关系。确实,同样长度的直线,在小图中可作为直线,但大图中可能还是偏短。

最后如果 \(NFA(r) \leq \epsilon\),则认为这个矩形可以作为最终直线。论文中参数 \(\epsilon = 1\)。其参考了 2008 年的一篇文章:From Gestalt Theory to Image Analysis。

流程三番外:进一步判断矩形是否可以作为最终直线

作者提出用 NFA 进行评估有一个问题,如下图所示,如果前半部分是一个合理误差内的方向,后半部分是另一个相反的合理误差方向,最后会通过 NFA 检测:

然后作者就提出进一步判断,用符合常规的数量占比来判断,如下图所示,论文使用的阈值是 \(D = 0.7\),即需要 \(d > 0.7\)但说实话我感觉好像还是没有解决问题啊,暂时跳过去吧,这些都是细节中的细节,实在不行看 OpenCV 源码...

流程四:不符条件则分割矩形

如果矩阵不符合要求,则按照如下步骤进行,一旦有一个步骤发现 NFA 值满足要求,那么就停止:缩小精确度 \(p\)、减小矩形宽度、减小矩形一边的长度、减小另一边的程度、进一步缩小精确度 \(p\)

如果最后矩形过小也会被丢弃。

Comments