长连接摄像头可以和主板分开。比如在智能小车应用当中,摄像头安装到车头中间位置,而电路板可以放在小车的主体位置,它们之间可以通过一根很长的数据线连接。使用这种方案,可以代替这种使用2个STM32单片机:1个控制小车的移动,1个做OpenMV算法。节省了硬件电路成本和小车的空间和布线难度。最近出于爱好和工作要求,做了一个这样的项目。

在OpenMV代码中添加模拟摄像头的sensor代码,由于都是使用的DCMI接口,OpenMV sensor.c的代码大部分可以共用。注意DCMI reset和pwr_down管脚的极性,跟自己的sensor模块要匹配,不然会出现sensor timeout的错误提示。

参考OpenMV的OPENMV4P机型代码加入SDRAM支持,不然分辨率只能到QVGA320x240,因为我的板子自带了16MB的SDRAM,将omv_boardconfig.h相关的参数修改成自己板子对应的参数。比如这里sensor的时钟用的是模拟摄像头模块配的28MHZ晶振,因此不需要STM32 timer定时器或者MCO单元给sensor提供时钟,相关的代码要选择合适的宏定义取消掉。

#define OMV_XCLK_MCO (0U)
 #define OMV_XCLK_TIM (1U)
 #define OMV_XCLK_OSC (2U)
 // Sensor external clock source.
 #define OMV_XCLK_SOURCE (OMV_XCLK_OSC)

我这里的模拟摄像头支持的图片格式有:

OpenCV怎么用于单片机 opencv怎么与单片机结合_OpenCV怎么用于单片机


支持的最大分辨率为TVPAL制720x576,另外支持TVPAL分辨率以下所有的分辨率,例如常见的:VGA,QVGA,QQVGA…

模拟摄像头受限于硬件条件限制,帧率最大只能到25桢/s,720x576像素分辨率。实际情况由于OpenMV使用STM32的DCMI Snapshot快照模式,分辨率最大只能到12.5桢/s,这里可以通过在分辨率小于VGA的时候,比如QVGA分辨率的情况下,每次取半场PAL制的图片720x288截取到320x240 QVGA分辨率,可以将帧率提升到25桢以上。相对来说,25桢的帧率用于OpenMV图像处理也是足够的了。

添加和修改代码,我这里考虑到后期OpenMV固件升级的需要,尽可能的在原有的代码的基础上增加代码,而没有删除或者改变原有代码的结构。

后期将推出基于RT thread操作系统的实现,RT thread+Micropython+OpenMV,并实现使用USB摄像头的实现方法。总的来说USB摄像头能够达到和DCMI连接 OV7725一样的效果,比模拟摄像头效果要更好。并且RT thread使用scons和Kconfig配置模块,可以支持很多的开源组件以及对物联网更好的支持。代码之间的模块化分层设计做得很优秀,并且支持Keil MDK、IAR、GCC 3种编译环境无缝切换。

# Untitled - By: chummyhe - 周一 五月 11 2020

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.YUV422)
sensor.set_framesize(sensor.TVPAL)
sensor.skip_frames(time = 2000)

clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
print(clock.fps())

抓取到的图片:

OpenCV怎么用于单片机 opencv怎么与单片机结合_帧率_02


Canny边缘检测:

# Edge detection with Canny:
#
# This example demonstrates the Canny edge detector.
import sensor, image, time

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.RGB565
sensor.set_framesize(sensor.QVGA) # or sensor.QVGA (or others)
sensor.skip_frames(time = 2000) # Let new settings take affect.
sensor.set_gainceiling(8)

clock = time.clock() # Tracks FPS.
while(True):
    clock.tick() # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot() # Take a picture and return the image.
    # Use Canny edge detector
    img.find_edges(image.EDGE_CANNY, threshold=(50, 80))
    # Faster simpler edge detection
    #img.find_edges(image.EDGE_SIMPLE, threshold=(100, 255))
    print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while

运行结果:

OpenCV怎么用于单片机 opencv怎么与单片机结合_帧率_03