找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8110|回复: 9
打印 上一主题 下一主题
收起左侧

MicroPython openmv识别直角

  [复制链接]
跳转到指定楼层
楼主
ID:323148 发表于 2018-5-14 21:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
openmv 识别直角


  1. import sensor
  2. import image
  3. import time
  4. import math
  5. import pyb
  6. from pyb import Pin, Timer, UART,LED
  7. from GeometryFeature import GeometryFeature

  8. # 当光线弱的时候,用于补光
  9. LED(4).on()

  10. # 是否开启debug模式
  11. # 如果是False就不print, 不进行可视化绘制,可以提高帧率
  12. is_debug = True
  13. #--------------感光芯片配置  START -------------------

  14. DISTORTION_FACTOR = 1.5 # 设定畸变系数
  15. IMG_WIDTH  = 64
  16. IMG_HEIGHT = 64
  17. def init_sensor():
  18.     '''
  19.     初始化感光芯片
  20.     '''
  21.     sensor.reset()
  22.     sensor.set_pixformat(sensor.GRAYSCALE)
  23.     sensor.set_framesize(sensor.B64X64)                  # 分辨率为B64X64
  24.     sensor.skip_frames(time=2000)
  25.     sensor.set_auto_gain(False)                         # 颜色追踪关闭自动增益
  26.     sensor.set_auto_whitebal(False)                     # 颜色追踪关闭白平衡

  27. init_sensor()
  28. #--------------感光芯片配置  END -------------------



  29. #--------------定时器部分 START -------------------

  30. is_need_send_data = False # 是否需要发送数据的信号标志
  31. def uart_time_trigger(timer):
  32.     '''
  33.     串口发送数据的定时器,定时器的回调函数
  34.     '''
  35.     global is_need_send_data
  36.     is_need_send_data = True

  37. # 初始化定时器 频率为20HZ 每秒执行20次
  38. tim = Timer(4, freq=20)
  39. # 设定定时器的回调函数
  40. tim.callback(uart_time_trigger)
  41. #--------------定时器部分 END -------------------


  42. #--------------直线与直角检测部分 START -------------------

  43. INTERSERCT_ANGLE_THRESHOLD = (45,90)

  44. # 直线灰度图颜色阈值
  45. LINE_COLOR_THRESHOLD = [(0, 120)]
  46. # 如果直线是白色的,阈值修改为:
  47. # LINE_COLOR_THRESHOLD = [(128, 255)]

  48. # 取样窗口
  49. ROIS = {
  50.     'down': (0, 55, 64, 8), # 横向取样-下方 1
  51.     'middle': (0, 28, 64, 8), # 横向取样-中间 2
  52.     'up': (0, 0, 64, 8), # 横向取样-上方 3
  53.     'left': (0, 0, 8, 64), # 纵向取样-左侧 4
  54.     'right': (56, 0, 8, 64) # 纵向取样-右侧 5
  55. }


  56. BLOB_MAX_WIDTH = 15 # 色块的最大宽度
  57. BLOB_MIN_WIDTH = 5 # 色块的最小宽度
  58. BLOB_MAX_HEIGHT = 15 # 色块的最大高度
  59. BLOB_MIN_HEIGHT = 5 # 色块的最小宽度


  60. def find_blobs_in_rois(img):
  61.     '''
  62.     在ROIS中寻找色块,获取ROI中色块的中心区域与是否有色块的信息
  63.     '''
  64.     global ROIS
  65.     global is_debug

  66.     roi_blobs_result = {}  # 在各个ROI中寻找色块的结果记录
  67.     for roi_direct in ROIS.keys():
  68.         roi_blobs_result[roi_direct] = {
  69.             'cx': -1,
  70.             'cy': -1,
  71.             'blob_flag': False
  72.         }
  73.     for roi_direct, roi in ROIS.items():
  74.         blobs=img.find_blobs(LINE_COLOR_THRESHOLD, roi=roi, merge=True, pixels_area=10)
  75.         if len(blobs) == 0:
  76.             continue

  77.         largest_blob = max(blobs, key=lambda b: b.pixels())
  78.         x,y,width,height = largest_blob[:4]

  79.         if not(width >= BLOB_MIN_WIDTH and width <= BLOB_MAX_WIDTH and height >= BLOB_MIN_HEIGHT and height <= BLOB_MAX_HEIGHT):
  80.             # 根据色块的宽度进行过滤
  81.             continue

  82.         roi_blobs_result[roi_direct]['cx'] = largest_blob.cx()
  83.         roi_blobs_result[roi_direct]['cy'] = largest_blob.cy()
  84.         roi_blobs_result[roi_direct]['blob_flag'] = True

  85.         if is_debug:
  86.             img.draw_rectangle((x,y,width, height), color=(255))

  87.     return roi_blobs_result

  88. def visualize_result(canvas, cx_mean, cx, cy, is_turn_left, is_turn_right, is_t, is_cross):
  89.     '''
  90.     可视化结果
  91.     '''
  92.     if not(is_turn_left or is_turn_right or is_t or is_cross):
  93.         mid_x = int(canvas.width()/2)
  94.         mid_y = int(canvas.height()/2)
  95.         # 绘制x的均值点
  96.         canvas.draw_circle(int(cx_mean), mid_y, 5, color=(255))
  97.         # 绘制屏幕中心点
  98.         canvas.draw_circle(mid_x, mid_y, 8, color=(0))
  99.         canvas.draw_line((mid_x, mid_y, int(cx_mean), mid_y), color=(255))

  100.     turn_type = 'N' # 啥转角也不是

  101.     if is_t or is_cross:
  102.         # 十字形或者T形
  103.         canvas.draw_cross(int(cx), int(cy), size=10, color=(255))
  104.         canvas.draw_circle(int(cx), int(cy), 5, color=(255))

  105.     if is_t:
  106.         turn_type = 'T' # T字形状
  107.     elif is_cross:
  108.         turn_type = 'C' # 十字形
  109.     elif is_turn_left:
  110.         turn_type = 'L' # 左转
  111.     elif is_turn_right:
  112.         turn_type = 'R' # 右转

  113.     canvas.draw_string(0, 0, turn_type, color=(0))




  114. #--------------直线与直角检测部分 END -------------------


  115. #---------------------MAIN-----------------------
  116. last_cx = 0
  117. last_cy = 0

  118. while True:
  119.     if not is_need_send_data:
  120.         # 不需要发送数据
  121.         continue
  122.     is_need_send_data = False

  123.     # 拍摄图片
  124.     img = sensor.snapshot()
  125.     # 去除图像畸变
  126.     img.lens_corr(DISTORTION_FACTOR)
  127.     # 创建画布
  128.     # canvas = img.copy()
  129.     # 为了IDE显示方便,直接在代码结尾 用IMG绘制

  130.     # 注意:林林的代码里 计算直线之间的交点的代码没有用到
  131.     lines = img.find_lines(threshold=1000, theta_margin = 50, rho_margin = 50)
  132.     # 寻找相交的点 要求满足角度阈值
  133.     intersect_pt = GeometryFeature.find_interserct_lines(lines, angle_threshold=(45,90), window_size=(IMG_WIDTH, IMG_HEIGHT))
  134.     if intersect_pt is None:
  135.         # 直线与直线之间的夹角不满足阈值范围
  136.         intersect_x = 0
  137.         intersect_y = 0
  138.     else:
  139.         intersect_x, intersect_y = intersect_pt

  140.     reslut = find_blobs_in_rois(img)

  141.     # 判断是否需要左转与右转
  142.     is_turn_left = False
  143.     is_turn_right = False


  144.     if (not reslut['up']['blob_flag'] ) and reslut['down']['blob_flag']:
  145.         if reslut['left']['blob_flag']:
  146.             is_turn_left = True
  147.         if reslut['right']['blob_flag']:
  148.             is_turn_right = True


  149.     # 判断是否为T形的轨道
  150.     is_t = False
  151.     # 判断是否十字形轨道
  152.     is_cross = False

  153.     cnt = 0
  154.     for roi_direct in ['up', 'down', 'left', 'right']:
  155.         if reslut[roi_direct]['blob_flag']:
  156.             cnt += 1
  157.     is_t = cnt == 3
  158.     is_cross = cnt == 4

  159.     # cx_mean 用于确定视角中的轨道中心
  160.     # 用于表示左右偏移量
  161.     cx_mean = 0
  162.     for roi_direct in ['up', 'down', 'middle']:
  163.         if reslut[roi_direct]['blob_flag']:
  164.             cx_mean += reslut[roi_direct]['cx']
  165.         else:
  166.             cx_mean += IMG_WIDTH / 2
  167.     cx_mean /= 3

  168.     # cx, cy 只有在T形区域检测出来的时候才有用,
  169.     # 用于确定轨道中圆形的大致区域, 用于定点, 是计算圆心的一种近似方法

  170.     cx = 0
  171.     cy = 0

  172.     if is_cross or is_t:
  173.         # 只在出现十字形或者T字形才计算圆心坐标
  174.         cnt = 0
  175.         for roi_direct in ['up', 'down']:
  176.             if reslut[roi_direct]['blob_flag']:
  177.                 cnt += 1
  178.                 cx += reslut[roi_direct]['cx']
  179.         if cnt == 0:
  180.             cx = last_cx
  181.         else:
  182.             cx /= cnt

  183.         cnt = 0
  184.         for roi_direct in ['left', 'right']:
  185.             if reslut[roi_direct]['blob_flag']:
  186.                 cnt += 1
  187.                 cy += reslut[roi_direct]['cy']
  188.         if cnt == 0:
  189.             cy = last_cy
  190.         else:
  191.             cy /= cnt


  192.     last_cx = cx
  193.     last_cy = cy

  194.     if is_debug:
  195.         visualize_result(img, cx_mean, cx, cy, is_turn_left, is_turn_right, is_t, is_cross)
