1 #!D:/Code/python 2 # -*- coding: utf-8 -*- 3 # @Time : 2019/8/29 16:58 4 # @Author : Johnye 5 # @Site : 6 # @File : detect_RoadL.py 7 # @Software: PyCharm 8 9 import cv2 as cv 10 import numpy as np 11 import math 12 13 # LaneLineDetection类 14 class LaneLineDetection: 15 def __init__(self): 16 print("instace it") 17 # leftline 和rightline车道检测的两条线 18 # 每一条线分别有两个点决定 19 self.left_line = {'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0} 20 self.right_line = {'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0} 21 22 def process(self, frame, method=0): 23 # 将图像转化为灰度图像 24 gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) 25 # canny边缘检测 26 binary = cv.Canny(gray, 150, 300) 27 h, w = gray.shape 28 # 这一步操作没看懂 29 binary[0:np.int(h/2+40),0:w] = 0 30 # 轮廓查找 31 contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) 32 # 创建输出用的空白图像 33 out_image = np.zeros((h, w), frame.dtype) 34 # 遍历每一个轮廓,进行轮廓分析 35 for cnt in range(len(contours)): 36 # 通过多种特征筛选 37 p = cv.arcLength(contours[cnt], True) 38 area = cv.contourArea(contours[cnt]) 39 x, y, rw, rh = cv.boundingRect(contours[cnt]) 40 if p < 5 or area < 10: 41 continue 42 if y > (h - 50): 43 continue 44 (x, y), (a, b), angle = cv.minAreaRect(contours[cnt]); 45 angle = abs(angle) 46 if angle < 20 or angle > 160 or angle == 90.0: 47 continue 48 if len(contours[cnt]) > 5: 49 (x, y), (a, b), degree = cv.fitEllipse(contours[cnt]) 50 if degree< 5 or degree>160 or 80<degree<100: 51 continue 52 cv.drawContours(out_image, contours, cnt, (255), 2, 8) 53 result = self.fitLines(out_image) 54 cv.imshow("contours", out_image) 55 dst = cv.addWeighted(frame, 0.8, result, 0.5, 0) 56 cv.imshow("lane-lines", dst) 57 # 直线拟合 58 def fitLines(self, image): 59 h, w = image.shape 60 h1 = np.int(h / 2 + 40) 61 out = np.zeros((h, w, 3), dtype=np.uint8) 62 cx = w // 2 63 cy = h // 2 64 left_pts = [] 65 right_pts = [] 66 for col in range(100, cx, 1): 67 for row in range(cy, h, 1): 68 pv = image[row, col] 69 if pv == 255: 70 left_pts.append((col, row)) 71 for col in range(cx, w-20, 1): 72 for row in range(cy, h, 1): 73 pv = image[row, col] 74 if pv == 255: 75 right_pts.append((col, row)) 76 77 if len(left_pts) >= 2: 78 [vx, vy, x, y] = cv.fitLine(np.array(left_pts), cv.DIST_L1, 0, 0.01, 0.01) 79 y1 = int((-x * vy / vx) + y) 80 y2 = int(((w - x) * vy / vx) + y) 81 dy = y2 - y1 82 dx = w - 1 83 k = dy/dx 84 c = y1 85 86 w1 = (h1 -c)/k 87 w2 = (h - c) / k 88 cv.line(out, (np.int(w1), np.int(h1)), (np.int(w2), np.int(h)), (0, 0, 255), 8, 8, 0) 89 self.left_line['x1'] = np.int(w1) 90 self.left_line['y1'] = np.int(h1) 91 self.left_line['x2'] = np.int(w2) 92 self.left_line['y2'] = np.int(h) 93 else: 94 x1 = self.left_line['x1'] 95 y1 = self.left_line['y1'] 96 x2 = self.left_line['x2'] 97 y2 = self.left_line['y2'] 98 cv.line(out, (x1, y1), (x2, y2), (0, 0, 255), 8, 8, 0) 99 100 if len(right_pts) >= 2: 101 x1, y1 = right_pts[0] 102 x2, y2 = right_pts[len(right_pts) - 1] 103 dy = y2 - y1 104 dx = x2 - x1 105 k = dy / dx 106 c = y1 - k * x1 107 w1 = (h1 - c) / k 108 w2 = (h - c)/k 109 cv.line(out, (np.int(w1), np.int(h1)), (np.int(w2), np.int(h)), (0, 0, 255), 8, 8, 0) 110 self.right_line['x1'] = np.int(w1) 111 self.right_line['y1'] = np.int(h1) 112 self.right_line['x2'] = np.int(w2) 113 self.right_line['y2'] = np.int(h) 114 else: 115 x1 = self.right_line['x1'] 116 y1 = self.right_line['y1'] 117 x2 = self.right_line['x2'] 118 y2 = self.right_line['y2'] 119 cv.line(out, (x1, y1), (x2, y2), (0, 0, 255), 8, 8, 0) 120 return out 121 122 123 def video_run(): 124 capture = cv.VideoCapture("images/road_line.mp4") 125 height = capture.get(cv.CAP_PROP_FRAME_HEIGHT) 126 width = capture.get(cv.CAP_PROP_FRAME_WIDTH) 127 count = capture.get(cv.CAP_PROP_FRAME_COUNT) 128 fps = capture.get(cv.CAP_PROP_FPS) 129 print(height, width, count, fps) 130 detector = LaneLineDetection() 131 while (True): 132 ret, frame = capture.read() 133 if ret is True: 134 cv.imshow("video-input", frame) 135 detector.process(frame, 0) 136 c = cv.waitKey(1) 137 if c == 27: 138 break 139 else: 140 break 141 142 143 if __name__ == "__main__": 144 video_run() 145 cv.waitKey(0) 146 cv.destroyAllWindows()
代码来源:贾志刚opencv 研习社
视频 录像: 链接:https://pan.baidu.com/s/1d_PmhY-GwvG1MZn44q2jeg 提取码:rwu5
复制这段内容后打开百度网盘手机App,操作更方便哦
反思,对于python语言中的numpy的使用不够熟练,opencv python缺少说明文档。