问:关于CCD,有几个问题想请教下: 1、 CCD的二值化是关键,阈值除了取平均值外, 还有哪些好的办法,比如双峰阈值法吗,大致的思路是怎么样的? 2、 全白和全黑的二值化怎么办,某种意义如果有阈值,计算结果可能就不是全白或全黑,怎么办? 3、 CCD是一维128个值的数组,车模偏差error一般为64-(left+right)/2 ,left和right是道路的左右边界位置,但是对于特殊的情况怎么办?例如转弯时只有左跳变,即只有left, 怎么办,是否按right=left+(路的宽度)来进行计算? 4、 同样的特殊情况,在十字弯时,全白的情况下,如何计算出车模偏差呢?毕竟任何情况下舵机的控制依赖于车模偏差error,再过十字弯时计算error怎么办? 5、 对于两个CCD,除了上诉问题外,还存在两个CCD,将计算出两个error ,怎么用这两个值,是取平均?还是权值平均?还是优先选择近的或远的? 6、 转向时的微分,一般是用硬件来实现(如陀螺仪)还是软件计算error1-error2来完成?
[size=10.5000pt]
[size=10.5000pt]答: [size=10.5000pt]1、CCD二值化常用除了取平均值外,还有双峰直方图和大津法,双峰直方图法是指在CCD的128个像素点中,把它从按灰度值从小到大排列,因为赛道有白有黑,白色跑道上的灰度值都比较大,但即使都在白的上面,白色之间像素点灰度值也有差异,那到底取白色灰度值区间里面哪一个值作为白色灰度值呢,是白的最大值,还是白的最小值,或者白色部分的平均,若是取白色部分的一个最大灰度值作为白色部分,有可能因为白色赛道某个点反光,取到最大值255,这显然不合理,所以为了排除一些干扰情况,我们取白色赛道特征代表灰度值的时候,不是取一个点而是取白色部分在某一区间分布最多的点,以这个区间的灰度值作为白色特征代表点,比如CCD照在正常赛道上,第50个点到底90个点照在白色赛道上,从左到右像素点依次为210,212.................230,235,228........................215,220,假设在区间220~230内,总共有20个点,其它点分布在其它区间内,但点数不超过20,那么我们就把220或者230作为白色部分的特征点,因为分布在它附件的最多,它最能代表白色的灰度值,反之,取黑色部分的代表点也一样,把黑色部分和白色部分的特征代表点取出来以后,取平均值作为阈值,然后二值化; 2、对于全白或者全黑,指的是在CCD有效点内,所有点灰度值都很高或者很低,这种情况只有在特定赛道,如直道或者直角黑带,当然如果你有几个CCD,最远的前瞻90+,这种情况下,远前瞻在大多数赛道下都会出现全黑,我的处理是这样的把CCD全照在黑带上,看用双峰直方图算出来的阈值,这个值会很小,因为我的CCD采集的是10位AD,,我测出的是350,所以只有当阈值大于350时我才进行接下来的搜线处理,因为用全黑的阈值处理出来的左右线,偏差都是错的,全白也一样,把CCD对着十字路口全白赛道看看阈值算出来是什么,同全黑一样处理,因为我的车用了3个CCD,所以当全黑或者全白时候,我采用的是切换前瞻巡线,优先选择最近前瞻有效的CCD巡线; 3、对于广角120度的镜头40cm前瞻下白色赛道大概占用40个点左右,CCD两边死区大概为15点左右,相当于有30个点没用,我们用的时候是当一边没有线的情况下,直接用死区边界作为CCD的某一边界,来巡线,没有补线,可以算下这个时候的偏差,可以达到25+,这个偏差已经足够让车来打角了,但是如果是90度或者71度的镜头,白色赛道上的点就占70以上,若不补线,偏差是不够让车打对应弯道的,补线的时候对于非直立车可按照固定赛道宽度来补线,但是直立车由于车角度变化,需要结合角度标定路宽,然后补线 4、十字路口,全白,一般处理是保持上次打角过去的,前提是你的车走线很流畅,进十字路口姿态好,盲跑一段也可以过去,由于我的车用的是3个CCD,前瞻分别问30,45,90,所以我能保证在十字路口,每一阶段我的车只少有一个CCD能找到正确的线; 5,对于多个CCD,除了对于特殊赛道判断外,正常跑的过程中,当三个CCD都有效的情况下,我的偏差是动态加权的,这个加权是按速度分配的,相当于我的车速度是根据赛道给定 直道,弯道,直角、单线、坡道等速度,但是我的打角是按照当前测回来的实时速度来给的,当车实时速度跑的越快时,我希望我的车看的越远越好,所以偏差有效的看的越远的CCD偏差权值给的越大,得到的偏差越大,实时速度慢的时候,远的CCD权值越小,得到的最终偏差也越小,我这样处理能保证我的车在快速和丢速的情况下,走线都很好,基本走的都是中线,不会切弯,也没见绕外环; 6、对于转向时候的微分项的处理我们用的是不完全微分,隔了4场图像,大概车走了10cm+,能够反映赛道变化 Steer_p=(1+angle*p_rate)*steer_kp;//转向P跟随角度,角度向前为负,角度越大,转向P越大 steer_d=(1+ABS(error[0]-error[4])*d_rate)*steer_kd; 转向的输出为: Steer_Value=steer_p*error[0]+steer_d*(error[0]-error[4]); 相当于P是根据角度来动态调整的,D是根据偏差变化率来动态调整的,具体调节p_rate和d_rate两个参数就可以。 欢迎兄弟院校海军工程大学过来交流!!! 武汉科技大学余义 2015年12月9日
|