复制代码

所有资料51hei提供下载:
源代码.rar (7.31 KB, 下载次数: 156)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:511477 发表于 2019-4-14 20:26 | 只看该作者
感谢楼主,正在做整个边缘的识别,希望能有所启发。
回复

使用道具 举报

板凳
ID:138247 发表于 2019-4-29 13:24 | 只看该作者

感谢楼主分享。。。
回复

使用道具 举报

地板
ID:255974 发表于 2019-5-13 16:38 | 只看该作者
GeometryFeature
这个库没有找到,是在哪里呢?
回复

使用道具 举报

5#
ID:277400 发表于 2019-5-23 21:02 | 只看该作者
感谢楼主
回复

使用道具 举报

6#
ID:581887 发表于 2019-7-30 14:29 | 只看该作者
有无详细介绍
回复

使用道具 举报

7#
ID:527456 发表于 2019-10-7 08:49 | 只看该作者
plj213 发表于 2019-4-29 13:24
感谢楼主分享。。。

请问这个你知道了吗?
回复

使用道具 举报

8#
ID:712457 发表于 2020-4-21 09:47 | 只看该作者
逍遥捷 发表于 2019-5-13 16:38
GeometryFeature
这个库没有找到,是在哪里呢?

下载楼主提供的附件压缩文件
回复

使用道具 举报

9#
ID:1038167 发表于 2022-7-3 17:23 | 只看该作者
感谢楼主,正在做相关十字检测
回复

使用道具 举报

10#
ID:1066253 发表于 2023-3-13 17:27 | 只看该作者
感谢楼主、
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表