车道线检测—python_opencv 代码解读

  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缺少说明文档。

猜你喜欢

转载自www.cnblogs.com/codeAndlearn/p/11432366.html