【图像处理】初等的直线检测算法
1、线用Canny算子检测图像的边界。
img0=cv2.imread('0.png')
img=cv2.Canny(img0,0,255)
2、上图中,除了边界像素等于255,其余都等于0。
因此,只统计非零像素。
r=int((u**2+v**2)**0.5)
acc=np.zeros((r,180))
for i in range(u):
for j in range(v):
if img[i,j]!=0:
for m in range(1,180):
m0=m*np.pi/180
R=int(j*np.cos(m0)+i*np.sin(m0))
if R<r and R>0:
acc[R,m]=acc[R,m]+1
为了便于查看,转置一下:
cv2.imwrite('2.png',acc.T)
3、画出像素最多的直线:
R,m1=np.where(acc==np.max(acc))
A=[]
for i in range(u):
for j in range(v):
if img[i,j]!=0:
for m in range(1,180):
m0=m*np.pi/180
h=int(j*np.cos(m0)+i*np.sin(m0))
if h==R and m==m1:
A.append((j,i))
cv2.line(img0,A[0],A[-1],(0,0,255),2)
4、用for循环,可以画出那些主要的线段:
B=np.reshape(acc,(1,-1))[0]
B=list(set(B))[::-1]
for i in range(5):
R,m1=np.where(acc==B[i])
A=[]
for i in range(u):
for j in range(v):
if img[i,j]!=0:
for m in range(1,180):
m0=m*np.pi/180
h=int(j*np.cos(m0)+i*np.sin(m0))
if h==R and m==m1:
A.append((j,i))
cv2.line(img0,A[0],A[-1],(0,0,255),2)
有重复吗?
5、opencv内置的检测直线的算子速度很快:
img0=cv2.imread('0.png')
lines = cv2.HoughLinesP(img, 1, np.pi/180, 80,30,10)
for x1, y1, x2, y2 in lines[0]:
cv2.line(img0, (x1, y1), (x2, y2), (0,255,0), 2)
cv2.imwrite('2.png',img0)
6、想多画几条线段?
img0=cv2.imread('0.png')
lines = cv2.HoughLinesP(img, 1, np.pi/180, 80,30,10)
for i in lines[:20]: #或者100
for x1, y1, x2, y2 in i:
cv2.line(img0, (x1, y1), (x2, y2), (0,255,0), 2)
cv2.imwrite('2.png',img0)
7、img0=cv2.imread('0.png')
img=cv2.Canny(img0,0,50)
lines = cv2.HoughLinesP(img, 1, np.pi/180, 80,30,10)
for i in lines:
for x1, y1, x2, y2 in i:
cv2.line(img0, (x1, y1), (x2, y2), (0,255,0), 2)
cv2.imwrite('2.png',img0)
这里,采用了其它的边界检测阈值。有些东西看起来是直的,但是检测结果显示那不直。