珠海网站策划,莱芜人力资源部最新招聘信息,着力加强网站内容建设,龙岗住房建设局网站我们基于图像的梯度和颜色特征#xff0c;定位车道线的位置。
在这里选用Sobel边缘提取算法#xff0c;Sobel相比于Canny的优秀之处在于#xff0c;它可以选择横向或纵向的边缘进行提取。从车道的拍摄图像可以看出#xff0c;我们关心的正是车道线在横向上的边缘突变。Ope…我们基于图像的梯度和颜色特征定位车道线的位置。
在这里选用Sobel边缘提取算法Sobel相比于Canny的优秀之处在于它可以选择横向或纵向的边缘进行提取。从车道的拍摄图像可以看出我们关心的正是车道线在横向上的边缘突变。OpenCV提供的cv2.Sobel()函数将进行边缘提取后的图像做二进制图的转化即提取到边缘的像素点显示为白色值为1未提取到边缘的像素点显示为黑色值为0。由于只使用边缘检测在有树木阴影覆盖的区域时虽然能提取出车道线的大致轮廓但会同时引入的噪声给后续处理带来麻烦。所以在这里我们引入颜色阈值来解决这个问题。
1.颜色空间
在车道线检测中我们使用的是HSL颜色空间其中H表示色相即颜色S表示饱和度即颜色的纯度L表示颜色的明亮程度。
HSL的H(hue)分量代表的是人眼所能感知的颜色范围这些颜色分布在一个平面的色相环上取值范围是0°到360°的圆心角每个角度可以代表一种颜色。色相值的意义在于我们可以在不改变光感的情况下通过旋转色相环来改变颜色。在实际应用中我们需要记住色相环上的六大主色用作基本参照360°/0°红、60°黄、120°绿、180°青、240°蓝、300°洋红它们在色相环上按照60°圆心角的间隔排列 HSL的S(saturation)分量指的是色彩的饱和度描述了相同色相、明度下色彩纯度的变化。数值越大颜色中的灰色越少颜色越鲜艳呈现一种从灰度到纯色的变化。因为车道线是黄色或白色所以利用s通道阈值来检测车道线。 HSL的L(lightness)分量指的是色彩的明度作用是控制色彩的明暗变化。数值越小色彩越暗越接近于黑色数值越大色彩越亮越接近于白色。 2.车道线提取
车道线提取的代码如下所示
# 车道线提取代码
def pipeline(img, s_thresh(170, 255), sx_thresh(40, 200)):img np.copy(img)#1.将图像转换为HLS色彩空间并分离各个通道hls cv2.cvtColor(img, cv2.COLOR_RGB2HLS).astype(np.float)h_channel hls[:, :, 0]l_channel hls[:, :, 1]s_channel hls[:, :, 2]#2.利用sobel计算x方向的梯度sobelx cv2.Sobel(l_channel, cv2.CV_64F, 1, 0)abs_sobelx np.absolute(sobelx) # 将导数转换为8bit整数scaled_sobel np.uint8(255 * abs_sobelx / np.max(abs_sobelx))sxbinary np.zeros_like(scaled_sobel)sxbinary[(scaled_sobel sx_thresh[0]) (scaled_sobel sx_thresh[1])] 1# 3.对s通道进行阈值处理s_binary np.zeros_like(s_channel)s_binary[(s_channel s_thresh[0]) (s_channel s_thresh[1])] 1# 4. 将边缘检测的结果和颜色空间阈值的结果合并并结合l通道的取值确定车道提取的二值图结果color_binary np.zeros_like(sxbinary)color_binary[((sxbinary 1) | (s_binary 1)) (l_channel 100)] 1return color_binary
我们来看下整个流程
首先我们是把图像转换为HLS颜色空间然后利用边缘检测和阈值的方法检测车道线我们以下图为例来看下检测结果 利用sobel边缘检测的结果利用S通道的阈值检测结果 将边缘检测结果与颜色检测结果合并并利用L通道抑制非白色的信息 总结 颜色空间 HLS色相饱和度明亮程度 车道线提取 颜色空间转换-》边缘检测-》颜色阈值-》合并得到检测结果。 代码
# encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#遍历文件夹
import glob
from moviepy.editor import VideoFileClip参数设置
nx 9
ny 6
#获取棋盘格数据
file_paths glob.glob(./camera_cal/calibration*.jpg)# 绘制对比图
def plot_contrast_image(origin_img, converted_img, origin_img_titleorigin_img, converted_img_titleconverted_img,converted_img_grayFalse):fig, (ax1, ax2) plt.subplots(1, 2, figsize(15, 20))ax1.set_title origin_img_titleax1.imshow(origin_img)ax2.set_title converted_img_titleif converted_img_gray True:ax2.imshow(converted_img, cmapgray)else:ax2.imshow(converted_img)plt.show()#相机矫正使用opencv封装好的api
#目的:得到内参、外参、畸变系数
def cal_calibrate_params(file_paths):#存储角点数据的坐标object_points [] #角点在真实三维空间的位置image_points [] #角点在图像空间中的位置#生成角点在真实世界中的位置objp np.zeros((nx*ny,3),np.float32)#以棋盘格作为坐标每相邻的黑白棋的相差1objp[:,:2] np.mgrid[0:nx,0:ny].T.reshape(-1,2)#角点检测for file_path in file_paths:img cv2.imread(file_path)#将图像灰度化gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#角点检测rect,coners cv2.findChessboardCorners(gray,(nx,ny),None)#若检测到角点则进行保存 即得到了真实坐标和图像坐标if rect True :object_points.append(objp)image_points.append(coners)# 相机较真ret, mtx, dist, rvecs, tvecs cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None)return ret, mtx, dist, rvecs, tvecs# 图像去畸变利用相机校正的内参畸变系数
def img_undistort(img, mtx, dist):dis cv2.undistort(img, mtx, dist, None, mtx)return dis#车道线提取
#颜色空间转换--》边缘检测--》颜色阈值--》并且使用L通道进行白色的区域进行抑制
def pipeline(img,s_thresh (170,255),sx_thresh(40,200)):# 复制原图像img np.copy(img)# 颜色空间转换hls cv2.cvtColor(img,cv2.COLOR_RGB2HLS).astype(np.float)l_chanel hls[:,:,1]s_chanel hls[:,:,2]#sobel边缘检测sobelx cv2.Sobel(l_chanel,cv2.CV_64F,1,0)#求绝对值abs_sobelx np.absolute(sobelx)#将其转换为8bit的整数scaled_sobel np.uint8(255 * abs_sobelx / np.max(abs_sobelx))#对边缘提取的结果进行二值化sxbinary np.zeros_like(scaled_sobel)#边缘位置赋值为1非边缘位置赋值为0sxbinary[(scaled_sobel sx_thresh[0]) (scaled_sobel sx_thresh[1])] 1plt.figure()plt.imshow(sxbinary, cmapgray)plt.title(sobel)plt.show()#对S通道进行阈值处理s_binary np.zeros_like(s_chanel)s_binary[(s_chanel s_thresh[0]) (s_chanel s_thresh[1])] 1plt.figure()plt.imshow(s_binary, cmapgray)plt.title(schanel)plt.show()# 结合边缘提取结果和颜色通道的结果color_binary np.zeros_like(sxbinary)color_binary[((sxbinary 1) | (s_binary 1)) (l_chanel 100)] 1return color_binaryif __name__ __main__:#测试车道线提取img cv2.imread(./test/test3.jpg)result pipeline(img)plot_contrast_image(img, result, converted_img_grayTrue)
代码输出
1.原图
2.sobel之后
3.schanel 4.处理完毕对比图