飞卡日常进度之鹰眼OV7725的深入熟悉及数据处理

恶补了前面有了基础知识的储备,这下摄像头的征程也就好走了点。


1、鹰眼特性了解

  • 鹰眼不是隔行扫描!
  • 鹰眼速率可达 150 帧每秒!
  • 三十万像素!
  • 硬件二值化摄像头,直接输出二值化图像,一次传输 8 个像素,相比与黑白摄像头一次传输一个像素快 8 倍、彩色摄像头两次传输一个像素快 16 倍。
  • 假设黑白摄像头每秒传输 30 帧,同样的数据线总线频率下,则野火鹰眼对应的速度是
    30 帧8=240 帧……
    假设彩色摄像头每秒传输 30 帧,同样的数据线总线频率下,则野火鹰眼对应的速度是
    30 帧
    16=480 帧……
  • 8 位数据线一次传输 8 个像素,ov7725 的图像像素先输出则在高位,后输出则低位。

飞卡日常进度之鹰眼OV7725的深入熟悉及数据处理_第1张图片

飞卡日常进度之鹰眼OV7725的深入熟悉及数据处理_第2张图片
2、鹰眼时序图

飞卡日常进度之鹰眼OV7725的深入熟悉及数据处理_第3张图片

HREF 和 HSYNC 都用于行中断信号,但时序有点区别。
HREF 上升沿就马上输出图像数据,而 HSYNC 会等待一段时间再输出图像数据,如果行中断里需要处理事情再开始采集,则显然用 HREF 的上升沿是很容易来不及采集第一个像素。

飞卡日常进度之鹰眼OV7725的深入熟悉及数据处理_第4张图片

3、图像采集思路

①使用 for 循环延时采集

  • 需要采集图像时,开场中断
  • 场中断来了就开启行中断,关闭场中断
  • 行中断里用 for 循环延时采集像素,可以在行中断里添加标志位,部分行不采集,
    即可跨行采集。
  • 行中断次数等于图像行数时即可关闭行中断,标志图像采集完毕。

(这种方法是最简单,最多人用,但也是采集图像最不稳定的方法,经常出现消隐区等问题。)

伪代码

  //for 循环延时采集,都是在行中断里采集一行数据
  void Hisr()
  {
	  static uint16 Hn=0; //正在采集的行数
	 
	  //行中断来了延时一下,跳过消隐区
	  DELAY_A();
	  for(i=0;i<每行元素数目;i++)
	  {
		  //采集图像值,并保存在对应的内存数组里
		  port2buff(Hn++,i);
		 
		  //单片机速度较快时,如果不加延时,那么很有可能同一个像素
		  //值采集多次,而且图像右边的像素没采集到,即会出现图像中心偏右。
		  DELAY_B();
	  }
	  Hn++;
  }

② 使用场中断和行中断,DMA 传输

  • 需要采集图像时,开场中断
  • 场中断来了,开行中断和初始化 DMA 传输
  • 行中断来了就设置 DMA 地址,启动 DMA 传输。如果先过滤部分行不采集,则设
    置一个静态变量,每次行中断来了都自加 1,根据值来选择采集或不采集某些行。
  • 每个 PCLK 上升沿来了都触发 DMA 传输,把摄像头输出的值读取到内存数组里。
    当触发 n 次(n=图像列数目)后就停止 DMA 传输。
  • 行中断次数等于一幅图像的行数,或者等待下一个场中断来临 就结束图像采集,
    关闭行中断和场中断。

(如果不用 DMA 传输,则直接用 for 循环加延时来采集就好,PCLK 也不需要用。不过延时值需要设置合适,不然要不就采集到消隐区,要不就只采集图像的左边部分。)

③ 使用场中断,DMA 传输

  • 需要采集图像时,开场中断
  • 场中断来了,初始化 DMA 传输,并启动 DMA 传输
  • 每个 PCLK 上升沿来了都触发 DMA 传输,把摄像头输出的值读取到内存数组里。
    当触发 n 次(n=图像像素数目)后就停止 DMA 传输。
  • DMA 停止传输时触发中断,中断里关闭场中断,图像采集完毕。
    或者等待下一个场中断来临才关闭场中断,标记图像采集完毕

