以下为使用上面方法应用测试图片的过滤前后对比图:
可以看到该方法的缺陷是在路面颜色相对较浅且车道线颜色为黄色时,无法捕捉到车道线(第三,第六,第七张图),但在其他情况车道线捕捉效果还是不错的。
接下来测试一下使用全局的颜色变化梯度来进行阈值过滤:
void mag_thresh(const cv::Mat& src,cv::Mat& dst,const int& sobel_kernel=3,const int& thresh_min=0,const int& thresh_max=255){ cv::Mat src_gray,gray_x,gray_y,grad; cv::Mat abs_gray_x,abs_gray_y; //转换成为灰度图片 cv::cvtColor(src,src_gray,cv::COLOR_RGB2GRAY); //使用cv::Sobel()计算x方向或y方向的导 cv::Sobel(src_gray,gray_x,CV_64F,1,0,sobel_kernel); cv::Sobel(src_gray,gray_y,CV_64F,0,1,sobel_kernel); //转换成CV_8U cv::convertScaleAbs(gray_x,abs_gray_x); cv::convertScaleAbs(gray_y,abs_gray_y); //合并x和y方向的梯度 cv::addWeighted(abs_gray_x,0.5,abs_gray_y,0.5,0,grad); //二值化 cv::inRange(grad,thresh_min,thresh_max,dst); // cv::threshold(grad,dst,thresh_min,thresh_max,cv::THRESH_BINARY|cv::THRESH_OTSU); } mag_thresh(imge,mag,3,45,150);结果仍然不理想(观察第三,第六,第七张图片),原因是当路面颜色相对较浅且车道线颜色为黄色时,颜色变化梯度较小,想要把捕捉车道线需要把阈值下限调低,然而这样做同时还会捕获大量的噪音像素,效果会更差。
那么使用颜色阈值过滤呢?
下面为使用hls颜色空间的s通道进行阈值过滤:
可以看到在路面颜色相对较浅且车道线颜色为黄色的区域,车道线仍然被清晰的捕捉到了,然而在其他地方表现却不太理想(第四,第八张图片)
因此为了应对多变的路面情况,需要结合多种阈值过滤方法。
以下为最终的阈值过滤组合:
abs_sobel_thresh(imge,absm,'x',55,200);//sobel边缘识别 mag_thresh(imge,mag,3,45,150); hls_select(imge,hls,'s',160,255); dir_threshold(imge,dir,3,0.7,1.3); luv_select(imge,luv,'l',180,255); // lab_select(imge,lab,'b',126,127); imgout=(absm&mag&luv)|(hls&luv); 透视变换(perspective transform)这里使用"cv::getPerspectiveTransform()"来获取变形矩阵(tranform matrix),把阈值过滤后的二进制图片变形为鸟撒视角。
以下为定义的源点(source points)和目标点(destination points)
Source Destination585, 460 320, 0
203, 720 320, 720
1127, 720 960, 720
695, 460 960, 0
定义方法获取变形矩阵和逆变形矩阵:
void get_M_Minv(const vector<cv::Point2f>& src,const vector<cv::Point2f>& dst,cv::Mat& M,cv::Mat& Minv){ M=cv::getPerspectiveTransform(src,dst); Minv=cv::getPerspectiveTransform(dst,src); }然后使用"cv::warpPerspective()"传入相关值获得变形图片(wrapped image)
cv::warpPerspective(cimg,imge,M,img.size(),cv::INTER_LINEAR);以下为原图及变形后的效果:
以下为阈值过滤后二进制图变形后效果:
上面的二进制图还存在一定的噪音像素,为了准确检测车道边界,首先要确定哪些像素是属于车道线的。