//TODO
Q:给定图片,如何辨认车道线?
能够从色彩、形态、方向、图像中的地位 几个角度来确定车道线。
色彩:
利用色彩来判断车道线(图中的车道线是红色的)
RGB图片有三个色彩通道R、G、B,每个通道中的每一个像素都是0到255范畴内的值。
其中0是最暗值,255是最亮值。
因而RGB图像中,纯白色是255,255,255
尝试过滤红色外的其余色彩:
import matplotlib.pyplot as pltimport matplotlib.image as mpimgimport numpy as npprint('start')# 读取图片,展现原图image=mpimg.imread('test.jpg')plt.imshow(image)plt.show()# 备份图片,不批改原图cp_image=np.copy(image)# 定义筛选阈值,红色是255,255,255,因而咱们选比255稍小的值即可,这里抉择200r_threshold=200g_threshold=200b_threshold=200rgb_thresholds=[r_threshold,g_threshold,b_threshold]# 筛选器,筛选出低于阈值的像素thresholds=(image[:,:,0]<rgb_thresholds[0]) | (image[:,:,1]<rgb_thresholds[1]) | (image[:,:,2]<rgb_thresholds[2])# 将不满足条件的值设为0,0,0,即彩色cp_image[thresholds]=[0,0,0]# 展现图片plt.imshow(cp_image)plt.show()# 保留图片mpimg.imsave('after_color.jpg',cp_image)
执行后果:
区域:
发现只靠色彩无奈精确检测出车道线,因为其余物体也有红色。
当初咱们假如车道线肯定是在车辆前端的固定区域内:
思考只对该区域进行色彩解决。
首先咱们要可能选出一个三角形区域:
import matplotlib.pyplot as pltimport matplotlib.image as mpimgimport numpy as npprint('start')# 读取图片,展现image=mpimg.imread('test.jpg')plt.imshow(image)plt.show()# 显示图片大小print(image.shape) # 后果:(540,960,3)# 备份图片,不批改原图cp_image=np.copy(image)# 指定区域点,这里是三角形区域,结构三角形的三个点# 须要留神的是,x轴是在下面的,y轴是从上往下的,和平时的坐标轴不太一样p_left=[0,550]p_right=[900,550]p_mid=[400,200]# 结构三角形的三条边# np.polyfit仿佛是给定一组点,拟合出一个多项式的函数# 咱们这里用来结构直线方程# 开端的参数1示意结构一次方程line_left=np.polyfit((p_left[0],p_mid[0]),(p_left[1],p_mid[1]),1)line_right=np.polyfit((p_mid[0],p_right[0]),(p_mid[1],p_right[1]),1)line_bottom=np.polyfit((p_left[0],p_right[0]),(p_left[1],p_right[1]),1)# 筛选器,用于筛选区域内的像素# 首先要结构地位矩阵# np.meshgrid传入X可选值域和Y值域,返回所有可选的坐标# np.arange(0,xsize,step)是结构[0,xsize)中步长为step的等差数列,默认步长为1# np.arange()和np.linespace()的区别在于,arange传入的是步长,linespace传入的是个数ysize=cp_image.shape[0] # 留神:行是yxsize=cp_image.shape[1] # 留神:列是xX,Y=np.meshgrid(np.arange(0,xsize),np.arange(0,ysize))region_threshold=((X*line_left[0]+line_left[1])<Y) \ & ((X*line_right[0]+line_right[1])<Y) \ & ((X*line_bottom[0]+line_bottom[1])>Y)# 绘制区域,将区域内的局部涂成红色cp_image[region_threshold]=[255,0,0]# 展现区域plt.imshow(cp_image)plt.show()
运行后果:
联合色彩和区域:
只在特定区域内进行色彩解决:
import matplotlib.pyplot as pltimport matplotlib.image as mpimgimport numpy as npprint('start')image = mpimg.imread('test.jpg')plt.imshow(image)plt.show()# 结构色彩筛选器r_threshold=200g_threshold=200b_threshold=200rgb_thresholds=[r_threshold,g_threshold,b_threshold]color_thresholds=(image[:,:,0]<rgb_thresholds[0]) \ | (image[:,:,1]<rgb_thresholds[1]) \ | (image[:,:,2]<rgb_thresholds[2])# 结构区域筛选器p_left=[0,540]p_right=[900,540]p_mid=[500,300]line_left=np.polyfit((p_left[0],p_mid[0]),(p_left[1],p_mid[1]),1)line_right=np.polyfit((p_mid[0],p_right[0]),(p_mid[1],p_right[1]),1)line_bottom=np.polyfit((p_left[0],p_right[0]),(p_left[1],p_right[1]),1)ysize=image.shape[0] # 留神:行是yxsize=image.shape[1] # 留神:列是xX,Y=np.meshgrid(np.arange(0,xsize),np.arange(0,ysize))region_threshold=((X*line_left[0]+line_left[1])<Y) \ & ((X*line_right[0]+line_right[1])<Y) \ & ((X*line_bottom[0]+line_bottom[1])>Y)# 显示区域# plt.ploy()是画直线用的# plt.ploy()的第三个参数中,b示意色彩blue,--示意虚线,b--即蓝色虚线cp_image=np.copy(image)x=[p_left[0],p_mid[0],p_right[0],p_left[0]]y=[p_left[1],p_mid[1],p_right[1],p_left[1]]plt.plot(x,y,'b--',lw=5)plt.imshow(cp_image)plt.show()# 对区域内进行色彩解决# cp_image[~region_threshold]=[0,0,0]cp_image[region_threshold&~color_thresholds]=[255,0,0]plt.imshow(cp_image)plt.show()
执行后果:
这样就实现了仅在特定区域内筛选色彩
其余色彩的车道线怎么办:canny边缘检测算法
然而,车道线不仅仅都是红色,有可能呈现其余色彩。
咱们甚至无奈事后晓得车道线的色彩,这时候怎么办呢?
有没有方法可能解决任何色彩的线条?
图像是x - y的数学函数,因而也能够对他进行数学运算,例如求导。
图像是二维的,因而对于x和y同时求导是有意义的,这称为梯度。
咱们测量像素点在每个地位上的变动水平,以及哪个方向变动最快,
通过梯度计算,可能取得较粗的边缘线,
利用canny算法,咱们通过仅保留梯度最大的像素点,将边缘细化,
而后,再通过蕴含一些梯度强度更低一些的像素点,再次扩大高强度边缘的宽度。
梯度强度低的像素点阈值是咱们调用canny函数时能够本人定的。
利用canny算法检测边缘线:
import matplotlib.pyplot as pltimport matplotlib.image as mpimgimport cv2image = mpimg.imread('exit-ramp.jpg')plt.imshow(image)plt.show()# 转化为灰度图片,灰度的目标'应该'是更好的检测梯度变动,防止色彩烦扰gray_image=cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)plt.imshow(gray_image,cmap='gray')plt.show()# 先进行高斯含糊,高斯含糊实质上是克制噪声和伪梯度均匀的一种办法# 实际上cv2.Canny()外部自带高斯平滑,但再做一次能够进一步平滑kernel_size=5 # 能够抉择任意奇数,越大越平滑blur_gray_image=cv2.GaussianBlur(gray_image,(kernel_size,kernel_size),0)# 算法首先会检测出>high_threshold的强像素,并回绝<low_threshold的强像素# 接着,在low_threshold和high_threshold之间的像素,和强像素联通的保留# 输入的edges在边缘地位是红色的,非边缘地位是彩色的# 参数取值:因为像素值是256的,因而阈值能够选成十上百# 官网倡议low与high的比值为1:2或1:3low_threshold=50high_threshold=150edges=cv2.Canny(blur_gray_image,low_threshold,high_threshold)plt.imshow(edges,cmap='Greys_r')plt.show()
运行后果: