天上星河转,人间幕帘垂。凉生枕蕈泪痕滋。起解罗衣聊问何其。
晚上,额或者说凌晨2:42了。好像还没睡。
最近在调车,我是做图像的。
其实挺奇怪的,我本来是做控制的,转组后算是跟队做硬件。五月份的时候,突然被要求做图像处理,就稀里糊涂的变成了图像处理的队员,然后学长学姐不知道为啥先后退出,又稀里糊涂的成了正式队员。
其实其他队员开始似乎挺抱期望的,因为他们借到了杨一鸣学长的图像处理代码,认为只要稍加修改就可以使用。
但是我明白,因为有了前事的经验。所以知道做这种事最容易、也最忌讳把事情想简单。做双车的时候就是,认为二月初就可以基本完成,但实际上进度远远落后。
说到杨一鸣学长,我觉得他很像是熟悉的人,感觉比较亲切,然后业务能力也确实强。我觉得这些能力是需要在课堂外额外花时间去积累的。
说回来,反正现在七月十二号了,进度依然不乐观。稳定性和速度,甚至完全比不上使用麦克姆轮的全向行进组的小车(杨一鸣学长做的图像处理)
图像处理代码是自己一行一行敲出来的,一方面是因为学长只给了旧版的代码,执行尚存问题。并且5000行的代码阅读起来不是很通畅,耦合性也稍有些严重。
现在的图像处理代码里使用了大量的色块比较(就算是简单的模板比较吧),前天把算法小改了下,算是减少了一些运算量。使用这种方式,一方面是因为对特征点的识别不是很擅长,并且使用的是水平扫线法而非八领域生长,边缘的误判比较严重;另一方面是得益于RT1064的高性能,可以比较任性的使用资源而不用担心运算速度和内存空间的问题(相比之前使用的mm32spin27ps好多了)。
但是也色块识别有一些比较严重的问题,一是对于变化的环境适应性较差(即所谓“鲁棒性”较差),二是反而增加了计算开销。
色块识别在图像中的位置是固定的,因此对于每个特征的不同表现形式不会特别适应。比如三岔入口,正对和斜入会有完全不同的表现形式,原本正对时所呈现的白区,在斜入时很可能就是黑区,如果采用色块识别就会失效。
耗费算力的问题,色块识别在图像中要逐像素比较,即使使用了快速模板比较的写法,也仍然存在较大的计算量。以每帧必然比较的T形路为例,如果符合条件的话最多需要比较188*3个像素点。这还仅仅是一个特征...
为了减少不必要的状态判断,我认为需要先完善状态互斥的内容。即有限状态机中列出互斥的状态,使状态识别更像是串行而非并行的,就像在环岛状态中不必识别十字一样。
另外对一个元素分段处理也是很必要的。以前使用学长的代码时总是卡在入环阶段,所以对这种链式的有限状态机有些怀疑,但其实是因为没有找到比较合适的错误状态的处理机制。毕竟链式状态要简洁的多。
//------环岛检测 <head>---------//
switch(Round_Status)
{
case 0:
if(flag_Y_Road || Feature_Verify_Color(83,9,20,40,Black,10))
{
break;
}
if(!RoundOutCount && Feature_Verify_Color(10,10,50,8,White,90) && !Feature_Verify_Color(127,10,50,3,White,90))
{
Round_Status=1;
flag_Normal_Lose_L=1; //避免打偏
}
else if(!RoundOutCount && Feature_Verify_Color(127,10,50,8,White,90) && !Feature_Verify_Color(10,10,50,3,White,90))
{
Round_Status=2;
flag_Normal_Lose_R=1;
}
break;
case 1:
if(ad_value_all>Round_ad_limit && Feature_Verify_Color(0,10,20,10,Black,90))
{
if(ad_value_all<Round_ad_limit)
{
Round_Status=0;
break;
}
Round_Status=3;
}
break;
case 2:
if(ad_value_all>Round_ad_limit && Feature_Verify_Color(167,10,20,10,Black,90))
{
if(ad_value_all<Round_ad_limit)
{
Round_Status=0;
break;
}
Round_Status=4;
}
break;
case 3:
if(!RoundInCount && Feature_Verify_Color(0,10,50,10,White,90))
{
RoundInCount=25;
}
if(RoundInCount==1)
{
Round_Status=5;
}
flag_Normal_Lose_L=1;
break;
case 4:
if(!RoundInCount && Feature_Verify_Color(137,10,50,10,White,90))
{
RoundInCount=25;
}
if(RoundInCount==1)
{
Round_Status=6;
}
flag_Normal_Lose_R=1;
break;
case 5:
if(Feature_Verify_Color(167,39,20,10,White,90))
{
Round_Status=7;
}
flag_Normal_Lose_L=1; //否则在大环内容易晃
break;
case 6:
if(Feature_Verify_Color(0,39,20,10,White,90))
{
Round_Status=8;
}
flag_Normal_Lose_R=1;
break;
case 7:
if(1)
{
Round_Status=9;
flag_Normal_Lose_L=1;
}
break;
case 8:
if(1)
{
Round_Status=10;
flag_Normal_Lose_R=1;
}
break;
case 9:
/*
if(!RoundOutCount && Feature_Verify_Color(0,10,50,10,White)>=90)
{
Round_Status=10;
RoundOutCount=40;
flag_Normal_Lose_L=1;
}
*/
if(!RoundOutCount)
{
Round_Status=11;
RoundOutCount=50;
flag_Normal_Lose_L=1;
}
break;
case 10:
/*
if(!RoundOutCount && Feature_Verify_Color(137,10,50,10,White)>=90)
{
Round_Status=11;
RoundOutCount=40;
flag_Normal_Lose_R=1;
}
break;
*/
if(!RoundOutCount)
{
Round_Status=12;
RoundOutCount=50;
flag_Normal_Lose_R=1;
}
break;
case 11:
if(RoundOutCount==1)
{
Round_Status=0;
}
break;
case 12:
if(RoundOutCount==1)
{
Round_Status=0;
}
break;
}
if((flag_Y_Road || flag_Y_Road_IN) && Round_Status<3) //防止三岔误识别为环岛
{
Round_Status=0;
}
if(RoundOutCount && Round_Status<=8)
{
Round_Status=0;
}
//------环岛检测 <bottom>---------//
↑我写的环岛状态机,可以看出使用了很多色块比较,所以存在小车跑偏无法入环的情况。
写这还花了不少时间,暂且这样。3:32分,该睡觉了。

Comments NOTHING