|
01、项目介绍与图片预处理的大概流程(代码实操)
项目介绍:
用传统的计算机视觉方法,主要使用OpenCV,识别道路上的车道线。先在一系列单独的图像上开发测试,
然后应用于视频流(实际上只是一系列图像的集合)
需要安装额外的库: pip3 install moviepy
步骤包括:变为灰度图像、高斯核卷积(滤波器)、Canny边缘检测、感兴趣区域选择、Hough Tranform线检测、外推后的车道线、VideoFileClip等
刚开始用基于OpenCV传统的计算机视觉技术,后来尝试用神经网络MaskRCNN图像实例分割的方法
所用到的技术:
1、RGB2GRAY变灰度、GaussianBlur降噪、Canny或Sobel边缘检测、fillPoly图像蒙版得到感兴趣区域、HoughLinesP线检测
2、计算相机校正矩阵和失真系数来校正图片
3、使用梯度阈值(gradient threshold),颜色阈值(color threshold)等处理图片得到清晰捕捉车道线的二进制图
4、使用透视变换(perspective transform)得到二进制图(binary image)的鸟瞰图
5、检测属于车道线的像素并用它来测出车道边界
6、MaskRCNN图像实例分割:VIA图像标注工具训练自己的数据集,效果不错
技术难点:
1、定位车道线的基点:把图片一分为二,左右两边的在x轴上的像素分布峰值非常有可能就是车道线基点
2、定位基点后,再使用使用滑动窗口多项式拟合来获取车道边界(使用9个200px宽的滑动窗口来定位一条车道线像素)
3、MaskRCNN网络结构复杂,backbone为resnet50或101,rpn网络、ProposalLayer、ROIAlign、FPN特征金字塔网络需要进一步细致研究
测试图片压缩包在附件test_images.zip ,可提供免费下载!
东方老师AI官网:http://www.ai111.vip
有任何问题可联系东方老师微信:dfy_88888
【微信二维码图片】
- # -*- coding: utf-8 -*-
- __author__ = u'东方耀 微信:dfy_88888'
- __date__ = '2019/11/2 11:19'
- __product__ = 'PyCharm'
- __filename__ = 'LandLinesDetection_for_Image'
- # 导入工具库
- import numpy as np
- import cv2
- import math
- import os
- print(os.listdir("test_images/"))
- # solidWhiteRight.jpg solidWhiteCurve.jpg
- img_original = cv2.imread('test_images/solidWhiteCurve.jpg')
- # img_original = cv2.imread('dfy_88888.jpg')
- img_shape_original = img_original.shape
- print('0、原始图像shape(HWC):', img_shape_original)
- # 如果用cv2读图片并且用cv2显示图片 则不需要考虑颜色空间变换
- cv2.imshow('0 step:original image', img_original)
- cv2.waitKey()
- def grayscale(img):
- """灰度变换"""
- # return cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
- # Or use BGR2GRAY if you read an image with cv2.imread()
- return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- img_gray = grayscale(img_original)
- print('1、gray图像shape(HWC):', img_gray.shape)
- cv2.imshow('1 step:gray image', img_gray)
- cv2.waitKey()
- def gaussian_blur(img, kernel_size):
- """高斯去燥"""
- return cv2.GaussianBlur(img, (kernel_size, kernel_size), sigmaX=0)
- def median_blur(img, kernel_size):
- """中值去燥"""
- return cv2.medianBlur(img, kernel_size)
- img_blur = gaussian_blur(img_gray, kernel_size=5)
- print('2、高斯降噪后图像shape(HWC):', img_blur.shape)
- cv2.imshow('2 step:gaussian Blur', img_blur)
- cv2.waitKey()
- def canny(img, low_threshold, high_threshold):
- """边缘检测"""
- return cv2.Canny(img, low_threshold, high_threshold)
- def sobel(img):
- """边缘检测 效果不行"""
- return cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
- img_edge = canny(img_blur, low_threshold=50, high_threshold=150)
- # img_edge = sobel(img_blur)
- print('3、边缘检测后图像shape(HWC):', img_edge.shape)
- cv2.imshow('3 step:canny detector', img_edge)
- cv2.waitKey()
- def region_of_interest(img, vertices):
- """
- 图像蒙版.
- """
- # 定义一个蒙版, 所有值都为0 黑色图像
- mask = np.zeros_like(img)
- # 根据输入图像的通道数, 设置色彩
- if len(img.shape) > 2:
- channel_count = img.shape[2]
- ignore_mask_color = (255,) * channel_count
- else:
- print('提取gray图片的_感兴趣区域')
- ignore_mask_color = 255
- # 使用白彩填充vertices构成的多边形在mask全黑的图像上
- mask = cv2.fillPoly(mask, vertices, ignore_mask_color)
- # mask 的像素 不是0 就是255 在多边形区域是255 其他都是0
- # 执行蒙版操作
- masked_image = cv2.bitwise_and(img, mask)
- return masked_image
- # 顺时针方向:左下 左上 右上 右下
- vertices = np.array([[(0, img_shape_original[0]),
- (425, 315),
- (540, 315),
- (img_shape_original[1], img_shape_original[0])]], dtype=np.int32)
- img_masked_edges = region_of_interest(img_edge, vertices)
- print('4、感兴趣区域后图像shape(HWC):', img_masked_edges.shape)
- cv2.imshow('4 step:region_of_interest', img_masked_edges)
- cv2.waitKey()
- def draw_lines(img, lines, color=[0, 0, 255], thickness=2):
- """
- 画线段
- """
- for line in lines:
- for x1, y1, x2, y2 in line:
- print('画线的点:(x1=%d, y1=%d), (x2=%d, y2=%d)' % (x1, y1, x2, y2))
- # color=[0, 0, 255] opencv bgr 这是红色
- cv2.line(img, (x1, y1), (x2, y2), color, thickness)
- def hough_lines(img, rho, theta, threshold, min_line_len, max_line_gap, extrapolate=False):
- """
- `img` Canny边缘检测的输出.
- `rho` = Hough Grid中像素的距离
- `theta` = Hough grid中角度的距离
- `threshold` = 最小的voting数值
- `min_line_len` = 构成一条线的最小像素个数
- `max_line_gap` = 可以相连的线段之间的最大距离
- extrapolate = 外推
- 返回黑背景上面有白线的图.
- """
- lines = cv2.HoughLinesP(img, rho, theta, threshold, np.array([]), minLineLength=min_line_len,
- maxLineGap=max_line_gap)
- # 3通道的黑色图像
- line_img = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
- print('要画的线:', lines)
- # 8*1*4
- print('要画的线shape:', lines.shape)
- if not extrapolate:
- draw_lines(line_img, lines)
- elif extrapolate:
- draw_lines_extrapolated(line_img, lines)
- return line_img
- def weighted_img(img, initial_img, a=0.8, b=1.):
- """
- `img` hough_lines()的输出, 黑背景上面有红线的图.
- `initial_img` 原始图像.
- 加权相加:
- initial_img * a + img * b
- """
- return cv2.addWeighted(initial_img, a, img, b, 0)
- img_hough_lines = hough_lines(img_masked_edges, rho=1, theta=np.pi/180, threshold=40,
- min_line_len=60, max_line_gap=20, extrapolate=False)
- print('5、霍夫线检测后图像shape(HWC):', img_hough_lines.shape)
- cv2.imshow('5 step:Hough Tranform line', img_hough_lines)
- cv2.waitKey()
- img_lanes = weighted_img(img=img_hough_lines, initial_img=img_original, a=0.8, b=1.)
- print('6、在原图上画出检测出来的线 展示效果shape(HWC):', img_lanes.shape)
- cv2.imshow('6 step:addWeighted show', img_lanes)
- cv2.waitKey()
复制代码
0、原始图像shape(HWC): (540, 960, 3)
1、gray图像shape(HWC): (540, 960)
2、高斯降噪后图像shape(HWC): (540, 960)
3、边缘检测后图像shape(HWC): (540, 960)
提取gray图片的_感兴趣区域
4、感兴趣区域后图像shape(HWC): (540, 960)
要画的线: [[[689 430 876 538]]
[[534 340 877 538]]
[[496 316 897 539]]
[[629 389 898 538]]
[[293 462 353 412]]
[[281 461 344 410]]
[[389 382 459 325]]
[[498 320 873 536]]]
要画的线shape: (8, 1, 4)
画线的点:(x1=689, y1=430), (x2=876, y2=538)
画线的点:(x1=534, y1=340), (x2=877, y2=538)
画线的点:(x1=496, y1=316), (x2=897, y2=539)
画线的点:(x1=629, y1=389), (x2=898, y2=538)
画线的点:(x1=293, y1=462), (x2=353, y2=412)
画线的点:(x1=281, y1=461), (x2=344, y2=410)
画线的点:(x1=389, y1=382), (x2=459, y2=325)
画线的点:(x1=498, y1=320), (x2=873, y2=536)
5、霍夫线检测后图像shape(HWC): (540, 960, 3)
6、在原图上画出检测出来的线 展示效果shape(HWC): (540, 960, 3)
|
-
01.png
(461.81 KB, 下载次数: 621)
-
02.png
(306.02 KB, 下载次数: 595)
-
03.png
(17.62 KB, 下载次数: 614)
-
04.png
(17.05 KB, 下载次数: 604)
-
0_step.png
(297.78 KB, 下载次数: 620)
-
1_step.png
(203.06 KB, 下载次数: 602)
-
2_step.png
(163.04 KB, 下载次数: 596)
-
3_step.png
(12.65 KB, 下载次数: 600)
-
4_step.png
(5.29 KB, 下载次数: 595)
-
5_step.png
(5.26 KB, 下载次数: 605)
-
6_step.png
(309.22 KB, 下载次数: 605)
-
-
test_images.zip
2.67 MB, 阅读权限: 10, 下载次数: 31
|