搜索
bottom↓
回复: 60

基于STM32与OV7670的简陋型光流模块

  [复制链接]

出0入0汤圆

发表于 2015-10-10 11:59:27 | 显示全部楼层 |阅读模式
本帖最后由 lcw_swust 于 2015-10-10 15:42 编辑

首先上传电路和程序:


还有两个VB上位机用于调试:


---------------------------------------------------------------------------------------------
简介:
此模块是利用STM32F103CBT6驱动OV7670摄像头模组,可作简单的图像处理,打算用于四轴飞行器的悬停。
实际应用中可能会不理想,假如环境太单调,那效果就不好。
听说PX4FLOW做得挺好,查了下好像挺贵。
---------------------------------------------------------------------------------------------
OV7670驱动原理:
电源(DOVDD,AVDD)为2.5V左右(HT7333输出串1N4148降压,因为我没有HT7325),
DVDD采用OV7670内部的LDO(1.8V),外部只需接一只电容.
单片机为STM32F103CBT6,采用HSI时钟,PLL倍频到64MHz,可省去外部晶振.
由于只需要处理灰度图像,OV7670配置为YUV格式,Y在前,
TIM4_CH1的捕获分频设置为2分频,就可以只采集Y(亮度).
TIM3_CH3产生XCLK,(16MHz对应VSYNC约20HZ,实测最低约8MHZ)
TIM4_CH1检测PCLK(4MHz),下降沿捕获,滤波为1,二分频,触发DMA,采集PA0~PA7的数据至数组DMA_Buf.
TIM3_CH4检测VSYNC,下降沿捕获中断,控制DMA的关与开.
HREF忽略.

引脚连接:
PA12:                        LED
PA0~7:                        OV7670_D0~D7
PB0(TIM3_CH3):        OV7670_XCLK
PB1(TIM3_CH4):        OV7670_VSYNC
PB2:                        OV7670_RST
PB7(TIM4_CH2):        OV7670_HREF(可省略)
PB6(TIM4_CH1):        OV7670_PCLK
PB10:                        OV7670_SIO_C
PB11:                        OV7670_SIO_D
PB12:                        OV7670_PWDN

建议:
        为加快速度,SIO_C与SIO_D可加外部上拉电阻

注意:
        看了下SCCB时序,貌似与IIC略有区别,指定地址读数据时:
        OV7670:        ...IICWByte(add);IICACK(0);IICEnd();IICStart();...
        普通IIC:...IICWByte(add);IICACK(0);         IICStart();...
---------------------------------------------------------------------------------------------
图像处理:
上次图像中部区域(按STEP间隔)存入数组MID_Buf,在当前采集的
图像中遍历,寻找差值最小的位置,从而得到座标增量。

程序中配置摄像头为YUV格式,窗口为160*80像素,得到80*80的Y(亮度)数据;
中心区为40*40像素,STEP设置为5,也就成了8*8的稀疏点阵,处理一幅图像大约耗时45ms.
(由于接收图像还需要时间,所以程序中约100ms处理一次)
程序经KEIL3编译后:Code=12054 RO-data=358 RW-data=48 ZI-data=8608;
可以看出代码量和内存消耗都不大。

