- 前言
在参加RM比赛时,我们挑选了许多的设备用来实验,openmv便是其中之一。openmv是在GitHub上的开源项目,开源是相当完整,有能力的团队完全可以依据开源设计制造出自己的产品。我们所使用的openmv为淘宝星瞳科技购买,目前主要用于飞镖的视觉引导。以下为早期使用openmv进行装甲板识别的示例,其实还存在着许多不足,但是可以运行。openmv作为一款高集成度的可供二次开发的轻便设备可以在其他比赛和项目中使用,但不建议在机甲大师赛中担当主力运算设备。 - 使用设备型号为openmv4 H7,通信则采用杜邦线直连引脚
我们对于openmv还购买了摄像头延长线、红外镜头、无畸变镜头、测距拓展板等用于测试开发。以下程序应该需要配合测距拓展板,但是如果没有的话也不受影响,只需要根据openmv开发示例简单注释几行即可。对于openmv的开发是多种多样的,其功能也十分强大,但测试发现其运行神经网络的效果并不理想,但对于一些做智能小车,完成简单的识别任务、轻量级的开发任务也还是可以的。
import sensor, image,math,pyb
from pyb import UART
import json
from machine import I2C
from vl53l1x import VL53L1X
import time
blue_threshold = ((((83, 100, -20, 34, -15, 48))))
#(((85, 100, -26, 127, -43, 127)))
#100, 97, -10, 28, -24, 69
#(58, 100, -32, 17, -48, 29)
#(68, 100, -42, 16, -33, 15)
sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # use RGB565.
sensor.set_framesize(sensor.QVGA) # use QQVGA for speed.
sensor.set_windowing((160,120)) #取160,120中间的区域
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_exposure(False, 3500)#降低曝光
sensor.set_auto_whitebal(True) # turn this off.
sensor.set_auto_gain(False)
#关闭白平衡。白平衡是默认开启的,在颜色识别中,需要关闭白平衡。
clock = time.clock() # Tracks FPS.
a=[]
K=2900
uart = UART(3, 115200)
#uart.init(115200, bits=8, parity=None, stop=1) #8位数据位,无校验位,1位停止位
i2c = I2C(2)
distance = VL53L1X(i2c)
while(True):
time_start = pyb.millis()
clock.tick() # Track elapsed milliseconds between snapshots().
#img = sensor.snapshot().lens_corr(strength = 1.06, zoom = 1.1)#畸变校正
img = sensor.snapshot()# Take a picture and return the image.
#img.midpoint(1, bias=0.5, threshold=True, offset=5, invert=True)
#img.mode(1)
#img.laplacian(1, sharpen=True)
#img = sensor.snapshot().cartoon(seed_threshold=0.05, floating_thresholds=0.05)
#img.gaussian(1, unsharp=True)
for blob in img.find_blobs([blue_threshold], pixels_threshold=4, area_threshold=8, merge=False):
if (blob[3]/blob[2])>=1.2 and blob.area()<100 :#通过高宽比,
#色块面积,与像素旋转角度来限制追踪目标and blob[7]>=float(1.35)and blob[7]<= float(1.80)
a.append(blob)
b=[]
if (len(a))>=3:
#d=image.find_rects([roi=(a[len(a)-2][0],a[len(a)-2][1],a[len(a)-2][2],a[len(a)-2][3]),threshold=100])
a.pop(0)
a_=a.copy()
new_b=[]
#print(len(a),"a",a)
for i in range(len(a)-1):#遍历
#for m in range(len(a)-1):下面将通过两色块中心点的X与Y坐标差值来进行约束
if abs(a[0][5]-a_[i+1][5])>10 and abs(a[0][5]-a_[i+1][5])<50 and abs(a[0][6]-a_[i+1][6]) >0 and abs(a[0][6]-a_[i+1][6]) <7 :
b.append(a[0])
b.append(a[i+1])
for i in b:
if i not in new_b and len(b)>=2:
new_b.append(i)
#print("b",len(b),b)
if len(new_b)>=2:
#and min(length) in new_b
#img.draw_rectangle(new_b[0][0:4],(0,255,0))
#img.draw_rectangle(new_b[1][0:4],(0,255,0))
img.draw_cross((int((new_b[0][5]+new_b[1][5])/2),int((new_b[0][6]+new_b[1][6])/2)),size=10)# cx, cy
img.draw_circle((int((new_b[0][5]+new_b[1][5])/2),int((new_b[0][6]+new_b[1][6])/2),20))
angles_x=math.degrees(math.atan(math.tan(((((new_b[0][5]+new_b[1][5])/2)-80)/1.4)*0.01745)))
angles_y=-math.degrees(math.atan(math.tan(((((new_b[0][6]+new_b[1][6])/2)-60)/1.3)*0.01745)))
print('水平角度:%f'%angles_x,'竖直角度:%f' % angles_y)
if len(new_b)==2:#测距
#Lm=(abs(new_b[0][0]-new_b[1][0])+(new_b[1][3]+new_b[0][3]))/2
#length=K/Lm
#print('length:%f'%length)
length=distance.read()
print('length:%f'%length)
x=int(angles_x*1000)
z=int(length)
#if angles_y<0:#当竖直角度为负数时,此坐标系角度转化方可成立
q=9.75
b=5.5
c=math.sqrt(math.pow(11.2,2)+math.pow(length,2)-2*11.2*length*math.cos(((90-angles_y)+60.57596)*0.01745))
angle__Y=math.degrees(math.acos((math.pow(11.2,2)+math.pow(c,2)-math.pow(length,2))/(2*11.2*c)))
Y=int((angle__Y-28)*1000)
#print(angles_y,angle__Y-30)
img_data = bytearray([0xAA,0xAF,x>>24,x>>16,x>>8,x,Y>>24,Y>>16,Y>>8,Y,z>>8,z,0x5B])
uart.write(img_data)
time.sleep(5)
duration = pyb.elapsed_millis(time_start)
此为早期不成熟作品,不建议实战使用。