找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9454|回復(fù): 9
收起左側(cè)

MicroPython openmv識別直角

  [復(fù)制鏈接]
ID:323148 發(fā)表于 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. # 當(dāng)光線弱的時(shí)候,用于補(bǔ)光
  9. LED(4).on()

  10. # 是否開啟debug模式
  11. # 如果是False就不print, 不進(jìn)行可視化繪制,可以提高幀率
  12. is_debug = True
  13. #--------------感光芯片配置  START -------------------

  14. DISTORTION_FACTOR = 1.5 # 設(shè)定畸變系數(shù)
  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)                         # 顏色追蹤關(guān)閉自動增益
  26.     sensor.set_auto_whitebal(False)                     # 顏色追蹤關(guān)閉白平衡

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



  29. #--------------定時(shí)器部分 START -------------------

  30. is_need_send_data = False # 是否需要發(fā)送數(shù)據(jù)的信號標(biāo)志
  31. def uart_time_trigger(timer):
  32.     '''
  33.     串口發(fā)送數(shù)據(jù)的定時(shí)器,定時(shí)器的回調(diào)函數(shù)
  34.     '''
  35.     global is_need_send_data
  36.     is_need_send_data = True

  37. # 初始化定時(shí)器 頻率為20HZ 每秒執(zhí)行20次
  38. tim = Timer(4, freq=20)
  39. # 設(shè)定定時(shí)器的回調(diào)函數(shù)
  40. tim.callback(uart_time_trigger)
  41. #--------------定時(shí)器部分 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), # 縱向取樣-左側(cè) 4
  54.     'right': (56, 0, 8, 64) # 縱向取樣-右側(cè) 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中色塊的中心區(qū)域與是否有色塊的信息
  63.     '''
  64.     global ROIS
  65.     global is_debug

  66.     roi_blobs_result = {}  # 在各個(gè)ROI中尋找色塊的結(jié)果記錄
  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.             # 根據(jù)色塊的寬度進(jìn)行過濾
  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.     可視化結(jié)果
  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的均值點(diǎn)
  96.         canvas.draw_circle(int(cx_mean), mid_y, 5, color=(255))
  97.         # 繪制屏幕中心點(diǎn)
  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' # 啥轉(zhuǎ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' # 左轉(zhuǎn)
  111.     elif is_turn_right:
  112.         turn_type = 'R' # 右轉(zhuǎn)

  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.         # 不需要發(fā)送數(shù)據(jù)
  121.         continue
  122.     is_need_send_data = False

  123.     # 拍攝圖片
  124.     img = sensor.snapshot()
  125.     # 去除圖像畸變
  126.     img.lens_corr(DISTORTION_FACTOR)
  127.     # 創(chuàng)建畫布
  128.     # canvas = img.copy()
  129.     # 為了IDE顯示方便,直接在代碼結(jié)尾 用IMG繪制

  130.     # 注意:林林的代碼里 計(jì)算直線之間的交點(diǎn)的代碼沒有用到
  131.     lines = img.find_lines(threshold=1000, theta_margin = 50, rho_margin = 50)
  132.     # 尋找相交的點(diǎn) 要求滿足角度閾值
  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.     # 判斷是否需要左轉(zhuǎn)與右轉(zhuǎn)
  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形區(qū)域檢測出來的時(shí)候才有用,
  169.     # 用于確定軌道中圓形的大致區(qū)域, 用于定點(diǎn), 是計(jì)算圓心的一種近似方法

  170.     cx = 0
  171.     cy = 0

  172.     if is_cross or is_t:
  173.         # 只在出現(xiàn)十字形或者T字形才計(jì)算圓心坐標(biāo)
  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)
復(fù)制代碼

所有資料51hei提供下載:
源代碼.rar (7.31 KB, 下載次數(shù): 160)


回復(fù)

使用道具 舉報(bào)

ID:511477 發(fā)表于 2019-4-14 20:26 | 顯示全部樓層
感謝樓主,正在做整個(gè)邊緣的識別,希望能有所啟發(fā)。
回復(fù)

使用道具 舉報(bào)

ID:138247 發(fā)表于 2019-4-29 13:24 | 顯示全部樓層

感謝樓主分享。。。
回復(fù)

使用道具 舉報(bào)

ID:255974 發(fā)表于 2019-5-13 16:38 | 顯示全部樓層
GeometryFeature
這個(gè)庫沒有找到,是在哪里呢?
回復(fù)

使用道具 舉報(bào)

ID:277400 發(fā)表于 2019-5-23 21:02 | 顯示全部樓層
感謝樓主
回復(fù)

使用道具 舉報(bào)

ID:581887 發(fā)表于 2019-7-30 14:29 | 顯示全部樓層
有無詳細(xì)介紹
回復(fù)

使用道具 舉報(bào)

ID:527456 發(fā)表于 2019-10-7 08:49 | 顯示全部樓層
plj213 發(fā)表于 2019-4-29 13:24
感謝樓主分享。。。

請問這個(gè)你知道了嗎?
回復(fù)

使用道具 舉報(bào)

ID:712457 發(fā)表于 2020-4-21 09:47 | 顯示全部樓層
逍遙捷 發(fā)表于 2019-5-13 16:38
GeometryFeature
這個(gè)庫沒有找到,是在哪里呢?

下載樓主提供的附件壓縮文件
回復(fù)

使用道具 舉報(bào)

ID:1038167 發(fā)表于 2022-7-3 17:23 | 顯示全部樓層
感謝樓主,正在做相關(guān)十字檢測
回復(fù)

使用道具 舉報(bào)

ID:1066253 發(fā)表于 2023-3-13 17:27 | 顯示全部樓層
感謝樓主、
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表