图像处理核心算法:
(注意,由于二维数组访问速度较低,真实的代码略有优化,详见附件)
  1. //--------------------------------------------------
  2. //变量定义
  3. //--------------------------------------------------
  4. U8         DMA_Buf[CAMHEIGHT][CAMWIDTH];//本次采集的摄像头数据
  5. U8         MID_Buf[MIDHEIGHT][MIDWIDTH];//上次中部区域的数据
  6. //--------------------------------------------------
  7. //计算差值的绝对值
  8. //--------------------------------------------------
  9. __INLINE U8  caldif(U8 v1,U8 v2)
  10. {
  11.         if(v1>v2)return v1-v2;
  12.         return v2-v1;
  13. }
  14. //--------------------------------------------------
  15. //图像处理:用上次图像中部区域去与当前采集图像(从x,y
  16. //开始的区域)求差,寻找差值最小的位置,
  17. //从而得到x增量(MovIncX)与y增量(MovIncY)
  18. //--------------------------------------------------
  19. void PicProcess(void)
  20. {
  21.         U16 i,j,x,y;
  22.         U32 dif,min=0xffffffff;        //差值,最小值
  23.         U16 minx,miny;                        //最小值处的左上角座标
  24.         //--------遍历整个当前图像,查找与之前中部图像相差最小的位置       
  25.         for(y=0;y<CAMHEIGHT-MIDHEIGHT;y++)//从上到下
  26.         {
  27.                 for(x=0;x<CAMWIDTH-MIDWIDTH;x++)//从左到右
  28.                 {               
  29.                         dif=0;//误差清0                       
  30.                         for(i=0;i<MIDHEIGHT;i+=STEP)
  31.                         {
  32.                                 for(j=0;j<MIDWIDTH;j+=STEP)
  33.                                 {//计算当前图像中的点与上次图像中部区域的点的差值
  34.                                         dif+=caldif(DMA_Buf[y+i][x+j],MID_Buf[i][j]);//误差累加       
  35.                                 }
  36.                         }
  37.                         if(min>dif)//误差小于当前最小值,则记最小值为当前值,且记下座标
  38.                         {
  39.                                 min=dif;
  40.                                 minx=x;
  41.                                 miny=y;
  42.                         }
  43.                 }
  44.         }
  45.         //------------------------------计算座标增量
  46.         if(min>30000)min=30000;//此句可省,是为了便于串口发送该值
  47.         if(min<15*(MIDHEIGHT/STEP)*(MIDWIDTH/STEP))//允许平均每个点15的误差
  48.         {
  49.                 MovIncX=minx-MIDX;//x增量
  50.                 MovIncY=miny-MIDY;//y增量
  51.                 MovX+=MovIncX;//模拟成鼠标的绝对座标,便于查看
  52.                 MovY+=MovIncY;       
  53.                 if(MovX<-1000)MovX=-1000;//限幅
  54.                 if(MovX>1000)MovX=1000;       
  55.                 if(MovY<-1000)MovY=-1000;
  56.                 if(MovY>1000)MovY=1000;
  57.         }       
  58.         //------------------------------复制当前中部区域
  59.         for(i=0;i<MIDHEIGHT;i+=STEP)
  60.         {
  61.                 //memcpy(MID_Buf[i],DMA_Buf[MIDY+i]+MIDX,MIDWIDTH);
  62.                 for(j=0;j<MIDWIDTH;j+=STEP)
  63.                 {
  64.                         MID_Buf[i][j]=DMA_Buf[MIDY+i][MIDX+j];                       
  65.                 }
  66.         }
  67.         //------------------------------串口查看误差与座标
  68.         UART1_SendByte(0xaa);
  69.         UART1_SendByte(6);       
  70.         UART1_SendByte(min>>8);
  71.         UART1_SendByte(min);                       
  72.         UART1_SendByte(MovX>>8);
  73.         UART1_SendByte(MovX);       
  74.         UART1_SendByte(MovY>>8);
  75.         UART1_SendByte(MovY);
  76. }
复制代码


下面是一些照片:
模块电路和照片:








将采集的图像发送出来用上位机查看:

将误差和座标发送出来用上位机查看:

8*8点阵去匹配当前图像的效果图,为避免GIF太大,只做了前5行的效果:

发送座标时的GIF图:


---------------------------------------------------------------------------------------------
补充一下:
测了下工作电流,约47mA
“处理一幅图像大约耗时10ms",这里写错了,应为45ms.
忘了传OV7670的资料了:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2015-10-10 12:09:21 | 显示全部楼层
做的不错,学习了

出0入134汤圆

发表于 2015-10-10 12:23:54 | 显示全部楼层
不明觉厉

出0入0汤圆

发表于 2015-10-10 12:35:07 | 显示全部楼层
好棒

出0入0汤圆

发表于 2015-10-10 13:01:07 | 显示全部楼层
楼主V5,标记一下。

出0入0汤圆

发表于 2015-10-10 13:59:43 | 显示全部楼层
先收藏了,谢谢楼主

出0入0汤圆

发表于 2015-10-10 14:00:20 | 显示全部楼层
牛X啊。。。

出0入0汤圆

