当前位置:   article > 正文

2023年电赛E题(运动目标控制与自动追踪系统)——视觉部分以及总结_2023全国大学生电子设计大赛题目

2023全国大学生电子设计大赛题目

前言

        虽然是第一次参加全国大学生电子设计大赛的新手,但是也是信心满满的完成这次四天三夜的电赛。由于我是负责视觉方面的,所以在此分享一下我做视觉处理的经验。接着就废话少说,看看我的方案吧!

一、题目分析

        首先,当看到这个题目的时候就感觉这个题目相对来说不是那么的难,但还是有一些坑在里面的。从题目里面就能够分析出我们需要将红色激光点以及A4纸黑色方框识别出来,怎么去识别就成为了接下来讨论的问题了。首先我们开始准备的是Openmv4 Plus这一款,因为这个要比普通款的算力要更加强大,确实到后面普通款实在是跑不掉我的能够代码,所以硬件也应该保证上。

1.激光头识别

        其实激光头识别映射到我们平时的应用当中就是色块识别,就是在图像中去识别设置好的阈值色块。但是在做到基础三的过程当中会遇到当红色激光笔走到黑线框的时候,红色激光被黑色吸收了导致阈值识别不到。这时有的人说可以用设置为灰度图像,调节亮度啥的。但是最后我还是参考的另一个博主的方法就是用曝光度来调节一个阈值,再带入到色块的阈值里。实在不行就在摄像头上再加上一个滤光片,这样也有一定的效果。

  1. import sensor, image, time
  2. sensor.reset()
  3. sensor.set_pixformat(sensor.RGB565)
  4. sensor.set_framesize(sensor.QVGA)
  5. sensor.skip_frames(time = 2000)
  6. # 您必须关闭自动增益控制和自动白平衡,否则他们将更改图像增益以撤消您放置的任何曝光设置
  7. sensor.set_auto_gain(False)
  8. sensor.set_auto_whitebal(False)
  9. sensor.set_auto_exposure(False, 2000) #调节曝光度
  10. clock = time.clock()
  11. while(True):
  12. clock.tick()
  13. img = sensor.snapshot()
  14. print(clock.fps())

        接着将调节好的阈值带入到寻找色块的代码当中,注意在用find_blobs()函数时要将area_threshold这个色块面积大小的参数调小一点大概在2~6左右。因为我们开始在调的过程当中就是把这个参数调到了15就导致了那个色块一直在抖,只要把这个色块面积调小一点就解决了。

img.find_blobs(red_td_01, roi=ROI_TH, pixels_threshold=2, area_threshold=5, merge=True, invert=0)

2.黑色方框识别

        其实识别黑色方框也不是很难的问题,直接使用OPENMV官方库的寻找矩形函数find_rects()。

 

二、重点难点

通过四天三夜的比赛以及赛后的总结分析后,我在看来重点难点有以下几个方面:

  1. 首先就是在你摄像头运行的过程中千万不能移动,要保证摄像头固定住。在测评的时候就有可能因为这个原因导致坐标点的数据产生偏差,也就前功尽弃了。
  2. 在摄像头拍摄的照片里面如果有包含背景那么就要将背景给去除。而去除的方法也十分简单,就是划分图像中的感兴趣区域。(我划分的感兴趣区域就是对应到实际的0.6*0.6的方框上的,比0.5*0.5的方框要大一点,提高了容错率。)
  3. 对于激光点的坐标,我的想法是在感兴趣区域内设置相对坐标,将左上角设置为坐标原点,那么激光点的坐标永远都在第四象限。还有就是在不同的环境下的阈值问题,后面我们是加入了多阈值识别来进行解决的。
    1. # 在图像中寻找红色激光笔 多阈值的寻找红色激光点
    2. light_01 = img.find_blobs(red_td_01, roi=ROI_TH, pixels_threshold=1, area_threshold=2, merge=True, invert=0)
    3. light_02 = img.find_blobs(red_td_02, roi=ROI_TH, pixels_threshold=1, area_threshold=2, merge=True, invert=0)
    4. light_03 = img.find_blobs(red_td_03, roi=ROI_TH, pixels_threshold=1, area_threshold=2, merge=True, invert=0)
  4. 还有黑色矩形框的识别,在比赛的过程中发现当矩形框下向左或向右倾斜时它识别的矩形框不一样,有时候是外框,有时候是内框。并且有时候还会识别错误。所以在识别时应该加入前50次的总数判断,这样能够提高识别率。

