标题:
MicroPython openmv识别直角
[打印本页]
作者:
孙权跑
时间:
2018-5-14 21:23
标题:
MicroPython openmv识别直角
openmv 识别直角
import sensor
import image
import time
import math
import pyb
from pyb import Pin, Timer, UART,LED
from GeometryFeature import GeometryFeature
# 当光线弱的时候,用于补光
LED(4).on()
# 是否开启debug模式
# 如果是False就不print, 不进行可视化绘制,可以提高帧率
is_debug = True
#--------------感光芯片配置 START -------------------
DISTORTION_FACTOR = 1.5 # 设定畸变系数
IMG_WIDTH = 64
IMG_HEIGHT = 64
def init_sensor():
'''
初始化感光芯片
'''
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.B64X64) # 分辨率为B64X64
sensor.skip_frames(time=2000)
sensor.set_auto_gain(False) # 颜色追踪关闭自动增益
sensor.set_auto_whitebal(False) # 颜色追踪关闭白平衡
init_sensor()
#--------------感光芯片配置 END -------------------
#--------------定时器部分 START -------------------
is_need_send_data = False # 是否需要发送数据的信号标志
def uart_time_trigger(timer):
'''
串口发送数据的定时器,定时器的回调函数
'''
global is_need_send_data
is_need_send_data = True
# 初始化定时器 频率为20HZ 每秒执行20次
tim = Timer(4, freq=20)
# 设定定时器的回调函数
tim.callback(uart_time_trigger)
#--------------定时器部分 END -------------------
#--------------直线与直角检测部分 START -------------------
INTERSERCT_ANGLE_THRESHOLD = (45,90)
# 直线灰度图颜色阈值
LINE_COLOR_THRESHOLD = [(0, 120)]
# 如果直线是白色的,阈值修改为:
# LINE_COLOR_THRESHOLD = [(128, 255)]
# 取样窗口
ROIS = {
'down': (0, 55, 64, 8), # 横向取样-下方 1
'middle': (0, 28, 64, 8), # 横向取样-中间 2
'up': (0, 0, 64, 8), # 横向取样-上方 3
'left': (0, 0, 8, 64), # 纵向取样-左侧 4
'right': (56, 0, 8, 64) # 纵向取样-右侧 5
}
BLOB_MAX_WIDTH = 15 # 色块的最大宽度
BLOB_MIN_WIDTH = 5 # 色块的最小宽度
BLOB_MAX_HEIGHT = 15 # 色块的最大高度
BLOB_MIN_HEIGHT = 5 # 色块的最小宽度
def find_blobs_in_rois(img):
'''
在ROIS中寻找色块,获取ROI中色块的中心区域与是否有色块的信息
'''
global ROIS
global is_debug
roi_blobs_result = {} # 在各个ROI中寻找色块的结果记录
for roi_direct in ROIS.keys():
roi_blobs_result[roi_direct] = {
'cx': -1,
'cy': -1,
'blob_flag': False
}
for roi_direct, roi in ROIS.items():
blobs=img.find_blobs(LINE_COLOR_THRESHOLD, roi=roi, merge=True, pixels_area=10)
if len(blobs) == 0:
continue
largest_blob = max(blobs, key=lambda b: b.pixels())
x,y,width,height = largest_blob[:4]
if not(width >= BLOB_MIN_WIDTH and width <= BLOB_MAX_WIDTH and height >= BLOB_MIN_HEIGHT and height <= BLOB_MAX_HEIGHT):
# 根据色块的宽度进行过滤
continue
roi_blobs_result[roi_direct]['cx'] = largest_blob.cx()
roi_blobs_result[roi_direct]['cy'] = largest_blob.cy()
roi_blobs_result[roi_direct]['blob_flag'] = True
if is_debug:
img.draw_rectangle((x,y,width, height), color=(255))
return roi_blobs_result
def visualize_result(canvas, cx_mean, cx, cy, is_turn_left, is_turn_right, is_t, is_cross):
'''
可视化结果
'''
if not(is_turn_left or is_turn_right or is_t or is_cross):
mid_x = int(canvas.width()/2)
mid_y = int(canvas.height()/2)
# 绘制x的均值点
canvas.draw_circle(int(cx_mean), mid_y, 5, color=(255))
# 绘制屏幕中心点
canvas.draw_circle(mid_x, mid_y, 8, color=(0))
canvas.draw_line((mid_x, mid_y, int(cx_mean), mid_y), color=(255))
turn_type = 'N' # 啥转角也不是
if is_t or is_cross:
# 十字形或者T形
canvas.draw_cross(int(cx), int(cy), size=10, color=(255))
canvas.draw_circle(int(cx), int(cy), 5, color=(255))
if is_t:
turn_type = 'T' # T字形状
elif is_cross:
turn_type = 'C' # 十字形
elif is_turn_left:
turn_type = 'L' # 左转
elif is_turn_right:
turn_type = 'R' # 右转
canvas.draw_string(0, 0, turn_type, color=(0))
#--------------直线与直角检测部分 END -------------------
#---------------------MAIN-----------------------
last_cx = 0
last_cy = 0
while True:
if not is_need_send_data:
# 不需要发送数据
continue
is_need_send_data = False
# 拍摄图片
img = sensor.snapshot()
# 去除图像畸变
img.lens_corr(DISTORTION_FACTOR)
# 创建画布
# canvas = img.copy()
# 为了IDE显示方便,直接在代码结尾 用IMG绘制
# 注意:林林的代码里 计算直线之间的交点的代码没有用到
lines = img.find_lines(threshold=1000, theta_margin = 50, rho_margin = 50)
# 寻找相交的点 要求满足角度阈值
intersect_pt = GeometryFeature.find_interserct_lines(lines, angle_threshold=(45,90), window_size=(IMG_WIDTH, IMG_HEIGHT))
if intersect_pt is None:
# 直线与直线之间的夹角不满足阈值范围
intersect_x = 0
intersect_y = 0
else:
intersect_x, intersect_y = intersect_pt
reslut = find_blobs_in_rois(img)
# 判断是否需要左转与右转
is_turn_left = False
is_turn_right = False
if (not reslut['up']['blob_flag'] ) and reslut['down']['blob_flag']:
if reslut['left']['blob_flag']:
is_turn_left = True
if reslut['right']['blob_flag']:
is_turn_right = True
# 判断是否为T形的轨道
is_t = False
# 判断是否十字形轨道
is_cross = False
cnt = 0
for roi_direct in ['up', 'down', 'left', 'right']:
if reslut[roi_direct]['blob_flag']:
cnt += 1
is_t = cnt == 3
is_cross = cnt == 4
# cx_mean 用于确定视角中的轨道中心
# 用于表示左右偏移量
cx_mean = 0
for roi_direct in ['up', 'down', 'middle']:
if reslut[roi_direct]['blob_flag']:
cx_mean += reslut[roi_direct]['cx']
else:
cx_mean += IMG_WIDTH / 2
cx_mean /= 3
# cx, cy 只有在T形区域检测出来的时候才有用,
# 用于确定轨道中圆形的大致区域, 用于定点, 是计算圆心的一种近似方法
cx = 0
cy = 0
if is_cross or is_t:
# 只在出现十字形或者T字形才计算圆心坐标
cnt = 0
for roi_direct in ['up', 'down']:
if reslut[roi_direct]['blob_flag']:
cnt += 1
cx += reslut[roi_direct]['cx']
if cnt == 0:
cx = last_cx
else:
cx /= cnt
cnt = 0
for roi_direct in ['left', 'right']:
if reslut[roi_direct]['blob_flag']:
cnt += 1
cy += reslut[roi_direct]['cy']
if cnt == 0:
cy = last_cy
else:
cy /= cnt
last_cx = cx
last_cy = cy
if is_debug:
visualize_result(img, cx_mean, cx, cy, is_turn_left, is_turn_right, is_t, is_cross)
复制代码
所有资料51hei提供下载:
源代码.rar
(7.31 KB, 下载次数: 160)
2018-5-14 21:22 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
棉城乖宝宝
时间:
2019-4-14 20:26
感谢楼主,正在做整个边缘的识别,希望能有所启发。
作者:
plj213
时间:
2019-4-29 13:24
感谢楼主分享。。。
作者:
逍遥捷
时间:
2019-5-13 16:38
GeometryFeature
这个库没有找到,是在哪里呢?
作者:
船长Fengi
时间:
2019-5-23 21:02
感谢楼主
作者:
wu123456789
时间:
2019-7-30 14:29
有无详细介绍
作者:
tytytyty......
时间:
2019-10-7 08:49
plj213 发表于 2019-4-29 13:24
感谢楼主分享。。。
请问这个你知道了吗?
作者:
孟祥平
时间:
2020-4-21 09:47
逍遥捷 发表于 2019-5-13 16:38
GeometryFeature
这个库没有找到,是在哪里呢?
下载楼主提供的附件压缩文件
作者:
当地的方言
时间:
2022-7-3 17:23
感谢楼主,正在做相关十字检测
作者:
refghkl
时间:
2023-3-13 17:27
感谢楼主、
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1