发表于 2015-10-10 14:11:49 | 显示全部楼层
可以测移动方向,但没加测距的无法实现测量位移距离吧

出0入0汤圆

 楼主| 发表于 2015-10-10 14:38:10 | 显示全部楼层
ICPACHONG 发表于 2015-10-10 14:11
可以测移动方向,但没加测距的无法实现测量位移距离吧

是啊,所以一般要配合超声波模块。

出0入0汤圆

发表于 2015-10-10 14:42:57 | 显示全部楼层
lcw_swust 发表于 2015-10-10 14:38
是啊,所以一般要配合超声波模块。

这个程序很有参考价值,感谢分享

出0入0汤圆

发表于 2015-10-10 15:03:53 | 显示全部楼层
STM32与OV7670的简陋型光流.可以配个超声波定高

出0入0汤圆

发表于 2015-10-10 15:47:44 | 显示全部楼层
很不错,我们之前使用过鼠标芯片来做光流。有些鼠标芯片还提供了初始化固件,让里面的DSP能有光流的算法处理。

出0入0汤圆

发表于 2015-10-10 17:53:41 | 显示全部楼层
涨姿势了!!


出0入0汤圆

发表于 2015-10-10 18:01:32 | 显示全部楼层
强帖,学习!

出0入0汤圆

 楼主| 发表于 2015-10-13 16:00:17 | 显示全部楼层
这两天找了下BUG:
MIDHEIGHT/STEP应改为(MIDHEIGHT+STEP-1)/STEP,宽度的同理
y<CAMHEIGHT-MIDHEIGHT应改为y<CAMHEIGHT-MIDHEIGHT+1,x同理
DMA可以一直工作不需停止.
OV7670的配置略有改动.
目前遗留的问题:
OV7670易丢帧(有VSYNC但无PCLK),特别是在光线剧烈变化的时候,估计是配置的问题

上位机改用C++builder编写,能支持更高的波特率,因为VB太过占用CPU。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出20入62汤圆

发表于 2015-10-20 20:09:19 | 显示全部楼层
这个厉害。stm32 ov7670 跟随电路 mark

出0入8汤圆

发表于 2015-10-20 21:44:03 | 显示全部楼层
非常好,无敌了

出0入0汤圆

发表于 2015-10-20 22:04:48 | 显示全部楼层
楼主太牛了

出0入0汤圆

发表于 2015-10-20 22:51:48 | 显示全部楼层

楼主学习了 自制PCB很棒

出0入0汤圆

发表于 2015-10-20 23:40:45 来自手机 | 显示全部楼层
牛!强力顶起!支持开源

出0入0汤圆

发表于 2015-10-21 00:11:40 | 显示全部楼层
楼主霸气,前几天也是和楼主的想法相近,我的想法是stm32采集视频数据,然后将采集的数据发送给FPGA用于进行图像处理原本想做70帧最有改到30帧,还是苦于不知传输速率如何解决一直没开工,楼主有何见解可以给讲讲吗

出0入0汤圆

发表于 2015-10-21 08:28:03 | 显示全部楼层
用407或者427不是更方便

出0入0汤圆

发表于 2015-10-21 08:49:38 | 显示全部楼层
不错,图片里的是楼主吗?

出0入0汤圆

 楼主| 发表于 2015-10-21 09:05:35 | 显示全部楼层
ZYBing 发表于 2015-10-21 08:49
不错,图片里的是楼主吗?

是啊,相素较低,看起来没那么帅

出0入0汤圆

发表于 2015-11-2 15:12:38 | 显示全部楼层
很不错!

出0入0汤圆

发表于 2015-11-10 09:05:53 | 显示全部楼层
厉害!              

出0入0汤圆

发表于 2015-11-10 09:12:59 | 显示全部楼层
楼主很厉害呀

出0入0汤圆

发表于 2015-11-10 09:34:10 | 显示全部楼层
做的不错,支持一个

出0入0汤圆

发表于 2015-11-15 10:52:16 | 显示全部楼层
做的不错,学习了

出0入0汤圆

发表于 2015-11-17 17:08:49 | 显示全部楼层
正在找相关的资料,谢谢楼主

出0入0汤圆