三、OPENMV代码

        接下共享部分代码:

  1. uart = pyb.UART(3, 115200) # 串口3初始化,波特率115200
  2. uart.init(115200, bits=8, parity=None, stop=1) # 8位数据位,无校验位,1位停止位
  3. RIO = (92, 42, 180, 175) #外框
  4. def return_zuobiao(x, y): # 矫正相对坐标的函数
  5. x = (x - 92)
  6. y = -(y - 42)
  7. return x, y
  8. def find_mode(nums): # 求解列表中的众数
  9. if nums is not None:
  10. num_count = {0:0}
  11. for num in nums:
  12. if num in num_count:
  13. num_count[num] += 1
  14. else:
  15. num_count[num] = 1
  16. mode = max(num_count, key=num_count.get)
  17. return mode
  18. def find_max(blobs): # 寻找范围内的最大色块
  19. max_size=0
  20. for blob in blobs:
  21. if blob.pixels() > max_size:
  22. max_blob = blob
  23. max_size = blob.pixels()
  24. return max_blob
  25. while(True):
  26. clock.tick()
  27. img = sensor.snapshot().lens_corr(strength = 1.8 , zoom = 1.0)
  28. img.draw_rectangle(RIO, color=(255, 0, 0), scale=4)
  29. #img.draw_rectangle(ROI_TH, color=(0, 255, 0), scale=4)
  30. # -----矩形框部分-----
  31. # 在图像中寻找矩形
  32. if (flag<50): # 在外框内寻找矩形框
  33. for r in img.find_rects(roi= RIO,threshold = 5000):
  34. # 判断矩形边长是否符合要求
  35. # 判断矩形框大于45度时
  36. if r.w() > 90 and r.h() > 90 and r.w() < 150 and r.h() < 150:
  37. # 在屏幕上框出矩形
  38. img.draw_rectangle(r.rect(), color = (255, 0, 0), scale = 2)
  39. # 获取矩形角点位置
  40. corner = r.corners()
  41. # 标记出矩形框四个角的位置
  42. img.draw_circle(corner[0][0], corner[0][1], 2, color = (0, 0, 255), thickness = 2, fill = False)
  43. img.draw_circle(corner[1][0], corner[1][1], 2, color = (0, 0, 255), thickness = 2, fill = False)
  44. img.draw_circle(corner[2][0], corner[2][1], 2, color = (0, 0, 255), thickness = 2, fill = False)
  45. img.draw_circle(corner[3][0], corner[3][1], 2, color = (0, 0, 255), thickness = 2, fill = False)
  46. if r.w() < 90 and r.h() < 90:
  47. # 在屏幕上框出矩形
  48. img.draw_rectangle(r.rect(), color = (255, 0, 0), scale = 2)
  49. # 获取矩形角点位置
  50. corner = r.corners()
  51. # 在屏幕上圈出矩形角点
  52. img.draw_circle(corner[0][0], corner[0][1], 2, color = (0, 0, 255), thickness = 2, fill = False)
  53. img.draw_circle(corner[1][0], corner[1][1], 2, color = (0, 0, 255), thickness = 2, fill = False)
  54. img.draw_circle(corner[2][0], corner[2][1], 2, color = (0, 0, 255), thickness = 2, fill = False)
  55. img.draw_circle(corner[3][0], corner[3][1], 2, color = (0, 0, 255), thickness = 2, fill = False)
  56. # -----激光笔部分-----
  57. # 在图像中寻找红色激光笔 多阈值的寻找红色激光点
  58. light_01 = img.find_blobs(red_td_01, roi=ROI_TH, pixels_threshold=1, area_threshold=2, merge=True, invert=0)
  59. light_02 = img.find_blobs(red_td_02, roi=ROI_TH, pixels_threshold=1, area_threshold=2, merge=True, invert=0)
  60. light_03 = img.find_blobs(red_td_03, roi=ROI_TH, pixels_threshold=1, area_threshold=2, merge=True, invert=0)
  61. if light_01:
  62. light_01_max = find_max(light_01)
  63. x0, y0 = return_zuobiao(light_01_max[5], light_01_max[6])
  64. print("黑",x0, y0)
  65. img.draw_rectangle(light_01_max.rect(), color = (255, 0, 0), scale = 2)
  66. elif light_02:
  67. light_02_max = find_max(light_02)
  68. x0, y0 = return_zuobiao(light_02_max[5], light_02_max[6])
  69. img.draw_rectangle(light_02_max.rect(), color = (0, 255, 0), scale = 2)
  70. print("偏暗",x0, y0)
  71. elif light_03:
  72. light_03_max = find_max(light_03)
  73. x0, y0 = return_zuobiao(light_03_max[5], light_03_max[6])
  74. img.draw_rectangle(light_03_max.rect(), color = (0, 0, 255), scale = 2)
  75. print("偏亮",x0, y0)
  76. # -----寻找众数坐标部分-----
  77. if (flag == 50):
  78. x1_mode = find_mode(list_x1)
  79. x2_mode = find_mode(list_x2)
  80. x3_mode = find_mode(list_x3)
  81. x4_mode = find_mode(list_x4)
  82. y1_mode = find_mode(list_y1)
  83. y2_mode = find_mode(list_y2)
  84. y3_mode = find_mode(list_y3)
  85. y4_mode = find_mode(list_y4)
  86. magnitude_mode = find_mode(list_magnitude)
  87. flag+=1
  88. else:
  89. send_data_packet(x0, y0, # 串口发送
  90. x1_mode, y1_mode,
  91. x2_mode, y2_mode,
  92. x3_mode, y3_mode,
  93. x4_mode, y4_mode)

四、总结

        作为第一次参加电赛的人来说,拿到省一这个成绩也相当不错了,就是不知道后面能不能进国赛了。其实开始我们队在第二天的时候就将基础部做的差不多了,第三天就开始在调后面的了,但是确实有点没有想全面导致我们的效果不太好,结果第四天都还在完善。但是最后结果还算是好的。由于我们是第一次打电赛,所以我们的经验还是欠缺一些浪费了很多时间,以及在一些小细节方面还做的不是很好。但是未来还有机会做的更好。

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

闽ICP备14008679号