文章目录
边缘检测: 传统的直线检测方法一般采用边缘检测算法提取二值边缘图像,然后利用Hough变换将表示每条直线属性的参数投影到Hough空间中。该线检测方法是一种全局拟合算法。缺点是依赖于边缘检测算法的准确性,在边缘密集的地方容易出现异常检测
LSD检测 LSD算法是一种基于梯度信息的直线检测方法,具有检测速度快、参数自适应、精度可达到亚像素级的特点。其主要思想是将局部区域内具有相同梯度方向的像素进行合并,以达到直线检测的目的
opencv中两个LSD直线检测算法的区别与应用
同样是Line Segment Detector(lsd)算法,opencv中提供了两种实现,并且位于不同的模块。在OpenCV 4.0版本及更高版本中,LSDDetector类的构造函数中没有LSDOptions参数。相反,它被重构为BinaryDescriptor::Params参数。因此,如果你的OpenCV版本高于4.0,那么在构造LSDDetector对象时,应该使用BinaryDescriptor::Params参数,而不是LSDOptions参数。下面分别介绍它们的使用方法:
- LineSegmentDetector
由于源码许可证问题 OpenCV 3.4.6-3.4.15、4.1.0-4.5.3中无法使用这个方法
使用该类检测直线并显示的代码如下:
import cv2
if __name__ == '__main__':
img = cv2.imread("test.jpg")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_img = cv2.GaussianBlur(gray_img, (3,3), 2.0)
#LineSegmentDetector
lsd = cv2.createLineSegmentDetector(refine=cv2.LSD_REFINE_NONE, scale=0.8, ang_th=35)
lines_detected, width, prec, nfa = lsd.detect(gray_img)
#lsd.drawSegments(img,lines_detected)
#绘制检测结果
for dline in lines_detected:
x0 = int(round(dline[0][0]))
y0 = int(round(dline[0][1]))
x1 = int(round(dline[0][2]))
y1 = int(round(dline[0][3]))
cv2.line(mask, (x0, y0), (x1,y1), 255, 1, cv2.LINE_AA)
cv2.imshow("Detected lines", img)
cv2.waitKey(0)
cv.destroyAllWindows()
c++示例代码如下(lsd_lines.cpp):
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using