接下來進(jìn)入代碼環(huán)節(jié)充包,這里詳細(xì)給大家解釋一下 HoughLinesP 參數(shù)的含義以及如何使用翔试。
lines = cv2.HoughLinesP(cropped_image,2,np.pi/180,100,np.array([]),minLineLength=40,maxLineGap=5)
第一參數(shù)是我們要檢查的圖片
Hough accumulator 數(shù)組
第二個和第三個參數(shù)用于定義我們 Hough 坐標(biāo)如何劃分 bin蜘澜,也就是小格的精度瓣距。我們通過曲線穿過 bin 格子來進(jìn)行投票箕戳,我們根據(jù)投票數(shù)量來決定 p 和 theta 的值某残。2 表示我們小格寬度以像素為單位 。
我們可以通過下圖劃分小格陵吸,只要曲線穿過就會對小格進(jìn)行投票玻墅,我們記錄投票數(shù)量,記錄最多的作為參數(shù)
如果定義尺寸過大也就失去精度壮虫,如果定義格子尺寸過小雖然精度上來了澳厢,這樣也會打來增長計算時間。
接下來參數(shù) 100 表示我們投票為 100 以上的線才是符合要求是我們要找的線旨指。也就是在 bin 小格子需要有 100 以上線相交于此才是我們要找的參數(shù)赏酥。
minLineLength 給 40 表示我們檢查線長度不能小于 40 pixel
maxLineGap=5 作為線間斷不能大于 5 pixel
定義顯示車道線方法
def disply_lines(image,lines):
pass
通過定義函數(shù)將找到的車道線顯示出來。
line_image = disply_lines(lane_image,lines)
查看探測車道線數(shù)據(jù)結(jié)構(gòu)
def disply_lines(image,lines):
line_image = np.zeros_like(image)
if lines is not None:
for line in lines:
print(line)
先定義一個尺寸大小和原圖一樣的矩陣用于繪制查找到車道線谆构,我們先判斷一下是否已經(jīng)找到車道線裸扶,lines 返回值應(yīng)該不為 None 是一個矩陣,我們可以簡單地打印一下看一下效果
[[704 418 927 641]]
[[704 426 791 516]]
[[320 703 445 494]]
[[585 301 663 381]]
[[630 341 670 383]]
探測車道線
看數(shù)據(jù)結(jié)構(gòu)[[x1,y1,x2,y2]] 的二維數(shù)組搬素,這就需要我們轉(zhuǎn)換一下為一維數(shù)據(jù)[x1,y1,x2,y2]
def disply_lines(image,lines):
line_image = np.zeros_like(image)
if lines is not None:
for line in lines:
x1,y1,x2,y2 = line.reshape(4)
cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)
return line_image
line_image = disply_lines(lane_image,lines)
cv2.imshow('result',line_image)
合成影響
combo_image = cv2.addWeighted(lane_image,0.8, line_image, 1, 1,1)
有關(guān)合成圖片我們是將兩張圖片通過給一定權(quán)重進(jìn)行疊加合成呵晨。
優(yōu)化
我們通過學(xué)習(xí)霍夫變換探測到的車道線還是不夠平滑魏保,我們需要優(yōu)化,基本思路就是對這些直線的斜率和截距取平均值然后將所有探測出點(diǎn)繪制到一條直線上摸屠。
averaged_lines = average_slope_intercept(lane_image,lines);
首先定義我們的函數(shù)谓罗,接收道路圖片和探測點(diǎn)做為參數(shù)。
def average_slope_intercept(image,lines):
left_fit = []
right_fit = []
for line in lines:
x1, y1, x2, y2 = line.reshape(4)
parameters = np.polyfit((x1,x2),(y1,y2),1)
print(parameters)
這里定義兩個數(shù)組 left_fit 和 right_fit 分別用于存放左右兩側(cè)車道線的點(diǎn)季二,我們打印一下 lines 的斜率和截距檩咱,通過 numpy 提供 polyfit 方法輸入兩個點(diǎn)我們就可以得到通過這些點(diǎn)的直線的斜率和截距。
[ 1. -286.]
[ 1.03448276 -302.27586207]
[ -1.672 1238.04 ]
[ 1.02564103 -299.
def average_slope_intercept(image,lines):
left_fit = []
right_fit = []
for line in lines:
x1, y1, x2, y2 = line.reshape(4)
parameters = np.polyfit((x1,x2),(y1,y2),1)
# print(parameters)
slope = parameters[0]
intercept = parameters[1]
if slope < 0:
left_fit.append((slope,intercept))
else:
right_fit.append((slope,intercept))
print(left_fit)
print(right_fit)
由于左側(cè)和右側(cè)線的斜率不同胯舷,我們根據(jù)斜率可以劃分點(diǎn)到左右兩側(cè)的直線矩陣上刻蚯。
left_fit_average = np.average(left_fit,axis=0)
right_fit_average = np.average(right_fit,axis=0)
然后通過取平局值來得到他們平均斜率和截距。
[ -1.61019355 1201.00387097]
[ 1.0243751 -298.80648538]
def make_coordinates(image, line_parameters):
slope, intercept = line_parameters
print(image.shape)
return
我們輸出一下圖片大小桑嘶,我們圖片是以其左上角作為原點(diǎn) 0 炊汹,0 來開始計算的,所以我們直線從圖片底部 700 多向上繪制我們無需繪制全部可以截距一部分即可逃顶。
![圖(https://upload-images.jianshu.io/upload_images/8207483-367e149bfb5a5165.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
(704, 1279, 3)
(704, 1279, 3)
left_line = make_coordinates(image, left_fit_average)
right_line = make_coordinates(image, right_fit_average)
def make_coordinates(image, line_parameters):
slope, intercept = line_parameters
y1 = image.shape[0]
y2 = int(y1*(3/5))
x1 = int((y1 - intercept)/slope)
x2 = int((y2 - intercept)/slope)
# print(image.shape)
return np.array([x1,y1,x2,y2])
所以直線開始和終止我們給定 y1,y2 然后通過方程的斜率和截距根據(jù)y 算出 x讨便。
averaged_lines = average_slope_intercept(lane_image,lines);
line_image = disply_lines(lane_image,averaged_lines)
combo_image = cv2.addWeighted(lane_image,0.8, line_image, 1, 1,1)
cv2.imshow('result',combo_image)