当前位置:   article > 正文

2023电赛E题视觉部分OpenMV_电赛e题openmv

电赛e题openmv

电赛E题视觉基础部分:

      OpenMV固定于舵机云台前,屏幕画面置于镜头前,OpenMV将屏幕中数据信息,包括原点位置,激光点位置,A4靶纸边框位置利用串口传给主控芯片。(完整代码直接见第四部分)

一、OpenMV串口部分代码

        初始化OpenMV串口3,利用数据包一次发送十个数据给主控,包括五个坐标点——激光点坐标,靶值四个角点坐标。当需要发送数据时,只要在程序中引用此函数即可。

  1. import sensor, image, time
  2. import ustruct
  3. from pyb import UART,LED
  4. uart = UART(3,9600)
  5. uart.init(9600, bits=8, parity=None, stop=1) # 开启OpenMV串口3 波特率为9600,8位,一位停止位
  6. def sending_data(rx,ry,cx,cy,cw,ch,xx,xy,xw,xh): # 定义发送数据包函数 包头位“FF”,包尾为“FE”
  7. global uart; # 数据包中有十个数据
  8. data = ustruct.pack("<bhhhhhhhhb", # 分别为激光点中心坐标以及靶纸corner坐标
  9. 0xFF,
  10. int(rx),
  11. int(ry),
  12. int(cx),
  13. int(cy),
  14. int(cw),
  15. int(ch),
  16. int(xx),
  17. int(xy),
  18. int(xw),
  19. int(xh),
  20. 0xFE)
  21. uart.write(data);

二、识别激光点

        利用OpenMV 自带的寻找色块的函数,寻找画面中最大激光点阈值的色块并读取中心坐标。3

2.1 阈值设置

        首先进行阈值的选择、ROI的选择以及曝光时间选择。(所给的数据均为比赛时我用的数据,请自行调整)

  1. #****************************阈值调整*******************************
  2. area=(45, 2, 200, 198)
  3. red=(88, 100, -16, 22, -128, 127)
  4. sensor.reset()
  5. sensor.set_pixformat(sensor.RGB565)
  6. sensor.set_framesize(sensor.QVGA)
  7. sensor.set_auto_whitebal(True)
  8. sensor.set_auto_gain(False)
  9. sensor.skip_frames(time = 2000)
  10. sensor.set_vflip(True)
  11. sensor.set_hmirror(True)
  12. #****************************曝光时间*******************************
  13. sensor.set_auto_exposure(False,4500)
  14. clock = time.clock()

2.2 色块识别

  1. while(True)
  2. clock.tick()
  3. img = sensor.snapshot().lens_corr(strength = 1.6, zoom = 1.0)
  4. red_point= img.find_blobs([red])
  5. if red_point:
  6. r= red_point[0]
  7. img.draw_rectangle(r[0:4],color=(0,0,0)) # rect
  8. rx=r[5]
  9. ry=r[6]

三、识别A4靶纸上电工胶带角点

