OpenMV(一)–基础介绍与硬件架构
OpenMV(二)–IDE安装与固件下载
OpenMV(三)–实时获取摄像头图片
本专栏基于以STM32H743为MCU的OpenMV-H7基板,结合OV7725卷帘快门摄像头进行相关机器视觉应用的开发。特征检测是机器视觉的基础,要做的内容包括边缘检测、各种形状识别、特征点识别等。特征检测是基于摄像头获取的图片进行的,在进行特征检测之间,我们需要了解如果在获取的图像上画标记。
OpenMV已经将图片处理封装成各类模块供我们使用:
image.draw_line( x 0 x_0 x0, y 0 y_0 y0, x 1 x_1 x1, y 1 y_1 y1, color, thickness = 1)
画线段
image.draw_rectangle(x, y, w, h, color, thickness = 1, fill = false)
画矩形
image.draw_circle(x, y, radius, color, thickness = 1, fill = false)
画圆形
image.draw_cross(x, y, color, size = 5, thickness = 1)
画十字交叉
image.draw_string(x, y, text, color,scale = 1, mono_space = True…)
写字符
边缘检测就是轮廓检测,本节基于OpenMV官方源码edges.py来完成实时轮廓提取。
OpenMV的库集成度非常高,只需要一个函数就可以进行图片的边缘检测。
"""
实时特征检测例程:使用canny特征检测算法
"""
# 导入相应的库
import sensor, image, time
# 初始化摄像头
sensor.reset()
# 设置采集到照片的格式:灰色图像
sensor.set_pixformat(sensor.GRAYSCALE)
# 设置采集到照片的大小: 320 * 240
sensor.set_framesize(sensor.QVGA)
# 等待一段时间2s,等摄像头设置好
sensor.skip_frames(time = 2000)
# 设定摄像头增益上限
sensor.set_gainceiling(8)
# 创建一个时钟来计算摄像头每秒采集的帧数FPS
clock = time.clock()
# 实时显示摄像头拍摄的照片
while(True):
# 更新FPS时钟
clock.tick()
# 拍摄图片并返回img
img = sensor.snapshot()
# 使用canny边缘检测
img.find_edges(image.EDGE_CANNY, threshold = (50, 80))
# 串口打印FPS参数
print(clock.fps())
我们将板子连接到OpenMV IDE, 新建文件,并将上述代码copy进去,点击左下角的绿色按钮,我们就可以看到IDE右边的窗口在实时显示提取到的边缘特征图片:
线段识别,直线识别与边缘识别原理近似,只是调用的函数不同,具体操作可以参考官方提供的源码。
本节的目标是识别摄像头采集图像中的圆形并画出来。构造函数如下:
"""
实时圆形特征检测例程:使用霍夫变换算法
"""
# 导入相应的库
import sensor, image, time
# 初始化摄像头
sensor.reset()
# 设置采集到照片的格式:彩色RGB,使用灰色图像会加快检测速度
sensor.set_pixformat(sensor.RGB565)
# 设置采集到照片的大小: 320 * 240
sensor.set_framesize(sensor.QQVGA)
# 等待一段时间2s,等摄像头设置好
sensor.skip_frames(time = 2000)
# 创建一个时钟来计算摄像头每秒采集的帧数FPS
clock = time.clock()
# 实时显示摄像头拍摄的照片
while(True):
# 更新FPS时钟
clock.tick()
# 拍摄图片并返回img, lens_corr()目的是去畸变,1.8是默认值
img = sensor.snapshot().lens_corr(1.8)
# 检测圆形, 并在图像上画出。 parms时检测圆形返回的对象参数,包括圆心(x,y), 半径( r), 量级(magnitude)
for params in img.find_circles(threshold = 2000,
x_margin = 10, y_margin = 10, r_margin = 10,
r_min = 2, r_max = 100,
r_step = 2):
# 将圆画出来
img.draw_circle(params.x(), params.y(), params.r(), color = (255, 0, 0))
# 将圆的参数信息打印出来
print(params)
# 串口打印FPS参数
print(clock.fps())
我们将板子连接到OpenMV IDE, 新建文件,并将上述代码copy进去,点击左下角的绿色按钮,我们就可以看到IDE右边的窗口在实时显示提取到的圆形特征:
矩形识别与圆形识别原理近似,只是调用的函数不同,具体操作可以参考官方提供的源码。
本小节实现的特征点识别,首先对采集到的图案或者物体进行学习识别,然后当摄像头重新抓捕到跟学习的目标特征点一样的图片时,就标记出来。
image.find_keypoints(roi, threshold=20, normalized=False, scale_factor=1.5, max_keypoints=100, corner_detector=image.CORNER_AGAST)
特征点识别函数,返回一个image.rect矩形对象列表
image.match_descriptor(descriptor0, descriptor1, threshold=70, filter_outliers=False)
特征点对比函数,用于比较两个特征点的相似程度。返回的是一个kptmatch对象。
特征点识别的步骤如下:
导入相应库–> 初始化相机模块–>拍摄图像并学习特征点K1–>实时采集当前特征点K2–>对比K1和K2是否一致–>如果一致则标记特征点位置
"""
实时特征点检测例程
"""
# 导入相应的库
import sensor, image, time
# 初始化摄像头
sensor.reset()
# 设置相机对比度
sensor.set_contrast(3)
# 设定摄像头增益上限
sensor.set_gainceiling(16)
# 设置采集到照片的大小
sensor.set_framesize(sensor.VGA)
# 设置相机分辨率
sensor.set_windowing((320, 240))
# 设置采集到照片的格式:灰色图像
sensor.set_pixformat(sensor.GRAYSCALE)
# 等待一段时间2s,等摄像头设置好
sensor.skip_frames(time = 2000)
# 关闭摄像头自动增益并设定固定增益值为100
sensor.set_auto_gain(False, value = 100)
"""
定义画特征点函数
"""
def draw_keypoints(img, kpts):
if kpts:
print(kpts)
img.draw_keypoints(kpts)
img = sensor.snapshot()
time.sleep(1000)
# 初始化特征点
kpts1 = None
kpts2 = None
"""
我们也可以从文件中导入特征点
kpts1 = image.load_descriptor("/desc.orb")
img = sensor.snapshot()
draw_keypoints(img, kpts1)
"""
while(True):
# 拍摄图片并返回img
img = sensor.snapshot()
# 如果特征点K1不存在,就学习摄像头所拍摄图片的特征点
if(kpts1 == None):
kpts1 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=1.2)
# 画出特征点
draw_keypoints(img,kpts1)
# 如果特征点K1存在,就检测特征点K2,然后比较二者是否一致
else:
kpts2 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True)
if (kpts2):
# 如果特征点K2存在,匹配两个特征
match = image.match_descriptor(kpts1, kpts2, threshold=85)
# 大于10可以判断为两个特征点一致,这个值可以调节
if(match.count()>10):
# 将一致的特征用十字交叉和矩形圈出
img.draw_rectangle(match.rect())
img.draw_cross(match.cx(), match.cy(), size = 10)
我们将板子连接到OpenMV IDE, 新建文件,并将上述代码copy进去,点击左下角的绿色按钮,我们首先看到摄像头在学习特征点,并标记了出来:
然后,再次进行检测,并标记特征点相同的地方: