原圖
完整代碼
- import numpy as np
- import cv2, os, math
- from skimage import io
- img1 = cv2.imread('Traffic_Lanes.jpg')
- img2 = img1.copy()
- gray = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
- edges = cv2.Canny(img1, 50, 200)
- edges_gray = cv2.Canny(gray, 50, 200)
- # cv2.HoughLines 找出來的直線任意角度
- lines = cv2.HoughLines(edges_gray, 1, math.pi / 180.0, 200)
- cv2.imshow('img2',img2)
- # cv2.imshow('Canny1 Image',edges)
- # cv2.imshow('Canny2 Imag',edges_gray)
- print(lines)
- # print(lines.__class__)
- print('lines只是空間座標資訊,我們得做轉換處理')
- print('lines.shape',lines.shape)
- if lines is not None:
- a,b,c = lines.shape
- print('a',a,'b',b,'c',c)
- for i in range(a):
- rho = lines[i][0][0]
- theta = lines[i][0][1]
- # print('rho',rho)
- # print('theta', theta)
- a = math.cos(theta)
- b = math.sin(theta)
- # print('a', a)
- # print('b', b)
- # x0, y0代表繪製直線的原始位置的距離
- # 依照sin與cos的角度關係,找出直線的起訖位置
- # 起點 x0 + 100 * (-b),y0 + 100 * (a)
- # 終點 x0 - 100 * (-b),y0 - 100 * (a)
- # 100 代表直線的長度,長度可以調整
- x0, y0 = a*rho, b*rho
- print('x0', x0,'y0', y0)
- pt1 = ( int(x0 + 1000 * (-b)), int(y0 + 1000 * (a)))
- pt2 = ( int(x0 - 1000 * (-b)), int(y0 - 1000 * (a)))
- print('pt1', pt1, 'pt2', pt2)
- print('依之前計算的座標pt1到pt2的繪製直線')
- cv2.line(img2,pt1,pt2,(255,0,0),1,cv2.LINE_AA)
- cv2.imshow('Lines Image', img2)
- cv2.imwrite('1000.png',img2)
- cv2.waitKey()
複製代碼
• lines=cv2.HoughLines(edges1,1,math.pi/180.0,120)
• 共有四個參數
• 1.輸入的影像,必須是灰階影像。
• 2.rho以像素為單位的距離精度,一般會設定為1。
• 3.theta,代表偵測時角度設定,math.pi/180.0 代表探索所有可能的角度。
• 4.偵測的閥值,這個數值愈小,判定出來的直線就會愈多 • is not None代表有偵測到直線。
• 以這個練習為例,shape為5X1X2。
• lines[0][0]代表rho距離。
• lines[0][1]代表theta角度。
• a的內容代表cos結果。
• b的內容代表sin結果。
• sin代表 三角座標的 高/ 斜
• cos代表三角座標的 底/斜
• 我們知道cv2.HoughLines( )找出來的直線是任意角度。
• x0與y0代表繪製直線的原始位置的距離。
• 我們依照sin與cos的角度關係,找出直線的起訖的位置:
• 起點:x0+1000*(-b),y0+1000*(a)
• 終點:x0-1000*(-b),y0-1000*(a)
• 1000代表直線的長度,長度可以調整。
• 原點於左上角。 • Q:可是sin不是垂直,而cos是水平?
• (tan是斜率)
• A:
• 配合前面HoughLines()方法推算,所以sin與cos是反過來。
• 這一張圖為何天空有直線?
• 圖像以300%比例查看,發現左上角有白色雲彩,與天空顏色不同,而左上角是原點,所以被判斷為直線。
• 可以偵測後將天空區域的座標刪除
|