3.1 方法一 :直线交点法

        用OpenMV自带的寻找直线的函数在ROI中找到所有的直线,然后通过判断所寻找的直线数是否为四进行下一步求交点。

  1. #*****************************line_threshold**********************
  2. line_threshold=2500
  3. rect_threshold=10000
  4. while(True):
  5. clock.tick()
  6. img = sensor.snapshot().lens_corr(strength = 1.6, zoom = 1.0)
  7. red_point= img.find_blobs([red])
  8. if red_point:
  9. r= red_point[0]
  10. img.draw_rectangle(r[0:4],color=(0,0,0)) # rect
  11. rx=r[5]
  12. ry=r[6]
  13. #print(rx,ry)
  14. #******************************************************************lines*****************
  15. lines = img.find_lines(roi=area, threshold=line_threshold)
  16. i=0
  17. if len(lines)==4 :

        如果识别到四条直线,依次两两直线遍历,是否夹角大于一定值,判断直线是否相交,从而求出交点坐标 。

  1. if len(lines)==4 :
  2. theta0=lines[0].theta()
  3. theta1=lines[1].theta()
  4. theta2=lines[2].theta()
  5. theta3=lines[3].theta()
  6. for line in lines:
  7. img.draw_line(line.line(),color=[255,0,0])
  8. if abs(theta0-theta1)>45:
  9. a[i]=calculate_intersection(lines[0],lines[1])[0]
  10. i=i+1
  11. a[i]=calculate_intersection(lines[0],lines[1])[1]
  12. i=i+1
  13. if abs(theta0-theta2)>45:
  14. a[i]=calculate_intersection(lines[0],lines[2])[0]
  15. i=i+1
  16. a[i]=calculate_intersection(lines[0],lines[2])[1]
  17. i=i+1
  18. if abs(theta0-theta3)>45:
  19. a[i]=calculate_intersection(lines[0],lines[3])[0]
  20. i=i+1
  21. a[i]=calculate_intersection(lines[0],lines[3])[1]
  22. i=i+1
  23. if abs(theta1-theta2)>45:
  24. a[i]=calculate_intersection(lines[2],lines[1])[0]
  25. i=i+1
  26. a[i]=calculate_intersection(lines[2],lines[1])[1]
  27. i=i+1
  28. if abs(theta1-theta3)>45:
  29. a[i]=calculate_intersection(lines[1],lines[3])[0]
  30. i=i+1
  31. a[i]=calculate_intersection(lines[1],lines[3])[1]
  32. i=i+1
  33. if abs(theta3-theta2)>45:
  34. a[i]=calculate_intersection(lines[2],lines[3])[0]
  35. i=i+1
  36. a[i]=calculate_intersection(lines[2],lines[3])[1]
  37. i=i+1

     其中求交点的坐标函数如下:

  1. def calculate_intersection(line1, line2):
  2. '''
  3. 计算两条线的交点
  4. '''
  5. a1 = line1.y2() - line1.y1()
  6. b1 = line1.x1() - line1.x2()
  7. c1 = line1.x2()*line1.y1() - line1.x1()*line1.y2()
  8. a2 = line2.y2() - line2.y1()
  9. b2 = line2.x1() - line2.x2()
  10. c2 = line2.x2() * line2.y1() - line2.x1()*line2.y2()
  11. if (a1 * b2 - a2 * b1) != 0 and (a2 * b1 - a1 * b2) != 0:
  12. cross_x = int((b1*c2-b2*c1)/(a1*b2-a2*b1))
  13. cross_y = int((c1*a2-c2*a1)/(a1*b2-a2*b1))
  14. return (cross_x, cross_y)
  15. return None

3.2 方法二 :   矩形角点法

        利用OpenMV自带的寻找矩形函数。但需要注意阈值以及ROI,可以设置识别矩形的长宽范围筛选出我们所需要的那个矩形,从而记录角点坐标。

  1. while(True):
  2. clock.tick()
  3. img = sensor.snapshot()
  4. # -----矩形框部分-----
  5. # 在图像中寻找矩形
  6. for r in img.find_rects(threshold = 10000):
  7. # 判断矩形边长是否符合要求
  8. if r.w() > 20 and r.h() > 20:
  9. # 在屏幕上框出矩形
  10. img.draw_rectangle(r.rect(), color = (255, 0, 0), scale = 4)
  11. # 获取矩形角点位置
  12. corner = r.corners()
  13. # 在屏幕上圈出矩形角点
  14. img.draw_circle(corner[0][0], corner[0][1], 5, color = (0, 0, 255), thickness = 2, fill = False)
  15. img.draw_circle(corner[1][0], corner[1][1], 5, color = (0, 0, 255), thickness = 2, fill = False)
  16. img.draw_circle(corner[2][0], corner[2][1], 5, color = (0, 0, 255), thickness = 2, fill = False)
  17. img.draw_circle(corner[3][0], corner[3][1], 5, color = (0, 0, 255), thickness = 2, fill = False)
  18. # 打印四个角点坐标, 角点1的数组是corner[0], 坐标就是(corner[0][0],corner[0][1])
  19. # 角点检测输出的角点排序每次不一定一致,矩形左上的角点有可能是corner0,1,2,3其中一个
  20. corner1_str = f"corner1 = ({corner[0][0]},{corner[0][1]})"
  21. corner2_str = f"corner2 = ({corner[1][0]},{corner[1][1]})"
  22. corner3_str = f"corner3 = ({corner[2][0]},{corner[2][1]})"
  23. corner4_str = f"corner4 = ({corner[3][0]},{corner[3][1]})"
  24. print(corner1_str + "\n" + corner2_str + "\n" + corner3_str + "\n" + corner4_str)

四、完整程序

