赞
踩
OpenMV固定于舵机云台前,屏幕画面置于镜头前,OpenMV将屏幕中数据信息,包括原点位置,激光点位置,A4靶纸边框位置利用串口传给主控芯片。(完整代码直接见第四部分)
初始化OpenMV串口3,利用数据包一次发送十个数据给主控,包括五个坐标点——激光点坐标,靶值四个角点坐标。当需要发送数据时,只要在程序中引用此函数即可。
- import sensor, image, time
- import ustruct
- from pyb import UART,LED
-
- uart = UART(3,9600)
- uart.init(9600, bits=8, parity=None, stop=1) # 开启OpenMV串口3 波特率为9600,8位,一位停止位
-
- def sending_data(rx,ry,cx,cy,cw,ch,xx,xy,xw,xh): # 定义发送数据包函数 包头位“FF”,包尾为“FE”
- global uart; # 数据包中有十个数据
- data = ustruct.pack("<bhhhhhhhhb", # 分别为激光点中心坐标以及靶纸corner坐标
- 0xFF,
- int(rx),
- int(ry),
- int(cx),
- int(cy),
- int(cw),
- int(ch),
- int(xx),
- int(xy),
- int(xw),
- int(xh),
- 0xFE)
- uart.write(data);
利用OpenMV 自带的寻找色块的函数,寻找画面中最大激光点阈值的色块并读取中心坐标。3
首先进行阈值的选择、ROI的选择以及曝光时间选择。(所给的数据均为比赛时我用的数据,请自行调整)
- #****************************阈值调整*******************************
- area=(45, 2, 200, 198)
- red=(88, 100, -16, 22, -128, 127)
-
- sensor.reset()
- sensor.set_pixformat(sensor.RGB565)
- sensor.set_framesize(sensor.QVGA)
- sensor.set_auto_whitebal(True)
- sensor.set_auto_gain(False)
- sensor.skip_frames(time = 2000)
- sensor.set_vflip(True)
- sensor.set_hmirror(True)
- #****************************曝光时间*******************************
- sensor.set_auto_exposure(False,4500)
-
- clock = time.clock()
- while(True)
- clock.tick()
- img = sensor.snapshot().lens_corr(strength = 1.6, zoom = 1.0)
-
- red_point= img.find_blobs([red])
- if red_point:
- r= red_point[0]
- img.draw_rectangle(r[0:4],color=(0,0,0)) # rect
- rx=r[5]
- ry=r[6]
用OpenMV自带的寻找直线的函数在ROI中找到所有的直线,然后通过判断所寻找的直线数是否为四进行下一步求交点。
- #*****************************line_threshold**********************
- line_threshold=2500
- rect_threshold=10000
-
- while(True):
- clock.tick()
- img = sensor.snapshot().lens_corr(strength = 1.6, zoom = 1.0)
-
- red_point= img.find_blobs([red])
- if red_point:
- r= red_point[0]
- img.draw_rectangle(r[0:4],color=(0,0,0)) # rect
- rx=r[5]
- ry=r[6]
- #print(rx,ry)
-
-
- #******************************************************************lines*****************
- lines = img.find_lines(roi=area, threshold=line_threshold)
- i=0
- if len(lines)==4 :
如果识别到四条直线,依次两两直线遍历,是否夹角大于一定值,判断直线是否相交,从而求出交点坐标 。
- if len(lines)==4 :
- theta0=lines[0].theta()
- theta1=lines[1].theta()
- theta2=lines[2].theta()
- theta3=lines[3].theta()
- for line in lines:
- img.draw_line(line.line(),color=[255,0,0])
- if abs(theta0-theta1)>45:
- a[i]=calculate_intersection(lines[0],lines[1])[0]
- i=i+1
- a[i]=calculate_intersection(lines[0],lines[1])[1]
- i=i+1
- if abs(theta0-theta2)>45:
- a[i]=calculate_intersection(lines[0],lines[2])[0]
- i=i+1
- a[i]=calculate_intersection(lines[0],lines[2])[1]
- i=i+1
- if abs(theta0-theta3)>45:
- a[i]=calculate_intersection(lines[0],lines[3])[0]
- i=i+1
- a[i]=calculate_intersection(lines[0],lines[3])[1]
- i=i+1
- if abs(theta1-theta2)>45:
- a[i]=calculate_intersection(lines[2],lines[1])[0]
- i=i+1
- a[i]=calculate_intersection(lines[2],lines[1])[1]
- i=i+1
- if abs(theta1-theta3)>45:
- a[i]=calculate_intersection(lines[1],lines[3])[0]
- i=i+1
- a[i]=calculate_intersection(lines[1],lines[3])[1]
- i=i+1
- if abs(theta3-theta2)>45:
- a[i]=calculate_intersection(lines[2],lines[3])[0]
- i=i+1
- a[i]=calculate_intersection(lines[2],lines[3])[1]
- i=i+1
其中求交点的坐标函数如下:
- def calculate_intersection(line1, line2):
- '''
- 计算两条线的交点
- '''
- a1 = line1.y2() - line1.y1()
- b1 = line1.x1() - line1.x2()
- c1 = line1.x2()*line1.y1() - line1.x1()*line1.y2()
-
- a2 = line2.y2() - line2.y1()
- b2 = line2.x1() - line2.x2()
- c2 = line2.x2() * line2.y1() - line2.x1()*line2.y2()
-
- if (a1 * b2 - a2 * b1) != 0 and (a2 * b1 - a1 * b2) != 0:
- cross_x = int((b1*c2-b2*c1)/(a1*b2-a2*b1))
- cross_y = int((c1*a2-c2*a1)/(a1*b2-a2*b1))
- return (cross_x, cross_y)
- return None
利用OpenMV自带的寻找矩形函数。但需要注意阈值以及ROI,可以设置识别矩形的长宽范围筛选出我们所需要的那个矩形,从而记录角点坐标。
- while(True):
- clock.tick()
- img = sensor.snapshot()
-
- # -----矩形框部分-----
- # 在图像中寻找矩形
- for r in img.find_rects(threshold = 10000):
- # 判断矩形边长是否符合要求
- if r.w() > 20 and r.h() > 20:
- # 在屏幕上框出矩形
- img.draw_rectangle(r.rect(), color = (255, 0, 0), scale = 4)
- # 获取矩形角点位置
- corner = r.corners()
- # 在屏幕上圈出矩形角点
- img.draw_circle(corner[0][0], corner[0][1], 5, color = (0, 0, 255), thickness = 2, fill = False)
- img.draw_circle(corner[1][0], corner[1][1], 5, color = (0, 0, 255), thickness = 2, fill = False)
- img.draw_circle(corner[2][0], corner[2][1], 5, color = (0, 0, 255), thickness = 2, fill = False)
- img.draw_circle(corner[3][0], corner[3][1], 5, color = (0, 0, 255), thickness = 2, fill = False)
-
- # 打印四个角点坐标, 角点1的数组是corner[0], 坐标就是(corner[0][0],corner[0][1])
- # 角点检测输出的角点排序每次不一定一致,矩形左上的角点有可能是corner0,1,2,3其中一个
- corner1_str = f"corner1 = ({corner[0][0]},{corner[0][1]})"
- corner2_str = f"corner2 = ({corner[1][0]},{corner[1][1]})"
- corner3_str = f"corner3 = ({corner[2][0]},{corner[2][1]})"
- corner4_str = f"corner4 = ({corner[3][0]},{corner[3][1]})"
- print(corner1_str + "\n" + corner2_str + "\n" + corner3_str + "\n" + corner4_str)
这里只给方法一的完整代码,方法二自行替换即可。
- import sensor, image, time
- import ustruct
- from pyb import UART,LED
-
- #****************************阈值调整*******************************
- area=(45, 2, 200, 198)
- red=(88, 100, -16, 22, -128, 127) #only red
-
- sensor.reset()
- sensor.set_pixformat(sensor.RGB565)
- sensor.set_framesize(sensor.QVGA)
- sensor.set_auto_whitebal(True)
- sensor.set_auto_gain(False)
- sensor.skip_frames(time = 2000)
- sensor.set_vflip(True)
- sensor.set_hmirror(True)
- #****************************曝光时间*******************************
- sensor.set_auto_exposure(False,4500)
-
- clock = time.clock()
- #*****************************line_threshold**********************
- line_threshold=2500
- rect_threshold=10000
-
- uart = UART(3,9600)
- uart.init(9600, bits=8, parity=None, stop=1)
-
- def calculate_intersection(line1, line2):
- '''
- 计算两条线的交点
- '''
- a1 = line1.y2() - line1.y1()
- b1 = line1.x1() - line1.x2()
- c1 = line1.x2()*line1.y1() - line1.x1()*line1.y2()
-
- a2 = line2.y2() - line2.y1()
- b2 = line2.x1() - line2.x2()
- c2 = line2.x2() * line2.y1() - line2.x1()*line2.y2()
-
- if (a1 * b2 - a2 * b1) != 0 and (a2 * b1 - a1 * b2) != 0:
- cross_x = int((b1*c2-b2*c1)/(a1*b2-a2*b1))
- cross_y = int((c1*a2-c2*a1)/(a1*b2-a2*b1))
- return (cross_x, cross_y)
- return None
-
- def sending_data(rx,ry,cx,c):
- global uart;
- data = ustruct.pack("<bhhhhhhhhb",
- 0xFF,
- int(rx),
- int(ry),
- int(cx),
- int(cy),
- int(cw),
- int(ch),
- int(xx),
- int(xy),
- int(xw),
- int(xh),
- 0xFE)
- uart.write(data);
- cx=0
- cy=0
- rx=0
- ry=0
- a=[0,0,0,0,0,0,0,0,0,0]
-
- while(True):
- clock.tick()
- img = sensor.snapshot().lens_corr(strength = 1.6, zoom = 1.0)
-
- red_point= img.find_blobs([red])
- if red_point:
- r= red_point[0]
- img.draw_rectangle(r[0:4],color=(0,0,0)) # rect
- rx=r[5]
- ry=r[6]
- #print(rx,ry)
-
- #******************************************************************lines*****************
- lines = img.find_lines(roi=area, threshold=line_threshold)
- i=0
- if len(lines)==4 :
- theta0=lines[0].theta()
- theta1=lines[1].theta()
- theta2=lines[2].theta()
- theta3=lines[3].theta()
- for line in lines:
- img.draw_line(line.line(),color=[255,0,0])
- if abs(theta0-theta1)>45:
- a[i]=calculate_intersection(lines[0],lines[1])[0]
- i=i+1
- a[i]=calculate_intersection(lines[0],lines[1])[1]
- i=i+1
- if abs(theta0-theta2)>45:
- a[i]=calculate_intersection(lines[0],lines[2])[0]
- i=i+1
- a[i]=calculate_intersection(lines[0],lines[2])[1]
- i=i+1
- if abs(theta0-theta3)>45:
- a[i]=calculate_intersection(lines[0],lines[3])[0]
- i=i+1
- a[i]=calculate_intersection(lines[0],lines[3])[1]
- i=i+1
- if abs(theta1-theta2)>45:
- a[i]=calculate_intersection(lines[2],lines[1])[0]
- i=i+1
- a[i]=calculate_intersection(lines[2],lines[1])[1]
- i=i+1
- if abs(theta1-theta3)>45:
- a[i]=calculate_intersection(lines[1],lines[3])[0]
- i=i+1
- a[i]=calculate_intersection(lines[1],lines[3])[1]
- i=i+1
- if abs(theta3-theta2)>45:
- a[i]=calculate_intersection(lines[2],lines[3])[0]
- i=i+1
- a[i]=calculate_intersection(lines[2],lines[3])[1]
- i=i+1
- print(a)
- FH = bytearray([0xFF,rx,ry,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],0xFE])
- uart.write(FH)
- print(rx,ry)
-
- print(clock.fps())
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。