• 车道线检测—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 # 通过对象封装,将其中的重要函数隔离开
     15 class LaneLineDetection:
     16     def __init__(self):
     17         print("instace it")
     18         # leftline 和rightline车道检测的两条线
     19         # 每一条线分别有两个点决定
     20         self.left_line = {'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0}
     21         self.right_line = {'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0}
     22 
     23     def process(self, frame, method=0):
     24         # 将图像转化为灰度图像
     25         gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
     26         # canny边缘检测
     27         binary = cv.Canny(gray, 150, 300)
     28         h, w = gray.shape
     29         # 这一步操作没看懂
     30         binary[0:np.int(h/2+40),0:w] = 0
     31         # 轮廓查找
     32         contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
     33         # 创建输出用的空白图像
     34         out_image = np.zeros((h, w), frame.dtype)
     35         # 遍历每一个轮廓,进行轮廓分析
     36         for cnt in range(len(contours)):
     37             # 通过多种特征筛选
     38             p = cv.arcLength(contours[cnt], True)
     39             # 计算轮廓面积
     40             area = cv.contourArea(contours[cnt])
     41             # 获取轮廓的中心坐标以及长、宽
     42             x, y, rw, rh = cv.boundingRect(contours[cnt])
     43             if p < 5 or area < 10:
     44                 continue
     45             if y > (h - 50):
     46                 continue
     47             # 计算最小外接矩形角度
     48             (x, y), (a, b), angle = cv.minAreaRect(contours[cnt]);
     49             angle = abs(angle)
     50             # 筛选标准 角度不能小于20或者大于90度或者等于90度,剔除
     51             if angle < 20 or angle > 160 or angle == 90.0:
     52                 continue
     53             # contour的长度大于5
     54             if len(contours[cnt]) > 5:
     55             # 椭圆拟合
     56                 (x, y), (a, b), degree = cv.fitEllipse(contours[cnt])
     57             # 椭圆的角度小于5 或者 角度大于160 或者角度在80和160之间,剔除
     58                 if degree< 5 or degree>160 or 80<degree<100:
     59                     continue
     60             # 不被以上的条件剔除的,在创建的空白图像上绘制该轮廓
     61             cv.drawContours(out_image, contours, cnt, (255), 2, 8)
     62         result = self.fitLines(out_image)
     63         cv.imshow("contours", out_image)
     64         dst = cv.addWeighted(frame, 0.8, result, 0.5, 0)
     65         cv.imshow("lane-lines", dst)
     66     #  直线拟合
     67     def fitLines(self, image):
     68         h, w = image.shape
     69         h1 = np.int(h / 2 + 40)
     70         out = np.zeros((h, w, 3), dtype=np.uint8)
     71         cx = w // 2
     72         cy = h // 2
     73         left_pts = []
     74         right_pts = []
     75         for col in range(100, cx, 1):
     76             for row in range(cy, h, 1):
     77                 pv = image[row, col]
     78                 if pv == 255:
     79                     left_pts.append((col, row))
     80         for col in range(cx, w-20, 1):
     81             for row in range(cy, h, 1):
     82                 pv = image[row, col]
     83                 if pv == 255:
     84                     right_pts.append((col, row))
     85         # 检测出的左车道线数量大于2
     86         if len(left_pts) >= 2:
     87             [vx, vy, x, y] = cv.fitLine(np.array(left_pts), cv.DIST_L1, 0, 0.01, 0.01)
     88             y1 = int((-x * vy / vx) + y)
     89             y2 = int(((w - x) * vy / vx) + y)
     90             dy = y2 - y1
     91             dx = w - 1
     92             k = dy/dx
     93             c = y1
     94 
     95             w1 = (h1 -c)/k
     96             w2 = (h - c) / k
     97             cv.line(out, (np.int(w1), np.int(h1)), (np.int(w2), np.int(h)), (0, 0, 255), 8, 8, 0)
     98             self.left_line['x1'] = np.int(w1)
     99             self.left_line['y1'] = np.int(h1)
    100             self.left_line['x2'] = np.int(w2)
    101             self.left_line['y2'] = np.int(h)
    102         # 检测出的左车道线数量为1
    103         else:
    104             x1 = self.left_line['x1']
    105             y1 = self.left_line['y1']
    106             x2 = self.left_line['x2']
    107             y2 = self.left_line['y2']
    108             cv.line(out, (x1, y1), (x2, y2), (0, 0, 255), 8, 8, 0)
    109         # 检测出的右车道线数量大于2
    110         if len(right_pts) >= 2:
    111             x1, y1 = right_pts[0]
    112             x2, y2 = right_pts[len(right_pts) - 1]
    113             dy = y2 - y1
    114             dx = x2 - x1
    115             k = dy / dx
    116             c = y1 - k * x1
    117             w1 = (h1 - c) / k
    118             w2 = (h - c)/k
    119             cv.line(out, (np.int(w1), np.int(h1)), (np.int(w2), np.int(h)), (0, 0, 255), 8, 8, 0)
    120             self.right_line['x1'] = np.int(w1)
    121             self.right_line['y1'] = np.int(h1)
    122             self.right_line['x2'] = np.int(w2)
    123             self.right_line['y2'] = np.int(h)
    124         # 检测出的右车道线数量为1
    125         else:
    126             x1 = self.right_line['x1']
    127             y1 = self.right_line['y1']
    128             x2 = self.right_line['x2']
    129             y2 = self.right_line['y2']
    130             cv.line(out, (x1, y1), (x2, y2), (0, 0, 255), 8, 8, 0)
    131         return out
    132 
    133 
    134 def video_run():
    135     capture = cv.VideoCapture("images/road_line.mp4")
    136     height = capture.get(cv.CAP_PROP_FRAME_HEIGHT)
    137     width = capture.get(cv.CAP_PROP_FRAME_WIDTH)
    138     count = capture.get(cv.CAP_PROP_FRAME_COUNT)
    139     fps = capture.get(cv.CAP_PROP_FPS)
    140     print(height, width, count, fps)
    141     detector = LaneLineDetection()
    142     while (True):
    143         ret, frame = capture.read()
    144         if ret is True:
    145             cv.imshow("video-input", frame)
    146             detector.process(frame, 0)
    147             c = cv.waitKey(1)
    148             if c == 27:
    149                 break
    150         else:
    151             break
    152 
    153 
    154 if __name__ == "__main__":
    155     video_run()
    156     cv.waitKey(0)
    157     cv.destroyAllWindows()
  • 相关阅读:
    JavaScript 相等(==)与全等(===)操作符
    JavaScript 判断空对象、空数组的方法
    JavaScript中的深拷贝与浅拷贝
    JS trim去除字符串收尾指定字符
    Django+Markdown+Pygments 支持Markdown 实现代码高亮
    crontab 定时服务
    程序员如何修复婚姻的bug
    向Mysql 中插入汉字(Emoji)出现 Incorrect string value
    根据html页面id寻找对应的Js文件
    Django Pagination
  • 原文地址:https://www.cnblogs.com/codeAndlearn/p/11432366.html
Copyright © 2020-2023  润新知