这里只给方法一的完整代码,方法二自行替换即可。

  1. import sensor, image, time
  2. import ustruct
  3. from pyb import UART,LED
  4. #****************************阈值调整*******************************
  5. area=(45, 2, 200, 198)
  6. red=(88, 100, -16, 22, -128, 127) #only red
  7. sensor.reset()
  8. sensor.set_pixformat(sensor.RGB565)
  9. sensor.set_framesize(sensor.QVGA)
  10. sensor.set_auto_whitebal(True)
  11. sensor.set_auto_gain(False)
  12. sensor.skip_frames(time = 2000)
  13. sensor.set_vflip(True)
  14. sensor.set_hmirror(True)
  15. #****************************曝光时间*******************************
  16. sensor.set_auto_exposure(False,4500)
  17. clock = time.clock()
  18. #*****************************line_threshold**********************
  19. line_threshold=2500
  20. rect_threshold=10000
  21. uart = UART(3,9600)
  22. uart.init(9600, bits=8, parity=None, stop=1)
  23. def calculate_intersection(line1, line2):
  24. '''
  25. 计算两条线的交点
  26. '''
  27. a1 = line1.y2() - line1.y1()
  28. b1 = line1.x1() - line1.x2()
  29. c1 = line1.x2()*line1.y1() - line1.x1()*line1.y2()
  30. a2 = line2.y2() - line2.y1()
  31. b2 = line2.x1() - line2.x2()
  32. c2 = line2.x2() * line2.y1() - line2.x1()*line2.y2()
  33. if (a1 * b2 - a2 * b1) != 0 and (a2 * b1 - a1 * b2) != 0:
  34. cross_x = int((b1*c2-b2*c1)/(a1*b2-a2*b1))
  35. cross_y = int((c1*a2-c2*a1)/(a1*b2-a2*b1))
  36. return (cross_x, cross_y)
  37. return None
  38. def sending_data(rx,ry,cx,c):
  39. global uart;
  40. data = ustruct.pack("<bhhhhhhhhb",
  41. 0xFF,
  42. int(rx),
  43. int(ry),
  44. int(cx),
  45. int(cy),
  46. int(cw),
  47. int(ch),
  48. int(xx),
  49. int(xy),
  50. int(xw),
  51. int(xh),
  52. 0xFE)
  53. uart.write(data);
  54. cx=0
  55. cy=0
  56. rx=0
  57. ry=0
  58. a=[0,0,0,0,0,0,0,0,0,0]
  59. while(True):
  60. clock.tick()
  61. img = sensor.snapshot().lens_corr(strength = 1.6, zoom = 1.0)
  62. red_point= img.find_blobs([red])
  63. if red_point:
  64. r= red_point[0]
  65. img.draw_rectangle(r[0:4],color=(0,0,0)) # rect
  66. rx=r[5]
  67. ry=r[6]
  68. #print(rx,ry)
  69. #******************************************************************lines*****************
  70. lines = img.find_lines(roi=area, threshold=line_threshold)
  71. i=0
  72. if len(lines)==4 :
  73. theta0=lines[0].theta()
  74. theta1=lines[1].theta()
  75. theta2=lines[2].theta()
  76. theta3=lines[3].theta()
  77. for line in lines:
  78. img.draw_line(line.line(),color=[255,0,0])
  79. if abs(theta0-theta1)>45:
  80. a[i]=calculate_intersection(lines[0],lines[1])[0]
  81. i=i+1
  82. a[i]=calculate_intersection(lines[0],lines[1])[1]
  83. i=i+1
  84. if abs(theta0-theta2)>45:
  85. a[i]=calculate_intersection(lines[0],lines[2])[0]
  86. i=i+1
  87. a[i]=calculate_intersection(lines[0],lines[2])[1]
  88. i=i+1
  89. if abs(theta0-theta3)>45:
  90. a[i]=calculate_intersection(lines[0],lines[3])[0]
  91. i=i+1
  92. a[i]=calculate_intersection(lines[0],lines[3])[1]
  93. i=i+1
  94. if abs(theta1-theta2)>45:
  95. a[i]=calculate_intersection(lines[2],lines[1])[0]
  96. i=i+1
  97. a[i]=calculate_intersection(lines[2],lines[1])[1]
  98. i=i+1
  99. if abs(theta1-theta3)>45:
  100. a[i]=calculate_intersection(lines[1],lines[3])[0]
  101. i=i+1
  102. a[i]=calculate_intersection(lines[1],lines[3])[1]
  103. i=i+1
  104. if abs(theta3-theta2)>45:
  105. a[i]=calculate_intersection(lines[2],lines[3])[0]
  106. i=i+1
  107. a[i]=calculate_intersection(lines[2],lines[3])[1]
  108. i=i+1
  109. print(a)
  110. FH = bytearray([0xFF,rx,ry,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],0xFE])
  111. uart.write(FH)
  112. print(rx,ry)
  113. print(clock.fps())

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/920275
推荐阅读
相关标签
  

闽ICP备14008679号