OpenMV在使用过程中可能会遇到光照太强或者光照太弱等影响图像识别的情况,尤其在跑神经网络模型时,光照太强或太弱对识别结果的影响是致命的。
针对光照过强这一影响因素,可以通过调节摄像头的初始参数来解决。比较常用的摄像头参数如下:
sensor.reset() # 初始化相机传感器
sensor.set_pixformat(sensor.RGB565) # 设置像素模式
sensor.set_framesize(sensor.QVGA) # 设置分辨率
sensor.skip_frames(time = 200) # 跳过20毫秒的帧
sensor.set_auto_gain(True) # 打开自动增益, 默认打开;追踪颜色,则需关闭白平衡。
sensor.set_auto_whitebal(True) # 打开(True)或关闭(False)自动白平衡。默认打开;追踪颜色,则需关闭白平衡
sensor.set_auto_exposure(True) # 打开(True)或关闭(False)自动曝光。默认打开。
上述设置为比较基本的参数初始化方法,但针对光照过强的影响,可以通过改变以下三个参数来解决:
sensor.set_contrast(constrast) # 设置相机图像对比度。-3至+3。
sensor.set_brightness(brightness) # 设置相机图像亮度。-3至+3。
sensor.set_saturation(saturation) # 设置相机图像饱和度。-3至+3。
通过固定相机图像的对比度、亮度和饱和度,基本可以保证在一定光照变化范围内,相机拍摄的图像的质量是相差无几的,即可以解决光照过强对OpenMV图像识别的影响。
当环境光照过弱时,只通过固定相机图像的对比度、亮度和饱和度并不能解决问题,此时需要通过人工增加光照,并且还要固定相机图像的对比度、亮度和饱和度。
人工增加光照可以通过外加上图所示的LED灯带来实现,但外加LED灯带还需要额外给LED灯带的供电,且外加的LED灯带通常需要8-12V的电压来供电。常出现的问题是灯带的位置不好确定且供电电压不易寻找。
OpenMV自身有四个LED灯,分别为红灯、绿灯、蓝灯和白灯,其中白灯的亮度可以应对一般的光照过弱场景,因此可以使用OpenMV自带的白色LED灯来增加光照,既不需要改变结构又不需要额外的供电电压。
import pyb
from pyb import LED #导入LED
red = LED(1) # 定义一个LED1 红灯
green = LED(2) # 定义一个LED2 绿灯
blue = LED(3) # 定义一个LED3 蓝灯
white = LED(4) # 定义一个LED4 照明灯
while(True):
red.on() # 打开红灯
pyb.mdelay(500) # 延时500ms
red.off() # 关闭红灯
pyb.mdelay(500)
green.on()
pyb.mdelay(500)
green.off()
pyb.mdelay(500)
blue.on()
pyb.mdelay(500)
blue.off()
pyb.mdelay(500)
white.on()
pyb.mdelay(500)
white.off()
pyb.mdelay(500)
在使用find_rects()函数查找图像中的矩形时,可能会识别到非目标矩形,甚至识别到一些奇形怪状的矩形,这也会影响识别的结果。
这种情况可以通过修改threshold参数来解决,此时,只有边界大小小于threshold的矩形才会被识别出来,其余矩形全被过滤掉了。
image.find_rects([threshold=10000])
但这种方法并不能解决全部的问题,有时OpenMV还会识别到一些长度很大、宽度很小或者宽度很大、长度很小的矩形,此时可以通过限制长度和宽度或限制长宽比来筛选正确的矩形框:
while(True):
img = sensor.snapshot()
for r in img.find_rects(threshold = 10000): # 在图像中搜索矩形
print(r.rect()[3]) # 索引[3]:返回矩形的高度
print(r.rect()[2]) # 索引[2]:返回矩阵的宽度
if(abs(r.rect()[3]) > 160 or abs(r.rect()[2]) > 160 or abs(r.rect()[3]) < 70 or abs(r.rect()[2]) < 70): # 限制长度和宽度
break
if(r.rect()[3]/r.rect()[2]>1.3 or r.rect()[3]/r.rect()[2]<0.7): # 限制长宽比
break
需要注意的是,上述threshold参数和长度宽度的取值都需要根据实际应用场景和对象来确定,每个物体的参数是不一样的。
在调试程序的过程中,可以在OpenMV IDE窗口中画一些图来直观地观察程序运行过程。
while(True):
img = sensor.snapshot()
img.draw_rectangle(r.rect(), color = (255, 0, 0)) # 绘制矩形外框,便于在IDE上查看识别到的矩形位置
img.draw_cross(int(r.rect()[0] + r.rect()[2]/2), int(r.rect()[1] + r.rect()[3]/2), color = (0, 255, 0))#在矩形中心画十字
img.draw_string(r.rect()[0] + 20, r.rect()[1]-20, 001+"my openmv"),color = (255,0,0), scale = 2,mono_space=False)#显示类别名称和准确率
for p in r.corners():
img.draw_circle(p[0], p[1], 5, color = (0, 255, 0))
img.draw_rectangle(r.rect(), color = (255, 0, 0))#在矩形的四个边角画出四个圆