提示:本程序测试主控为open mv4 H7,开发平台为openmv IDE
openmv一些常见小问题与阶段性心得总结
前言
本文主要对我在使用openmv过程中发现的一些常见小问题进行总结归纳,这些问题都不是很严重,但细微之处见差距,希望对你的使用有所帮助,同时也作为我备赛阶段性使用openmv的笔记总结。
一、谨慎使用画图画线功能
a.画图画线也会影响图像识别效果
当我们测试时,喜欢在图像中绘制各种线条,比如感性区域,指定的坐标点,指定区域范围等线条
这里要注意,这些画线也会影响我们的图像和目标效果追踪,要注意到我们这些函数都是img.draw_XXX这类,这类都是在图像中绘制,相当于对图像进行了二次处理,留意一些我们的图像都是通过img = sensor.snapshot()这句话实现的,那些绘制出来的线段也会影响效果
b.实际效果对比
如下图所示,这是没有加线条的正常图像颜色识别效果
如下图所示,这是拿滚球控制系统标记了点后的图像来看,可以发现图像识别区域有了明显的干扰,中心点和框大小都有了明显的变化
这是继续移动的效果,可见图像已经无法识别出来了,我们绘制的线已经影响了物体的完整性,图像由于绘制的线条出现了明显的分割现象
如果绘制的线条颜色和我们追踪的线条颜色相近,也会影响阈值选取,也可能会干扰颜色识别效果
c. 动态画线和静态画线
如下就是这些画线的函数,尤其要注意主动画线和被动画线的区别,主动画线是直接对追踪前的图像进行操作,会影响识别效果如下为静态绘线
如下就是被动绘线,img.draw_edges(max_blob1.min_corners(), color=(0,255,128))
img.draw_cross(max_blob1[5], max_blob1[6],color=(0,255,128))
这是在识别完成后的绘线,不会影响图像识别,也就是动态画线
d.小结
这里建议在测试的时候可以提前先绘制线条,测试的时候实时观看,在实际工作比赛时关闭这些不必要的线段,这样可以在一定程度上提高辨识效果,减少误差
二、定时器中无法运行分配内存的函数
d.定时器无法添加分配内存
定时器中无法添加分配内存的函数,否则会出现如下错误提示-uncaught exception in Timer(2) interrupt handler,程序能正常运行,但会提示定时器中断无法正常工作
这是因为我们在中断回调函数中添加了分配内存的函数,通俗的来说,就是我们在定时器中断中对定时器函数以外(主函数)中其它变量进行了修改或者值改变。
相当于openmv定时器是一个不同与主函数的新线程,不能打断影响主函数变量和进程,只能输出主函数分配内存的函数,在其中定义的值相当于局部变量,不影响全局变量
b.图示实测对比
如下图所示,使用LDE,串口等读取输出内存函数可以正常运行
这里我们在定时器中更改了test的值,可见在while中依然输出的是1,可见在定时器中更改的值不会影响除了定时器以外的地方
如下图可见定时器中的变量变化不会影响除了定时以外的地方
如下图,定时器可以正常输出访问while中的变量变化
这里在回调中添加分配内存的函数,可见我们想要的效果并没有达到,同时还输出了一个错误警告
c.小结
在回调中不允许分配内存的函数,具体解决方案还要错误问题描述如果还是没有明白,可以参考一下如下博文查看详细解释,这里由于篇幅原因不做过多解释
三.open MV光照阈值不稳定优化
在我们实际使用中,openmv受环境光影响较大,有可能提前设置好的阈值并不适合实际比赛或者应用场地,这里给大家一些使用方法和建议,注意这里只是总结,相关详细方案在其它博文中会有详细介绍,欢迎查看
a.一种基于open mv的自适应阈值的方法
这里推荐一种基于openmv的自适应取阈值的方法,在我们实际使用中,openmv受环境光影响较大,有可能提前设置好的阈值并不适合实际比赛或者应用场地,而且如果遇到混合颜色或者极端情况提前取好的阈值可能失效,增加阈值数目又可能会出现颜色混淆,所以我设计出这种自适应阈值的取阈值方式,程序初始没有设置准确的阈值,通过将想要追踪的颜色或者混合颜色目标对准摄像头中间绘出小框,再通过按键等对P1口施加高电平,摄像头即可自动追踪目标颜色,可以根据条件一键追踪目标,一般和外接的LCD屏连用用于比赛或实际工作场地调节,无需再连接到电脑手动调节阈值,适合比赛准备或者抗光干扰实验研究
由于篇幅原因这里不过多介绍,详细资料情况请查看下面博文,我已经上传提供了完整配置教程和代码文件
b.多个阈值对应一个物体
一般我们追踪目标都是通过颜色追踪,颜色追踪的效果是最好的,一般我们对于一个物体只会用一个元组设置一个阈值,但随着环境中光源的不经意改变,早上取的阈值到了晚上就用不了了,这种情况很多,不利于我们比赛和实际效果。
这时,我们可以通过设置多个颜色阈值来捕捉目标,通过在一个列表中设置多个颜色元组来适应不同情况
由于篇幅原因这里不过多介绍,详细资料情况请查看下面博文,我已经上传提供了完整配置教程和代码文件
c.寻找最大物体
如果我们追踪的物体同一时间同一场景中只有一个,那我们可以通过设置如下函数找到最大的那一个,大大的减少误差和噪点
由于篇幅原因这里不过多介绍,详细资料情况请查看下面博文,我已经上传提供了完整配置教程和代码文件
d.设置限定参数
通过设置目标区域的感性区域,最小像素点合并,像素点最大最小值等限制条件提高效果,例如下列中的roi,pixels_threshold, area_threshold,merge,等限制条件
由于篇幅原因这里不过多介绍,详细资料情况请查看下面博文,我已经上传提供了完整配置教程和代码文件
四.open MV图像卡顿问题
a.帧率过低
通过print(clock.fps())可以查看整个全局程序运行的帧率
b.解决方案1
可以通过计算耗费的时间,通过millis()来计算不同过程的时间。 可以测量出到底是程序哪里耗费时间多来进行优化
import pyb
time_start = pyb.millis()
img = sensor.snapshot() # Take a picture and return the image.
duration = pyb.elapsed_millis(time_start)
c.解决方案2
如果代码已经无法再继续优化,那么可以通过超频的方案提示一部分的性能,按照官网给出的数值,通过实际测试效果有一定提高,目前没有发生什么问题,不过就是主控芯片温度会高了点,一般情况下帧率是足够的,而且脱机后帧率会加倍。
# Overclocking Example
#
# 这个例子展示了如何让你的OpenMV2超频到216MHZ。
# 摄像头的超频状态会持续到下一次硬件重启,如果你需要保持这个频率,
# 你需要在主程序中调用set_frequency函数
# 警告: 超频到216MHz应该是安全的,然而需要自担风险!
import cpufreq
# 打印当前的频率
print(cpufreq.get_frequency())
# 设置频率,可用的值为 (120, 144, 168, 192, 216)
cpufreq.set_frequency(cpufreq.CPUFREQ_216MHZ)
# 打印当前的频率
print(cpufreq.get_frequency())
b.软件卡顿
有的时候我发现软件图像运行时偶尔会出现一点卡顿,不过可能这是个别现象,通过比较数据没有发现数据流出现波动,可见只是我们的观测窗口发生了卡顿,并不会对实际效果产生影响。
五.部分项目示例参考
这里附上一些项目示例部分程序,供大家参考,篇幅有限原因不做详细解释,如果有兴趣的朋友可以评论或私聊我获取相关资料和代码
a.滚球控制系统
电赛控制题:滚球控制系统(openmv部分)
# 2021.07.17 滚球控制系统 地眼计划
# x=320 y=240
import sensor, image, time, math, json, pyb,lcd
from pyb import LED
from pyb import UART
from pyb import Pin
from pyb import Timer
#LED(1).on()
#LED(2).on()
#LED(3).on()
pin1 = Pin('P1', Pin.IN, Pin.PULL_UP) ##将P1口作为阈值控制口 OUT_PP PULL_NONE
pin9 = Pin('P9', Pin.IN, Pin.PULL_UP)
blue_L_min=1
blue_L_max=1
blue_A_min=1
blue_A_max=1
blue_B_min=1
blue_B_max=1
# 颜色跟踪阈值(L Min, L Max, A Min, A Max, B Min, B Max)
thresholds1 =[
#(0, 26, -128, 126, -128, -18),#13;40
#(0, 100, -128, 127, -128, -26), #17:17
#(0, 27, -128, 125, -128, -13)
#(0, 100, 23, 127, -128, 127),
(0, 25, -128, 127, -18, 127),
(blue_L_min,blue_L_max,blue_A_min,blue_A_max,blue_B_min,blue_B_max)
] #16:30 #蓝色车尾
thresholds2 =[(0, 58, -128, -20, -128, 127),#19;22反光
(0, 26, -128, -13, -128, 127),#12:43
(20, 43, -128, -16, -128, 127) #16:30 #绿色车头
]
#thresholds3 =[
#(0, 18, -128, 10, -128, 6),#18;15
#(0, 14, -128, 6, -128, 127) #14:10 #测试黑色
#]
#thresholds4 =[(0, 100, 26, 127, -128, 127),#16:10 #修正
#(33, 100, 26, 127, 25, 127), #15:15 #修正
#(57, 100, 8, 127, 19, 127),#21:00半黄
#(0, 99, 26, 124, -128, 127)] #16:30 #测试橘黄
sensor.reset()
#初始化摄像头,reset()是sensor模块里面的函数
sensor.set_pixformat(sensor.RGB565)
#设置图像色彩格式,有RGB565色彩图和GRAYSCALE灰度图两种
sensor.set_framesize(sensor.QVGA)
lcd.init() # 初始化lcd屏幕。
#设置图像像素大小
sensor.skip_frames(time =