2023年电赛e控制题视觉处理部分
题目
视觉处理模块
openmv
处理思路
大致的思路是我这边识别黑色胶带矩形四个点位置,计算斜率,然后将一边的长度均分均分,每次x坐标设为1,有ab斜率y = k*b 计算y大致值,就得到一个大致的坐标,发送给电控。
基础全部代码
import sensor, image, time, math, ustruct,lcd,math
from pyb import UART
#thresholds =(0, 52, -128, 127, -128, 127)
#thresholds =(0, 43, -128, 127, -128, 127)
#thresholds =(0, 23, -128, 127, -128, 127)
thresholds =(0, 34, -128, 127, -128, 127)
roi = (85,30,165,170)# 开始roi的面积
flage = 100
corners = ([0,0],
[0,0],
[0,0],
[0,0])
Rect = (0,0,0,0)
k = 0.0
b = 0
m = 0
n = 0
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
lcd.init()
clock = time.clock()
uart = UART(1,115200)
def outuart(x,y,flage):
global uart;
data = ustruct.pack("<bbhhhb",
0x2C,
0x12,
int(x*100),
int(y*100),
int(flage),
0x5B)
uart.write(data);
time.sleep_ms(20)
while(True):
if flage == 100:
print("等待电控给我值")
flage = int(uart.readchar())
print(flage)
if flage == 150:
flage = 0
else:
flage = 100
if flage is not 100:
clock.tick()
img = sensor.snapshot()
img.draw_rectangle((roi),color = (255,0,0), thickness=1,fill=False)
#img.draw_circle(160+22, 120+2, 3, color = (0, 0, 0), thickness = 1, fill = True)
img.draw_cross(160+22,120+2,color = (255,0,0),thickness=1)#画红色十字位置与激光在一个位置上
for blob in img.find_blobs([thresholds],roi=roi,x_stride = 1, y_stride=1,pixels_threshold=300, area_threshold=300, merge=True):
print("返回色块面积")
print(blob.area())
if blob.area()>8000 and blob.area()<30000:
corners = blob.corners()
A = corners[0]
B = corners[1]
C = corners[2]
D = corners[3]
#将ABCD四点的坐标转为十字为原点的坐标系下
Ax = (A[0])-160-22
Ay = (A[1])-120-2
Bx = (B[0])-160-22
By = (B[1])-120-2
Cx = (C[0])-160-22
Cy = (C[1])-120-2
Dx = (D[0])-160-22
Dy = (D[1])-120-2
print("******A******")
print(A)
print("******B******")
print(B)
print("******C******")
print(C)
print("******D******")
print(D)
Rect = blob.rect()
rectx = int(Rect[0])
recty = int(Rect[1])
rectw = int(Rect[2])
recth = int(Rect[3])
'''rectx = rectx-20
recty = recty-30
rectw = rectw+40
recth = recth+45'''
rectx = rectx-40
recty = recty-40
rectw = rectw+70
recth = recth+90
roi = (rectx,recty,rectw,recth)
img.draw_edges(blob.corners(), color=(0,255,255),thickness=3)
#画图abcd四个点
img.draw_string((corners[0])[0],(corners[0])[1],"A",color = (0,255,255),scale=4, mono_space=False)
img.draw_string((corners[1])[0],(corners[1])[1],"B",color = (0,255,255),scale=4, mono_space=False)
img.draw_string((corners[2])[0],(corners[2])[1],"C",color = (0,255,255),scale=4, mono_space=False)
img.draw_string((corners[3])[0],(corners[3])[1],"D",color = (0,255,255),scale=4, mono_space=False)
img.draw_rectangle(blob.rect())
k1 = str(k)
img.draw_string(5,5,"k:"+k1,color = (255,0,0),scale=4, mono_space=False)
#四条边的判断以及与电控通信
if flage == 0:
outuart(Ax,Ay,flage)
print("111111111111111111111111111")
print(Ax,Ay)
if abs(Ax)<3 and abs(Ay)<3:
time.sleep_ms(500)
flage = 1
outuart(0,0,10)
print("--------------------------------")
if flage == 1:
print("222222222222222222222222222")
if Bx is not 0:
bk= By/Bx
x=1.0
y=1.0*bk
outuart(x,y,flage)
print(Bx,By)
if abs(Bx)<5 and abs(By)<5:
time.sleep_ms(500)
flage = 2
outuart(0,0,10)
if flage == 2:
print("333333333333333333333333333333333")
if Cx is not 0:
ck = Cy/Cx
x=1.0
y=1.0*ck
outuart(x,y,flage)
#outuart(0,0,10)
print(Cx,Cy)
if abs(Cx)<4.5 and abs(Cy)<4.5:
outuart(0,0,10)
time.sleep_ms(500)
flage = 3
print("--------------------------------")
if flage == 3:
print("444444444444444444444444444444444")
if Dx is not 0:
dk = Dy/Dx
x=-1.0
y=-1.0*dk
outuart(x,y,flage)
print(Dx,Dy)
if abs(Dx)<5 and abs(Dy)<5.5:
outuart(0,0,10)
time.sleep_ms(500)
flage = 4
print("--------------------------------")
if flage == 4:
print("555555555555555555555555555555555")
if Ax is not 0:
ak = Ay/Ax
x=-1.0
y=-1.0*ak
outuart(x,y,flage)
# outuart(0,0,10)
print(Ax,Ay)
if abs(Ax)<4.5 and abs(Ay)<4.5:
outuart(0,0,10)
time.sleep_ms(500)
outuart(0,0,20)
print("--------------------------------")
flage = 100
break
#lcd.display(img,x_scale=0.3,y_scale = 0.4)
print(clock.fps())
提高部分
思路
其实很简单识别红色的激光色块然后进行坐标转换,计算出目标的位置发给电控就ok了
提高部分代码
import sensor, image, time,ustruct,lcd,math
from pyb import UART,LED
thresholds_red1 = (12, 100, 3, 127, -128, 127)
t2 =(5, 100, -128, 127, -128, 127)
center = [0,0] #红色激光笔的位置
roi = (100,60,126,140)
flage = 0.0 # 是否追上
#img.draw_cross(160-3,120-1,color = (255,0,0),thickness=2) #绿色十字的位置
sensor.reset() # Reset and initialize the sensor.
sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.skip_frames(time = 2000) # Wait for settings take effect.
clock = time.clock() # Create a clock object to track the FPS.
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
sensor.set_auto_exposure(False,9000)
uart = UART(3,115200)
def outuart(x,y,flage):
global uart;
#frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
#data = bytearray(frame)
data = ustruct.pack("<bbhhhb", #格式为俩个字符俩个短整型(2字节)
0x2C, #帧头1
0x12, #帧头2
int(x*100), # up sample by 4 #数据x坐标
int(y*100), # up sample by 4 #数据y坐标
int(flage), # up sample by 4 #FLAGE
0x5B)
uart.write(data); #必须要传入一个字节数组
time.sleep_ms(10)
while(True):
clock.tick() # Update the FPS clock.
img = sensor.snapshot()
img.binary([thresholds_red1])
img.dilate(1)
#img.draw_rectangle((roi),color = (0,0,255), thickness=1,fill=False) #画出roi
Blob = img.find_blobs([t2],roi = roi,pixels_threshold=2, area_threshold=15, merge=True,invert = 0)
if not Blob:
outuart(0,0,10)
for b in Blob:
print("光斑的面积大小")
print(b.area())
area = b.area()
if area>20 and area<500:
# 打印激光色块的中心位置 下面获取的坐标基于图像的左上角为原点(0, 0),X轴向右增大,Y轴向下增大
# 使用b.x()获取色块矩形左上角X坐标
# 使用b.y()获取色块矩形左上角Y坐标
# 使用b.w()获取色块矩形宽度
# 使用b.h()获取色块矩形高度
# 矩形中心坐标为(x + w/2,y + h/2)
img.draw_rectangle(b.rect(), color = (255,0 , 0), scale = 2, thickness = 5)
center[0] = (b.x() + b.w()/2)-160+4 #x
center[1] = (b.y() + b.h()/2)-120+8 #y
Ax = center[0]
Ay = center[1]
rectx = b.x()-30
recty = b.y()-30
rectw = b.w()+60
recth = b.h()+60
roi = (rectx,recty,rectw,recth)
print("距离*************************************")
dis = math.sqrt(abs(Ax)*abs(Ax)+abs(Ay)*abs(Ay))
print(dis)
#if dis>2 and dis <15:
#roi = roi
if dis>2:
outuart(Ax,Ay,flage)
if dis<=7.2 and dis>2:
flage = 1
outuart(Ax,Ay,flage)
print("报警")
LED(1).on()
outuart(Ax,Ay,10)
if dis>7.2:
flage = 0
print("不报警")
outuart(Ax,Ay,flage)
LED(1).off()
outuart(Ax,Ay,10)
print(clock.fps())
大致的效果,我调的也不是很好只能是这样