import cv2 as cv
import numpy as np
img = cv.imread('1.png')
def line_detection(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# apertureSize做Canny时梯度窗口的大小
edges = cv.Canny(gray, 50, 150, apertureSize=3)
# 返回的是r和theta
lines = cv.HoughLines(edges, 1, np.pi/180, 200)
for line in lines:
print(type(line))
rho, theta = line[0]
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
# 乘以1000,是根据源码乘的,通过x1、x2、y1、y2画一条直线
x1 = int(x0+1000*(-b))
y1 = int(y0+1000*a)
x2 = int(x0-1000*(-b))
y2 = int(y0-1000*a)
cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) # 2是所画直线长度的宽
print(x1,y1,x2,y2)
cv.imshow('image_lines', image)
line_detection(img);
cv.waitKey(0)
cv.destroyAllWindows()
结论 : 效果不好,漏检很多,不适合精密场合
http://www.ipol.im/pub/art/2012/gjmr-lsd/
LSD的基本实现流程是计算出图像的梯度和场方向,然后对梯度进行排序,然后从大到小进行区域增长,之后对增长得到的区域求最小外接矩形,如果矩形不满足要求,则修改参数重新生长或者修改矩形的大小和位置,若仍旧不满足,则放弃该区域,该方法由于版权问题在opencv中被剔除,有兴趣可以自行找到该作者的主页去
注意这个算法再contrib包中,先要安装,pip install opencv-contrib-python
## 使用ximgproc的createFastLineDetector
import cv2
import numpy as np
### 读取输入图片
img0 = cv2.imread("1.png")
### 将彩色图片转换为灰度图片
img = cv2.cvtColor(img0,cv2.COLOR_BGR2GRAY)
### 创建一个LSD对象
fld = cv2.ximgproc.createFastLineDetector()
### 执行检测结果
dlines = fld.detect(img)
### 绘制检测结果
color = 100
for dline in dlines:
x0 = int(round(dline[0][0]))
y0 = int(round(dline[0][1]))
x1 = int(round(dline[0][2]))
y1 = int(round(dline[0][3]))
color=color+30
if color>225:
color= 10
cv2.line(img0, (x0, y0), (x1,y1), (color,color,color), 1, cv2.LINE_AA)
print(x0,y0,x1,y1)
# 显示并保存结果
cv2.imwrite('res.jpg', img0)
cv2.imshow("LSD", img0)
cv2.waitKey(0)
cv2.destroyAllWindows()
结论,较好,但是要自行合并直线
1 运行一个灰度图像,运行边缘检测、边缘绘制ED算法,产生像素相邻的链,称之为边缘。边缘线段直观地反应对象的边界。
2 利用直线度准则,即最小二乘直线拟合法,从生成的像素链中提取线段。
3 线的验证步骤定于亥姆霍兹原理Helmholtz principle ,用来消除虚假线段的检测。
edlines算法无论是速度和效果都是可以的,可以自行研究该算法,该算法研究完毕应该会得到很多东西。
如果有钱可以考虑halcon商业软件
read_image (Bk45, 'bk45')
*带通滤波
bandpass_image (Bk45, Lines, 'lines')
threshold (Lines, Region, 128, 255)
*计算划痕
skeleton (Region, Skeleton)
dev_set_colored (12)
*生成轮廓
gen_contours_skeleton_xld (Skeleton, Contours, 5, 'filter')
dev_display (Bk45)
dev_display (Contours)