一、前言
本人有幸参加2023年全国大学生电子设计竞赛,我们团队选择了E题-运动目标控制与自动追踪系统,我在团队中负责视觉部分,因为我们手头有两个OpenMV,故选择了使用OpenMV。
二、问题分析与设计
针对题目要求,我们团队设计出相应的背景板(如下图)
前两问我们团队是半写死的,这里我不做过多追叙。
基础部分我只说明第三问的(第四问和第三问同样道理)
基础部分第三问:红色激光点沿着A4长方形边运动
这里的解决思想就是让Openmv检测到长方形的四边,并将长方形四角坐标反馈给单片机处理。
很幸运的告诉大家,OpenMV官方已经有相关的驱动程序了
import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.RGB565) # 灰度更快(160x120 max on OpenMV-M7)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
# 下面的`threshold`应设置为足够高的值,以滤除在图像中检测到的具有
# 低边缘幅度的噪声矩形。最适用与背景形成鲜明对比的矩形。
for r in img.find_rects(threshold = 10000):
img.draw_rectangle(r.rect(), color = (255, 0, 0))
for p in r.corners(): img.draw_circle(p[0], p[1], 5, color = (0, 255, 0))
print(r)
print("FPS %f" % clock.fps())
上面的程序会将OpenMV检测到的矩形的四角坐标打印出来,效果如下图
这里要注意,这里返回的坐标是矩形四角在OpenMV中的坐标,坐标返回顺序是左下、右下、右上、左上。如果要实际使用的话,需要处理。
当然,如果可以做到识别的话,接下来就是数据处理,让其运动起来。这里提一嘴,我们团队用的是线性回归方程,将目标角坐标转化为PWM值,实现瞬移效果。
以下是OpenMV与STM32通信代码,可以实现坐标数据的传输与数据过滤,我完整放出了,求三连~
import sensor, image, time , math, pyb, ustruct
from pyb import LED, UART
thresholds = [(1, 20, -20, 19, -13, 17)]
sensor.reset()
sensor.set_pixformat(sensor.RGB565) # 灰度更快(160x120 max on OpenMV-M7)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()
sensor.set_vflip (True)
sensor.set_hmirror (True)
led = pyb.LED(3).on()
uart = UART(3,115200) #定义串口3变量
uart.init(115200, bits=8, parity=None, stop=1)
flag = 1
check = 0
x_range = 0
y_range = 0
x_last_range = 0
y_last_range = 0
high = 0
high_range = 0
wight = 0
wight_range = 0
inix = 0
iniy = 0
wight_xiangsu = 0
high_xiangsu = 0
li_list = []
x_list = []
y_list = []
while(True):
clock.tick()
img = sensor.snapshot()
for r in img.find_rects(threshold = 33000):
img.draw_rectangle(r.rect(), color = (255, 0, 0))
led = pyb.LED(3).off()
led = pyb.LED(2).on()
for li in r.corners():
img.draw_circle(li[0], li[1], 5, color = (0, 255, 0))
#print(li,xielu)
#print(check)
if check >= 10 and flag < 4: # 上电10次求出平均值和标志点坐标
flag += 1 # 实验发现10次求平均值后得到的原始数据会乱序(总体向前3个单位)
li_list.append(li) # 加注flag < 4既等待3个单位以顺序正确
led = pyb.LED(2).off()
led = pyb.LED(1).on()
inix = (x_range/10)
iniy = (y_range/10)
wight_xiangsu = (wight_range / 10)
high_xiangsu = (high_range / 10)
else:
li_list.append(li)
if len(li_list) >= 4: # 当li_list里数据超过4个但不超过5个时(正常情况)绘制辅助边框
if len(li_list) < 5: # 实验发现当等待3个单位后,数据长度异常为5位 以此过滤
print(li_list,check,flag)
x_list = [x[0] for x in li_list]# 读取元组
y_list = [y[1] for y in li_list]
if flag == 4: # 平均值得出后执行绘制辅助区域程序
wight = (wight_xiangsu-inix)/21
high = (high_xiangsu-iniy)/30
wucha = wight-high
print("误差为 :",wucha)
else:
if abs(x_list[3]-x_last_range) < 10 and check >= 1 and abs(y_list[3]-y_last_range) < 10: # 10次检测中过滤误差大于10的数据
x_range += x_list[3]
y_range += y_list[3]
wight_range = wight_range + (x_list[1] + x_list[2])/2
high_range = high_range + (y_list[0] + y_list[1])/2
check+=1
x_last_range = x_range / check
y_last_range = y_range / check
#print('next')
elif check == 0:
x_range += x_list[3]
y_range += y_list[3]
wight_range = wight_range + (x_list[1] + x_list[2])/2
high_range = high_range + (y_list[0] + y_list[1])/2
check+=1
x_last_range = x_range / check
y_last_range = y_range / check
#print('first')
else:
x_last_range = x_range / check
y_last_range = y_range / check
#print('error')
#data = bytearray([0xb3,0xb3,inix,iniy,x_list[0]-inix,x_list[1]-inix,x_list[2]-inix,x_list[3]-inix,y_list[0]-iniy,y_list[1]-iniy,y_list[2]-iniy,y_list[3]-iniy,0x5b])# 重新构建的坐标系发送32处理/?在openmv内部处理
data = bytearray([0xb3,0xb3,x_list[0],x_list[1],x_list[2],x_list[3],y_list[0],y_list[1],y_list[2],y_list[3],0x5b])
uart.write(data)
x_list.clear()
y_list.clear()
li_list.clear()
else:
x_list.clear()
y_list.clear()
li_list.clear()
视频效果如下
2023年电赛E题OpenMV沿矩形划线
发挥部分追踪问题
这里相信大家都会遇到一个问题,那就是——黑色胶带吸红光。
针对这个问题,两种解决办法
第一种:采用更亮的激光笔,这样可以有效解决问题,但是发热严重
第二种:调整OpenMV图像设置
sensor.skip_frames(time=200) # 跳过多少帧
sensor.set_auto_exposure(False, 1000)#调节曝光度
sensor.set_auto_gain(False) # 关闭增益(色块识别时必须要关)
sensor.set_vflip (True)
sensor.set_hmirror (True)
只要在追踪方云台端的OpenMV程序中加入以上代码可解决问题,即使红色光较弱也可以完美识别到。
三、总结
以上可以完美解决视觉部分问题,只是很可惜,因为各种原因,最终只拿到了省一,无缘国赛,不过还是想在此与大家分享此次有意义的经历。如果大家有不懂得地方可以在评论区留言,或者私信我,一起探讨!如有不对的地方还望各位大佬斧正!求三连~谢谢大家!
转自:
https://blog.csdn.net/m0_66418395/article/details/133280948