发表于 2015-11-17 18:06:01 来自手机 | 显示全部楼层
做的不错 多谢楼主分享~

出0入0汤圆

发表于 2015-12-25 11:33:22 | 显示全部楼层
串口呢?

出0入0汤圆

 楼主| 发表于 2015-12-25 12:05:46 | 显示全部楼层

若想达到高于115200的波特率,建议用USB转TTL模块。

出0入0汤圆

发表于 2015-12-25 16:50:35 | 显示全部楼层
做的不错,学习学习!!

出0入0汤圆

发表于 2015-12-25 18:19:18 来自手机 | 显示全部楼层
学习学习!

出0入0汤圆

发表于 2016-1-15 11:57:14 | 显示全部楼层
楼主板子做得非常漂亮。好玩的东西。

出0入0汤圆

发表于 2016-1-18 02:04:49 来自手机 | 显示全部楼层
好东西啊,学习学习

出0入0汤圆

发表于 2016-1-19 16:13:10 | 显示全部楼层
本帖最后由 黄瓜 于 2016-1-19 16:14 编辑

楼主做得不错。
可以考虑移植下APM的光流算法。

出0入0汤圆

发表于 2016-1-21 09:10:39 | 显示全部楼层
好呀,研究的很透彻,说明的清晰,好资料,当时要是能看到,OV7670也不至于摆弄那么长时间了

出0入0汤圆

发表于 2016-1-21 21:03:11 | 显示全部楼层
不错,楼主可以外接一个晶振,倍频到128M试一试呀,主频提高一倍,处理速度和响应速度就快了一倍,效果应该会更好些!

出0入0汤圆

发表于 2016-1-22 16:14:17 | 显示全部楼层
学习中,有应用前景。

出0入0汤圆

发表于 2016-3-3 22:14:11 | 显示全部楼层
楼主牛人!!!!

出0入0汤圆

发表于 2016-5-14 13:11:15 | 显示全部楼层
我的天哪,都可以做成武器的自动瞄准了,厉害!!

出0入0汤圆

发表于 2016-6-17 09:25:10 | 显示全部楼层
学习中,有应用前景。

出0入0汤圆

发表于 2016-7-18 20:17:36 | 显示全部楼层
太牛了!!!

出40入514汤圆

发表于 2016-7-25 20:35:15 | 显示全部楼层
牛人mark一个

出0入0汤圆

发表于 2016-7-25 20:56:25 | 显示全部楼层
标记,以后有可能用到

出0入0汤圆

发表于 2016-8-9 08:45:21 | 显示全部楼层
做的非常好,谢谢分享

出0入0汤圆

发表于 2016-8-30 09:58:48 | 显示全部楼层
从楼主发帖,回复,制板和焊接看出,楼主大牛,很严谨的一个人

出0入0汤圆

发表于 2016-11-12 23:02:36 | 显示全部楼层
夹子很强大。。。

出0入0汤圆

发表于 2016-11-14 09:26:26 | 显示全部楼层
很强大,牛人一个

出0入0汤圆

发表于 2016-11-15 11:10:18 | 显示全部楼层
不错很好的东西

出0入0汤圆

发表于 2016-11-15 13:23:31 | 显示全部楼层

不错很好的东西

出0入0汤圆

发表于 2016-11-15 18:01:46 | 显示全部楼层
顶楼主,很好的东西

出0入21汤圆

发表于 2016-11-15 20:01:36 | 显示全部楼层
牛!建议搞个套件出来,大家一起整整

出0入0汤圆

发表于 2016-11-15 20:25:27 | 显示全部楼层
厉害了楼主,谢谢分享。

出0入0汤圆

发表于 2017-12-15 14:32:21 | 显示全部楼层
学习一下,也做一个

出0入0汤圆

发表于 2018-5-6 20:45:20 | 显示全部楼层
大神,太厉害了。

出0入0汤圆

发表于 2018-5-12 20:42:13 | 显示全部楼层
学习了。谢谢。

出0入0汤圆

发表于 2019-10-14 17:53:49 | 显示全部楼层
这个要给赞,真的太牛了。

出0入0汤圆

发表于 2021-5-14 07:57:27 | 显示全部楼层
学习一下,LZ厉害
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 23:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表