一、中线提取
void get_certerline()//提取中线函数 0表示黑色,255表示白色
{
uint8 i = 0,j = 0;
uint8 middleline = 0;
for (i = 0;i < 60;i ++)//0 - 60行
{
//左边界扫描
for (j = 40; j >= 1;j --)//40-0列,不能是>=0,不然会无限循环
{
if (img[i][j] == 0)
{
Left_Black = j;
break;
}
else
{
Left_Black = 0;//未找到,取第0列第i行像素作为黑点
}
}
//右边界扫描
for (j = 41; j <= 79; j++)//41-79列,第i行第j列为黑点
{
if (img[i][j] == 0)
{
Right_Black = j;
break;
}
else
{
Right_Black = 79;//未找到,取第79列第i行像素作为黑点
}
}
middleline = (Left_Black + Right_Black) / 2;//中线上的某点
img[i][middleline] = 0;//将第i行的中线黑点写入数组,便于在oled显示中线
}
}
void MY_OLED_ShowBMP(uint8 x,uint8 y,void * picture,uint8 loca)//OLED显示图像函数
{
uint8 *buf;
uint8 x1 = 0,y1 = 0;//临时x1,y1坐标,第x1列,第y1行
uint16 count = 0;
buf = picture;//赋地址
count = x * y;
while (count --)
{
if (*buf++ == 0)
OLED_DrawPoint(x1,y1,0);//第y1行x1列写入黑色
else
OLED_DrawPoint(x1,y1,1);//第y1行x1列写入白色
if (++x1 == x)//已经写到第x列,第y1行写完
{
x1 = 0;
y1++;
}
}
}
void main(void)
{
OLED_Init();
camera_init(imgbuff);
set_vector_handler(PORTC_VECTORn , PORTC_IRQHandler); //设置 PORTA 的中断服务函数为 PORTA_IRQHandler
set_vector_handler(DMA0_VECTORn , DMA0_IRQHandler); //设置 DMA0 的中断服务函数为 PORTA_IRQHandler
while(1)
{
camera_get_img(); //通过DMA方式读取摄像头像素,每个字节8个像素
img_extract(img, imgbuff, CAMERA_SIZE); //将摄像头像素解压为每一个字节一个像素
get_centerline(); //获取中线
OLED_ShowBMP(80,60,img,24); //OLED显示图像函数
OLED_Refresh_Gram(); //OLED刷新
}
}
二、怎样计算偏差
偏差就是计算出来的中线(一般会显示在OLED上的黑线),与摄像头当前的中线(像素宽度的一半,80 * 60摄像头的中线就是40)的差值,就是车当前位置与预期位置的偏离程度