OpenMV自学笔记1
目的
学习OpenMV是为了准备农业机器人大赛,也是为了后续课题中使用图像处理。主要目的是:使用OpenMV识别到物体(色块),并将色块信息(位置、大小等)输出到arduino单片机上,通过单片机操纵机械臂对物体进一步操作。
笔记内容
主要学习星瞳科技的OpenMV教程,以下为笔记内容:
寻找色块
目的:找到色块。
示例位置:文件->示例->Color-Tracking->single_color rgb565 blob tracking.py
for blob in img.find_blobs(thresholds, roi=Auto, x_stride=2, y_stride=1, invert=False, area_threshold=10, pixels_threshold=10, merge=False, margin=0, threshold_cb=None, merge_cb=None)
这里参数众多,以下只记录对我有用的部分,完整查看link
1.for blob in img.find_blobs:即使用for循环遍历一个snapshot中的所有色块进行操作,其中blob为变量单个色块,find_blobs为列表,包含很多blob。
2.thresholds:颜色的阈值,这个参数是一个列表,可以包含多个颜色,可使用阈值编辑器(工具->机器视觉->阈值编辑器->帧缓冲区 将所选物体调为白色,复制下方LAB阈值到thresholds中)选择所要颜色(这里也可以在IDE右方帧缓冲区框出色块,看着直方图LAB色彩空间调节)。
3.x_stride与y_stride:色块在XY方向上的最小像素宽度,过滤掉过小色块。
4.area_threshold:面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉。
5.pixels_threshold:像素个数阈值,如果色块像素数量小于这个值,会被过滤掉。
对blob对象操作
目的:获得色块大小、像素坐标系位置等信息。
blob有多个方法:
返回值 | 代码 |
---|---|
色块的外框的宽度w(int) | blob.w()或blob[2] |
色块的外框的高度h(int) | blob.h() 或blob[3] |
色块的像素数量(int) | blob.pixels() 或blob[4] |
色块的外框的中心x坐标(int) | blob.cx() 或blob[5] |
色块的外框的中心y坐标(int) | blob.cy() 或blob[6] |
色块的外框的面积 | blob.area() |
AprilTag标记跟踪
目的:通过计算将获得的像素坐标系转换成现实中的平面坐标系(高度一定)。
由于镜头会有畸变,因此需要对OpenMV进行标定,OpenMV自带函数库中只有image.lens_corr([strength=1.8[, zoom=1.0]])命令可以对镜头畸变进一步校正(也可购买无畸变镜头),链接如下:
link
link
对OpenMV标定后需要通过AprilTag获得像素坐标系与现实平面坐标系的转化计算方法。
制作AprilTag:工具->机器视觉->AprilTag生成器->TAG36H11(推荐),输入需要的AprilTag数,保存图片并打印出来(大小无所谓)。
使用link中最下方的代码,并参看“AprilTag标记追踪”视频教程,获得转化计算公式。
openMV与arduino通讯并输出XY坐标
目的:通过openMV识别到物体位置,将其xy方向坐标发送至arduino单片机。
星瞳科技给出三种openMV与arduino通讯方式,分别为:
I2C(INTER IC BUS:意为IC之间总线)
SPI(Serial Peripheral Interface:串行外设接口)
UART(Universal Asynchronous Receiver Transmitter:通用异步收发器)
具体例程链接如下:
I2C: link
SPI: link
UART: link
具体区别不是很懂,打算边用边试。
经过一天挠头最终选用UART通讯方式,因为不会改I2C和ISP例程中的(转为发送int类型的xy坐标值):
text = "Hello World!\n"
data = ustruct.pack("<%ds" % len(text), text)
其中:
使用 “ustruct” 来生成需要发送的数据包
“<” 把数据以小端序放进struct中
“%ds” 把字符串放进数据流,比如:“13s” 对应的 “Hello World!\n” (13 chars).
ustruct.pack(fmt, v1, v2, …)
按照格式字符串 fmt 压缩参数 v1, v2, … 。返回值是参数编码后的字节对象。
len()
返回对象(字符、列表、元组等)长度或项目个数。
本来是改为ustruct.pack("<ii", blob.cx(),blob.cy()),但输出为乱码,所以放弃(麻烦有懂的大神搞一下)。
以下为识别红色并发送坐标值至arduino的openMV程序
import sensor, image, time, math
from pyb import UART
# UART 3, and baudrate.
uart = UART(3, 19200)
threshold_index = 0 # 0 for red, 1