上一篇博文我简单论述了Freescale光电组传感器——线性CCD的曝光与采集,那在对赛道的路面信息处理中,大多有两种算法:凹槽法,可详见上海交大的技术报告与论文;更常见且本人采取的做法是软件二值化。
大家知道,线性CCD一个曝光周期只能采集视野范围内一条线的信息,即128个像素信息。我们通过AD采样获取的数据其实是通过运算电路得到的像素点的电压值,是一个数值。通过采样函数ImageCapture(Pixel)将一个曝光周期内采集到的128个像素点的电压值寄存到位长128的数组Pixel[i]中,从而用于计算与数据处理。在128个像素点的信息中,光线越强的点电压值越高,越弱的点电压值越低。针对赛道来说,CCD采集到白色的赛道部分电压值较高,我们认为是区域白电平;赛道两边的黑线以及黑线外的深蓝色背景光线暗,电压值低,即暗电压。由此我们可以区分赛道与边界,通过寻找赛道两边的黑线位置,计算赛道中间位置,让小车近似循中线行进。
引出本文重点内容——二值化与动态阈值。对于CCD来说,黑与白的电压差是很大的。下图显示的是反映在上位机中CCD采集的一个画面。中间的凹槽表明在视野的那个位置有一个黑色区域。
实际赛道黑色与白色部分的电压差值比上图要大许多,如果我们找到白电压与黑电压数值上的一个合适的中间值作为阈值,高于此阈值的像素点电压一律拉高到250(250数值根据上位机显示设置),低于此阈值的像素点电压一律置0,那么画面中的数据只有两个值,会产生明显的黑白电压跳变沿,这样只要找到两边的跳变沿,就可以确定黑线位置,从而计算出赛道中值。这就是二值化的基本原理与用法。
二值化的数据处理不难,难在找到一个合适的阈值。首先要保证黑白电压的差值要很明显,通过更改曝光时间,加偏振片可以一定程度改变电压的差距。我个人还用了一个方法。在上一篇博文里我介绍的采样函数中有这一条采样语句:
temp_int = AD_Measure12(0);
*ImageData++ =(byte)(temp_int>>4);
我们把第二句改成这样:
*ImageData++ = k* (byte)(temp_int>>4); 加上系数k,黑白电压的数值都乘上一个合理的系数,在保证图像清晰的前提下可以黑白电压的差值也相应增大,这样也扩大了我们可寻找的阈值范围,避免了出现阈值离黑白电压的上下限太近,二值出现紊乱的情形。
现在有以下三种方法确定阈值:
1、固定阈值
在黑白电压值得较稳定,浮动范围很小的情况下,如白电压始终在170上下极小的范围内浮动,黑电压在50左右稳定,此时阈值可选范围很大,我们随机取一个100或120都是没问题的。但很多CCD存在畸变,视野两侧的电压始终很低,而且有时考虑到CCD视角的变化(如更改前瞻,焦距),图像的波动可能也会较大,用以下两种方法可能更实用。
2、取平均电压值作阈值
我们计算出128个像素点电压的平均值,取此值作为二值化的阈值,可以增强环境的适应性,哪怕黑白电压的门限不断变化,有一定的波动,或者光线略有不均,此方法都还比较凑效。
3、计算max与min的均值作阈值
我们对128个像素点做排序,取出电压最大与最小的两个像素点的电压值,取二者的平均值作阈值,事实证明效果也还是可以的,本人在安徽赛区的赛场上用的就是这个方法。但是考虑到比赛赛场上的光线过强,加上CCD畸变的影响,即使加上偏振片,得到的图像可能仍不理想,如下: