先解释一下何为中线检测:
程序输入的是一段视频,拍摄的是一条白色直线。
如图所示
要求拟合直线的中线并计算中线到图像中心的距离以及和竖直轴的夹角。
思路很明确: 堆每一帧作如下处理:先滤波,去除噪声,防止后面检测直线时的干扰;然后用Hough检测找到图片中的直线;将得到的直线拟合成一条中线并最后显示出来;然后循环,依次处理每一帧并显示。
然而没想到遇到了不少坑。。。。。。。
一开始的时候先把视频截了个图,计划先对单张照片进行处理,成功之后再处理视频。然而我是全屏播放的条件下截的屏,然后就挖了一个坑。。。。。。
这一步还是比较顺利的(虽然花了我一个晚上的时间。。。。。。),遇到了第一个问题
vector <Vec2f> lines;//the rho and theta of each line
HoughLines(edge,lines,0.1,CV_PI/360,13,0,0);
我一开始想的拟合方法是对每一条线的rho 和 theta 相加然后取平均值,进而得到中线的rho和theta。theta这么做是没问题的,但是rho就不行了,如果白线左边检测出来1条线,而右边检测出来100条线,这种方法得到的’中线‘肯定会明显偏向右边。
解决思路:对白线的左边和右边分别拟合两条直线,然后再用拟合得到的两条线的rho取平均值得到中线的rho。
解决方法: 新建一个array储存lines的rho,然后对rho进行排序,然后计算相邻元素的差值,当相邻差值出现剧烈变化时判定之后的线属于另外一边。
代码如下
sort(arr_rho,arr_rho+lines.size());
//for(int i=(total-count);i<total;i++)//because the heading (total-count) values in the array is zero
// cout<<"rho"<<arr_rho[i]<<endl;
double rho_mid_l,rho_mid_r;
static int divide;
double count_l=0,count_r=0;
bool left=1;
for(int i=(total-count);i<total;i++)
{
if((abs(arr_rho[i]-arr_rho[i+1]) > 10*abs(arr_rho[i+1]-arr_rho[i+2])));
{
left = 0;
divide = i;
}
if(lef