基本原理:检测亮度的急剧变化(大梯度 比如从白色到黑色)在给定阈值下定义为边
预处理:转换灰度图
def do_canny(frame):
gray = cv.cvtColor(frame, cv.COLOR_RGB2GRAY)
blur = cv.GaussianBlur(gray, (5,5),0)
canny = cv.Canny(blur,50,150)
return canny
手动指定一个三角形来分割出路面区域,去除其他干扰边缘
def do_segment(frame):
height = frame.shape[0]
polygons = np.array([
[(0,height), (800,height),(380,290)]
])//对应三个点
mask = np.zeros_like(frame)//生成一张图片,只不过所有值都是0
cv.fillPoly(mask, polygons, 255) //将三个点围城区域填充为255,其余还是0 ,实际就是掩码
segment = cv.bitwise_and(frame,mask)//比特位的与操作 255实际就是8比特位为1然后与原像素进行比特位的与操作,就会保留原来像素的值
return segment
hough = cv.HoughLinesP(segment, 2, np.pi / 180,100, np.array([]), minLineLength = 100, maxLineGap = 50)
霍夫变换如何帮助我们找到线?
综合所有线,求得两条车道线的平均斜率和截距
def calculate_line(frame, lines):
left = []
right = []
for line in lines:
x1,y1,x2,y2 = line.reshape(4) # reshape line from 2d to 1d
parameters = np.polyfit((x1,x2),(y1,y2),1) # 拟合一条直线返回系数
slope = parameters[0] #斜率
y_intercept = parameters[1]
if slope < 0:
left.append((slope,y_intercept))
else:
right.append((slope,y_intercept))
left_avg = np.average(left,axis = 0)
right_avg = np.average(right, axis = 0)
left_line = calculate_coordinates(frame,left_avg)
right_line = calculate_coordinates(frame,right_avg)
return np.array([left_line, right_line])
cap = cv.VideoCapture("input.mp4")
while (cap.isOpened()):
# ret = a boolean return value from getting the frame, frame = the current frame being projected in the video
ret, frame = cap.read()
canny = do_canny(frame) #canny边缘检测
cv.imshow("canny", canny)
# plt.imshow(frame)
# plt.show()
segment = do_segment(canny) #手工分割
hough = cv.HoughLinesP(segment, 2, np.pi / 180, 100, np.array([]), minLineLength = 100, maxLineGap = 50) #霍夫变换,确定车道线
# Averages multiple detected lines from hough into one line for left border of lane and one line for right border of lane
lines = calculate_lines(frame, hough)
# Visualizes the lines
lines_visualize = visualize_lines(frame, lines) #显示车道线
cv.imshow("hough", lines_visualize)
# Overlays lines on frame by taking their weighted sums and adding an arbitrary scalar value of 1 as the gamma argument
output = cv.addWeighted(frame, 0.9, lines_visualize, 1, 1) #车道和原始图片叠加
# Opens a new window and displays the output frame
cv.imshow("output", output)
# Frames are read by intervals of 10 milliseconds. The programs breaks out of the while loop when the user presses the 'q' key
if cv.waitKey(10) & 0xFF == ord('q'):
break
# The following frees up resources and closes all windows
cap.release()
cv.destroyAllWindows()