系列链接:
- 十三届智能汽车竞赛 信标对抗组 思路参考 程序参考(一)模块初始化
- 十三届智能汽车竞赛 信标对抗组 思路参考 程序参考(二)图像处理
- 十三届智能汽车竞赛 信标对抗组 思路参考 程序参考(三)寻灯策略Part.①
- 十三届智能汽车竞赛 信标对抗组 思路参考 程序参考(四)寻灯策略Part.②
- 十三届智能汽车竞赛 信标对抗组 思路参考 程序参考(五)分段控速
- 十三届智能汽车竞赛 信标对抗组 思路参考 程序参考(六)避障
正文开始:
这次更新图像处理部分,主要是为了从摄像头采集的信息中提取出信标灯,并求出信标灯在图像中的坐标。程序代码可完善的地方还有很多,主要还是提供一种当时我们参赛的解决思路,抛砖引玉。
- 摄像头采用中断的方式来采集图像,现在有新版的摄像头配置起来应该比较方便。当时我们使用的某厂的OV7725摄像头采集图像就比较麻烦了,除了场中断外,还需要配置行中断。行中断即为每采集一行像素触发的中断,场中段即为每采集一幅完整的图像触发的中断。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28/************************摄像头中断***************************/ void PORTE_IRQHandler() { if(PORTE_ISFR & 0x1000000) //PTC16触发中断,采集的行中断 { PORTE_ISFR |= 0x1000000; //写1清中断标志位 DMA_DADDR(DMA_CH4) = (uint32_t )&ADdata[LinADCout][0]; //数据存储地址变化 dlay();//摄像头行中断改为下降沿触发,有效点前面有一段行消隐区,故需要一段延时消除消耗掉,该处的时间,程序里面的需要根据单片机的主频调整。 DMA_EN(DMA_CH4); //使能通道CHn 硬件请求 (这样才能继续触发DMA传输) LinADCout ++; LinCout ++; if(LinADCout == DATALINE) { LinADCout=0; DMA_Over_Flg = 1; } } if(PORTE_ISFR & 0x2000000) //PTC17触发中断,采集的场中断。 { PORTE_ISFR |= 0x2000000; //写1清中断标志位 LinCout = 0; LinADCout=0; Sample_Flag=1; gpio_Interrupt_init(PTE24, GPI_DOWN,RING) ; //开启行中断 PORTE_ISFR |= 0x1000000; //写1清中断标志位 } }
- 然后要解压图像:众所周知,硬件二值化的OV7725摄像头返回的图像中各个像素点的值只有二进制的0或1,但是这款摄像头并不返回一个我们能直接使用的图像矩阵,它返回的是一长串的十六进制数据,因此我们需要把这些数据解析成我们所需要的图像矩阵。假设设置摄像头采集图像的尺寸为W×H,那么这款摄像头采集完一幅完整的图像总共会返回W/8×H个十六进制数据,每一个十六进制数据包含八个二进制数,正是图像同一行中连续八个点的像素值。这样我们的解压方式就很明晰了,只需要将十六进制的每一位按顺序取出,赋值给一个定义好的W×H的二维图像矩阵即可。具体的操作如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18/************************解压图像***************************/ void Image_JIEYA(uint8 *data1,uint8 *data2) //data1为原始的十六进制数据,data2为定义好的W×H的二维图像矩阵 { uint8 temp[2] = {0,255}; int lenth = 600; //设置的图像尺寸为80×60,即共有 W/8×H = 80/8×60 = 600 个十六进制数据 uint8 i = 8; while(lenth--) { i = 8; while(i--) { *data2++ = temp[(*data1 >> i) & 0x01]; //移位并按位与0x01 } data1++; } }
- 有了图像矩阵之后,就可以进行处理了,最终找出信标灯中心在画面中的坐标。信标灯在亮起时会以一定频率闪烁,发出一定频率范围的红光和红外光。摄像头镜头使用了红外滤光片,环境光线比较好的情况下,当信标灯亮起时,其红外光能够很明显在图像上显示为一个光斑,我们则通过逐行扫描图像矩阵的方式来求出这个光斑在画面中的像素坐标,具体操作如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45/************************找坐标***************************/ void find_LR(void) { unsigned int i,j; unsigned char lside=80,rside=0; for(i=0;i<DATALINE;i++) { lside=80,rside=0; for(j=0;j<80-1;j++) { if(!image_dec[i][j]&&!image_dec[i][j+1]) //同一行中连续两个像素点亮 { if(lside==80) lside=j; //定左边缘 rside=j+1; //定又边缘 } } if(lside<rside) PianCha[i]=(lside+rside)/2; //最大为80 else PianCha[i]=0xff; } } void find_XY(void) { int i=0,k=0,p=0,g=0,m=0,q=0; float Xx=0; for(i=0;i<DATALINE-1;i++) { if((PianCha[i]!=0xff)&&(PianCha[i+1]!=0xff)) //连续四个点表示确定为信标灯而不是噪点 { if(g==0) { k=i; g=1; } if(m==0) p++; } else if(g==1) m=1; } for(q=0;q<p-1;q++) Xx+=PianCha[k+q]; x_MID=Xx/(p-1); y_MID=(k+(p>>1)); //右移一位相当于除以二 而运算速度更快 }
- 在某些光线条件比较差(比如存在阳光、带红外光的灯管等)的情况下,阳光中有红外光的分量,带红外光的灯管直接发出红外光。图像中的光斑就不仅仅是信标灯发出的红外光了了,恶劣时甚至被大片的光干扰淹没,此时想要克服或者减弱这个影响,就需要利用到一个点:信标灯的红外光是以一定频率闪烁的而其他的红外光是常亮的。利用这个特性,可以对相邻的或一定帧间隔内的两张或多张图像之间做 差 或者做 异或 操作,能将常亮的红外光滤除掉,信标灯又能清晰的出现在图像中了:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/************************闪烁识别***************************/ void SHANSHUOSHIBIE(void) { int q,w; Image_Decompression((uint8 *)ADdata,(uint8 *)image_dec[0]); //解压图像 if(shan>0) { shan=0; for(q=0;q<60;q++) { for(w=0;w<80;w++) { shanshuo[q][w]=copy[q][w]^image_dec[q][w]; //两幅图像对应位置像素异或操作 copy[q][w]=image_dec[q][w]; } } } shan++; }
---------------------
作者:ZZM丶
来源:CSDN
原文:https://blog.csdn.net/qq_41833526/article/details/109445998
最后
以上就是顺心滑板最近收集整理的关于[转]十三届智能汽车竞赛 信标对抗组 思路参考 程序参考(二)图像处理()的全部内容,更多相关[转]十三届智能汽车竞赛内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复