不使用行中断信号,直接 DMA 模块计数来完成一场结束的判断。

4、SCCB

SCCB 是 ov 系列摄像头的控制信号通信的协议,兼容 I2C 协议,与 I2C 协议唯一不同
的是 SCCB 在读时,增加一个总线停止条件(SCCB 信号线需要接上拉电阻,理由与 I2C 一
样)。
ov 系列摄像头的寄存器是 EEPROM,不稳定,数据容易丢失,因此程序每次初始化时
都重新写入寄存器配置。

ov 系列摄像头通常都是配置好默认的参数,但特定的场合需要特定的配置,因此有必
要学习 SCCB 控制摄像头,从而发挥摄像头的最大采集效果。

常见需要修改的寄存器有,PCLK 速率,帧率、图像亮度、对比度、色饱和度、镜像等
功能。

学习方法,一是可以参考山外的例程进行,另外发现一个CSDN大神的博客,也可以参考。<传送门>

5、常见问题汇总

①、 图像分成上下两幅图图像

没处理好场中断信号: 不根据场中断信号来了才开始每帧的采集,就会出现采集到一幅
图片里由上下两幅图片组成:上半幅图是前一帧图像的底部,下半幅图是这帧的顶部图像。
或者场中断来了后,先处理太多东西,然后才开始采集,导致跳过了开头的数据,后续
采集的时候又根据采集的行数来判断是否停止采集,就好采集到下一幅图像的开头

参考帖子:
http://www.znczz.com/forum.php?mod=viewthread&tid=98576
http://www.znczz.com/forum.php?mod=viewthread&tid=24642

②、图像 分成左右两半图像,左 半幅图 是右 半幅图的右边图像。
没处理好行中断,可能行中断来了后处理太多东西才开始采集,然后还是采固定的点数。

③、图像分成左右两半相同的图片,而 图像分成左右两半相同的图片,而 且中间有消隐区
读取行的数目太多,或者中间延时太久,导致读取一行变成的读取两行

参考帖子:
http://www.znczz.com/forum.php?mod=viewthread&tid=98767
http://www.znczz.com/forum.php?mod=viewthread&tid=97071

④、 图像采集没居中,图像中心偏左或偏右了

排除摄像头镜头歪了,或者摄像头芯片焊接歪了的硬件问题外,一般情况下是出现在用
for 循环延时采集上。

  //for 循环延时采集,都是在行中断里采集一行数据
  void Hisr()
  {
	  static uint16 Hn=0; //正在采集的行数
	 
	  //行中断来了延时一下,跳过消隐区
	  DELAY_A();
	 
	  for(i=0;i<每行元素数目;i++)
	  {
		  //采集图像值,并保存在对应的内存数组里
		  port2buff(Hn++,i);
		 
		  //单片机速度较快时,如果不加延时,那么很有可能同一个像素
		  //值采集多次,而且图像右边的像素没采集到,即会出现图像中心偏右。
		  DELAY_B();
	  }
	 
	  Hn++;
  }

如果 DELAY_A()延时值过大,图像左边的部分像素就没采集到,图像中心偏左。
如果 DELAY_A()延时值过小,图像左边就会出现消隐区。HREF 上升沿触发 行中断 就
不需要添加添加 DELAY_A()延时值。

如果 DELAY_B()延时值过大,右边图像就会出现消隐区。当不添加 DELAY_B()还是出
现右边有消隐区时,说明单片机速度太慢,每行采集像素数目太多,可以减少每行采集的数目。
如果 DELAY_B()延时值过小,右边图像没采集到,图像中心偏右

每行元素数目过大,即上面所说的出现右边有消隐区情况。
每行元素数目过小,显然采集图片太窄,影响路况识别。

参考帖子:
http://www.znczz.com/forum.php?mod=viewthread&tid=98644

⑤、图像有四个角落有阴影

镜头与芯片没对正中心,或者芯片焊接歪了。

参考帖子:
http://www.znczz.com/forum.php?mod=viewthread&tid=96179

你可能感兴趣的:(#,飞思卡尔比赛留念)