代码
import cv2
import numpy
as np
def find_line_fit(img
, name
= "default" ,nwindows
=9, margin
=100, minpix
=50 , minLane
= 50):
'''
Args:
img: 传入的灰度图像
name: 图像的名字,当处理视屏流的时候,有些图像没法拟合可以用异常来报错提示那一帧出了问题
nwindows: 将图像纵向切割的窗口个数
margin: 滑动窗口的宽
minpix: 如果滑动窗口中像素个数大于设定的这个阈值,则将下一次滑动窗口的中心设为这次白色像素的水平方向的均值处
minLane: 如果当前直方图的最大值小于这个阈值,则这次的滑动窗口中心设置成上一次的值
Returns:
left_fit:左车道线的二阶函数式系数
right_fit:右车道线的二阶函数式系数
'''
img2show
= img
.copy
()
midpoint
= np
.int(img
.shape
[1]/2)
window_height
= np
.int(img
.shape
[0]/nwindows
)
nonzero
= img
.nonzero
()
nonzeroy
= np
.array
(nonzero
[0])
nonzerox
= np
.array
(nonzero
[1])
left_lane_inds
= []
right_lane_inds
= []
h
= [0,img
.shape
[0]]
w
= [0,img
.shape
[1]]
leftx_current
= w
[0]
rightx_current
= w
[1]
for window
in range(nwindows
):
start
= h
[1] - int(h
[0] + (h
[1] - h
[0]) * window
/ nwindows
)
end
= h
[1] - int(h
[0] + (h
[1] - h
[0]) * (window
+ 1) / nwindows
)
cv2
.line
(img2show
, (0, start
), (w
[1], start
), (255, 255, 255))
cv2
.line
(img2show
, (0, end
), (w
[1], end
), (255, 255, 255))
histogram
= np
.sum(img
[end
:start
,w
[0]:w
[1]], axis
=0)
leftx_current
= np
.argmax
(histogram
[:midpoint
]) if np
.argmax
(histogram
[:midpoint
]) > minLane
else leftx_current
rightx_current
= np
.argmax
(histogram
[midpoint
:]) + midpoint
if np
.argmax
(histogram
[midpoint
:]) > minLane
else rightx_current
win_y_low
= img
.shape
[0] - (window
+1)*window_height
win_y_high
= img
.shape
[0] - window
*window_height
win_xleft_low
= leftx_current
- margin
win_xleft_high
= leftx_current
+ margin
win_xright_low
= rightx_current
- margin
win_xright_high
= rightx_current
+ margin
cv2
.rectangle
(img2show
,(win_xleft_low
,win_y_low
),(win_xleft_high
,win_y_high
),
(255,255,255), 2)
cv2
.rectangle
(img2show
,(win_xright_low
,win_y_low
),(win_xright_high
,win_y_high
),
(255,255,255), 2)
cv2
.imshow
("rec",img2show
)
cv2
.waitKey
(2000)
good_left_inds
= ((nonzeroy
>= win_y_low
) & (nonzeroy
< win_y_high
) &
(nonzerox
>= win_xleft_low
) & (nonzerox
< win_xleft_high
)).nonzero
()[0]
good_right_inds
= ((nonzeroy
>= win_y_low
) & (nonzeroy
< win_y_high
) &
(nonzerox
>= win_xright_low
) & (nonzerox
< win_xright_high
)).nonzero
()[0]
left_lane_inds
.append
(good_left_inds
)
right_lane_inds
.append
(good_right_inds
)
if len(good_left_inds
) > minpix
:
leftx_current
= np
.int(np
.mean
(nonzerox
[good_left_inds
]))
if len(good_right_inds
) > minpix
:
rightx_current
= np
.int(np
.mean
(nonzerox
[good_right_inds
]))
left_lane_inds
= np
.concatenate
(left_lane_inds
)
right_lane_inds
= np
.concatenate
(right_lane_inds
)
leftx
= nonzerox
[left_lane_inds
]
lefty
= nonzeroy
[left_lane_inds
]
rightx
= nonzerox
[right_lane_inds
]
righty
= nonzeroy
[right_lane_inds
]
cv2
.imwrite
("result.png",img2show
)
try:
left_fit
= np
.polyfit
(lefty
, leftx
, 2)
right_fit
= np
.polyfit
(righty
, rightx
, 2)
except:
print("error:" + name
)
return [0,0,0],[0,0,0]
return left_fit
, right_fit
if __name__
== '__main__':
imgName
= "line.png"
img
= cv2
.imread
(imgName
)
gray
= cv2
.cvtColor
(img
,cv2
.COLOR_BGR2GRAY
)
find_line_fit
(gray
,name
= imgName
)
使用的图片
运行方式
将图片和代码保存本地,代码命名fitLine.py,图片命名line.png。然后将图片和代码处于同一文件夹下,执行以下命令运行代码:
python fitLine.py
运行结果