OpenMV学习笔记

目录

目录

OpenMV简介

1.简介

2.具体参数

3.功能

使用

图像处理

python

REPL和串口

基础程序

图像处理

感光元件

初始化

自动增益/白平衡/曝光

窗口ROI

画图

色彩

画线

画框

画圆

画十字

写字

颜色识别

find_blobs函数

颜色阈值选择工具

blobs列表

标记跟踪

AprilTag简介

制作AprilTag

一个检测程序示例

3D定位示例

测距

方法一:

方法二:

颜色形状同时识别

颜色与模板匹配同时识别

视觉小车

pyb各种外设

json

串口通信



OpenMV简介

1.简介

OpenMV摄像头通过高级语言Python脚本( MicroPython )。可以很容易的使用外部终端触发拍摄或者或者执行算法,也可以把算法的结果用来控制IO引脚。通过额外的ttl-rs232或者ttl-rs485模块和PLC通信。

2.具体参数

STM32H743II ARM Cortex M7 处理器,480 MHz ,1MB RAM,2 MB flash.

所有引脚均可承受5V电压,输出电压为3.3V。所有引脚都可以提供最高25mA的拉电流(source)或灌电流(sink)。在ADC或DAC模式下,P6不能承受5V电压。引脚总共可提供最高120mA的拉电流(source)或灌电流(sink)。VIN可以在3.6V和5V之间。不要从OpenMV Cam的3.3V引脚输出超过250mA的电流。

他的镜头是M12通用的镜头,在不同的场景应用不同的镜头:

  • 标配镜头视角大概120度,长焦镜头30度,广角185度,无畸变镜头90度。

  • 标配镜头焦距2.8mm,长焦12mm,广角1.7mm,无畸变镜头3.6mm。

这个处理器有以下的IO接口:

  • 全速 USB (12Mbs) 接口,连接到电脑。当插入OpenMV摄像头后,电脑会出现一个虚拟COM端口和一个“U盘”。

  • μSD卡槽拥有100Mbs读写,这允许OpenMV摄像头录制视频,和把机器视觉的素材从SD卡提取出来。

  • 一个SPI总线高达100Mbs速度,允许简单的把图像流数据传给LCD扩展板,WiFi扩展板,或者其他控制器。

  • 一个 I2C总线,CAN总线, 和2两个异步串口总线 (TX/RX) ,用来链接其他控制器或者传感器。

  • 一个12-bit ADC 和一个12-bit DAC。

  • 2个 I/O 引脚用于舵机控制.

  • 所有的IO口都可以用于,中断和PWM(板子上有10个I/O引脚)。

  • 一个RGB LED(三色), 两个高亮的 850nm IR LED(红外)。

  • 32 MB 外置的 32-bit SDRAM ,100 MHz的时钟,达到 400 MB/s 的带宽。

  • 32 MB 外置的 quadspi flash, 100 MHz的时钟,4-bit DDR模式达到 100 MB/s 的带宽。

  • 可拆卸的摄像头模块系统,允许OpenMV Cam H7 Plus与不同的感光元件模组连接:

  • OpenMV4 H7 Plus默认配置的OV5640 感光元件处理2592×1944 (5MP)图像。在QVGA (320×240)及以下的分辨率时,大多数简单的算法可以运行(25~50)FPS。OpenMV 摄像头有一个2.8mm焦距镜头在一个标准M12镜头底座上。

  • 3.7V 锂离子电池接口

3.功能

  • 滤波

  • 颜色追踪

  • AptilTag

  • 二维码

  • 条形码

  • 人脸识别

  • 人眼追踪(瞳孔识别)

  • 直线识别

  • 圆形识别

  • 矩形识别

  • 数字识别

  • 线性回归-巡线

  • 模板匹配

  • 特征点追踪

  • 光流

  • 边缘检测

  • 录制视频

  • mavlink

使用

供电:USB口供电或者外部电源供电(3.7-5V)。注意,不要接3.3V

图像处理

1.LAB亮度-对比度

Lab颜色空间中,L亮度;a的正数代表红色,负端代表绿色;b的正数代表黄色,负端代表兰色。不像RGB和CMYK色彩空间,Lab颜色被设计来接近人类视觉。

因此L分量可以调整亮度对,修改a和b分量的输出色阶来做精确的颜色平衡。

2.镜头的畸变:OpenMV中使用image.lens_corr(1.8)来矫正2.8mm焦距的镜头

3.滤光片:通过波长650nm以内的滤光片,把红外光截止了

python

REPL和串口

OpenMV的IDE自带一个串口助手,用于连接OpenMV,也可以连接其他的串口,比如Arduino,pyboard,esp8266。

首先,断开OpenMV与IDE的连接,否则串口会冲突!

基础程序

 首先 import 是导入此代码所依赖的模块

进入一个while大循环,在这里 image 在不断的截图保存图像,而截取的图像我们就可以在右上角看到

最后一句 也就是打印的帧率,我们可以在下面的框Terminal看到 

图像处理

感光元件

初始化

  • sensor.reset() 初始化感光元件

自动增益/白平衡/曝光

  • sensor.set_auto_gain()     

自动增益开启(True)或者关闭(False)。在使用颜色追踪时,需要关闭自动增益。

  • sensor.set_auto_whitebal()

自动白平衡开启(True)或者关闭(False)。在使用颜色追踪时,需要关闭自动白平衡。

  • sensor.set_auto_exposure(enable[, exposure_us])

enable 打开(True)或关闭(False)自动曝光。默认打开。

如果 enable 为 False,则可以用 exposure_us 设置一个固定的曝光时间(以微秒为单位)。


窗口ROI


  ROI:Region Of Interest,图像处理中的术语“感兴趣区”。就是在要处理的图像中提取出的要处理的区域。

sensor.set_windowing(roi)
roi的格式是(x, y, w, h)
x:ROI区域中左上角的x坐标
y:ROI区域中左上角的y坐标
w:ROI的宽度
h:ROI的高度

画图

色彩

  • 颜色可以是灰度值(0-255),或者是彩色值(r, g, b)的tupple。默认是白色。

  • 其中的color关键字必须显示的标明color=

画线

  • image.draw_line(line_tuple, color=White) 在图像中画一条直线。

    • line_tuple的格式是(x0, y0, x1, y1),意思是(x0, y0)到(x1, y1)的直线。

    • 颜色可以是灰度值(0-255),或者是彩色值(r, g, b)的tupple。默认是白色

画框

  • image.draw_rectangle(rect_tuple, color=White) 在图像中画一个矩形框。

    • rect_tuple 的格式是 (x, y, w, h)。

画圆

  • image.draw_circle(x, y, radius, color=White) 在图像中画一个圆。

    • x,y是圆心坐标

    • radius是圆的半径

画十字

  • image.draw_cross(x, y, size=5, color=White) 在图像中画一个十字

    • x,y是坐标

    • size是两侧的尺寸

写字

  • image.draw_string(x, y, text, color=White) 在图像中写字 8x10的像素

    • x,y是坐标。使用\n, \r, and \r\n会使光标移动到下一行。

    • text是要写的字符串。

颜色识别

find_blobs函数

通过find_blobs函数可以找到色块

image.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)

参数:

  • thresholds是颜色的阈值,注意:这个参数是一个列表,可以包含多个颜色。如果你只需要一个颜色,那么在这个列表中只需要有一个颜色值,如果你想要多个颜色阈值,那这个列表就需要多个颜色阈值。注意:在返回的色块对象blob可以调用code方法,来判断是什么颜色的色块。

  • x_stride 就是查找的色块的x方向上最小宽度的像素,默认为2,如果你只想查找宽度10个像素以上的色块,那么就设置这个参数为10:

    blobs = img.find_blobs([red],x_stride=10)

  • y_stride 就是查找的色块的y方向上最小宽度的像素,默认为1

  • invert 反转阈值,把阈值以外的颜色作为阈值进行查找

  • area_threshold 面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉

  • pixels_threshold 像素个数阈值,如果色块像素数量小于这个值,会被过滤掉

  • merge 合并,如果设置为True,那么合并所有重叠的blob为一个。
    注意:这会合并所有的

  • roi的格式是(x, y, w, h)的tupple.

    x:ROI区域中左上角的x坐标

    y:ROI区域中左上角的y坐标

    w:ROI的宽度

    h:ROI的高度

颜色阈值选择工具

借助颜色阈值选择工具实时的看到阈值的结果

blobs列表

一个blobs列表里包含很多blob对象,blobs对象就是色块,每个blobs对象包含一个色块的信息。

find_blobs对象返回的是多个blob的列表.

blob的多个方法:

  • blob.rect() 返回这个色块的外框——矩形元组(x, y, w, h),可以直接在image.draw_rectangle中使用。

  • blob.x() 返回色块的外框的x坐标(int),也可以通过blob[0]来获取。

  • blob.y() 返回色块的外框的y坐标(int),也可以通过blob[1]来获取。

  • blob.w() 返回色块的外框的宽度w(int),也可以通过blob[2]来获取。

  • blob.h() 返回色块的外框的高度h(int),也可以通过blob[3]来获取。

  • blob.pixels() 返回色块的像素数量(int),也可以通过blob[4]来获取。

  • blob.cx() 返回色块的外框的中心x坐标(int),也可以通过blob[5]来获取。

  • blob.cy() 返回色块的外框的中心y坐标(int),也可以通过blob[6]来获取。

  • blob.rotation() 返回色块的旋转角度(单位为弧度)(float)。如果色块类似一个铅笔,那么这个值为0~180°。如果色块是一个圆,那么这个值是无用的。如果色块完全没有对称性,那么你会得到0~360°,也可以通过blob[7]来获取。

  • blob.code() 返回一个16bit数字,每一个bit会对应每一个阈值。举个例子:

    blobs = img.find_blobs([red, blue, yellow], merge=True)

如果这个色块是红色,那么它的code就是0001,如果是蓝色,那么它的code就是0010。注意:一个blob可能是合并的,如果是红色和蓝色的blob,那么这个blob就是0011。这个功能可以用于查找颜色代码。也可以通过blob[8]来获取。

  • blob.count() 如果merge=True,那么就会有多个blob被合并到一个blob,这个函数返回的就是这个的数量。如果merge=False,那么返回值总是1。也可以通过blob[9]来获取。

  • blob.area() 返回色块的外框的面积。应该等于(w * h)

  • blob.density() 返回色块的密度。这等于色块的像素数除以外框的区域。如果密度较低,那么说明目标锁定的不是很好。
    比如,识别一个红色的圆,返回的blob.pixels()是目标圆的像素点数,blob.area()是圆的外接正方形的面积。

标记跟踪

AprilTag简介

AprilTag是一个视觉基准系统,可用于各种任务,包括AR,机器人和相机校准。这个tag可以直接用打印机打印出来,而AprilTag检测程序可以计算相对于相机的精确3D位置,方向和id,只要把这个tag贴到目标上,就可以在OpenMV上识别出这个标签的3D位置,id。

制作AprilTag

从OpenMV的IDE里生成。 在工具——Machine Vision——AprilTag Generate中选择family,推荐使用TAG36H11。

一个检测程序示例

# AprilTags Example
#
# This example shows the power of the OpenMV Cam to detect April Tags
# on the OpenMV Cam M7. The M4 versions cannot detect April Tags.

import sensor, image, time, math

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...
sensor.skip_frames(30)
sensor.set_auto_gain(False)  # must turn this off to prevent image washout...
sensor.set_auto_whitebal(False)  # must turn this off to prevent image washout...
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
    for tag in img.find_apriltags(): # defaults to TAG36H11 without "families".
        img.draw_rectangle(tag.rect(), color = (255, 0, 0))
        img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
        degress = 180 * tag.rotation() / math.pi
        print(tag.id(),degress)

3D定位示例

Tag的空间位置,一共有6个自由度,三个位置,三个角度。

# AprilTags Example
#
# This example shows the power of the OpenMV Cam to detect April Tags
# on the OpenMV Cam M7. The M4 versions cannot detect April Tags.

import sensor, image, time, math

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...
sensor.skip_frames(30)
sensor.set_auto_gain(False)  # must turn this off to prevent image washout...
sensor.set_auto_whitebal(False)  # must turn this off to prevent image washout...
clock = time.clock()

# 注意!与find_qrcodes不同,find_apriltags 不需要软件矫正畸变就可以工作。

# 注意,输出的姿态的单位是弧度,可以转换成角度,但是位置的单位是和你的大小有关,需要等比例换算

# f_x 是x的像素为单位的焦距。对于标准的OpenMV,应该等于2.8/3.984*656,这个值是用毫米为单位的焦距除以x方向的感光元件的长度,乘以x方向的感光元件的像素(OV7725)
# f_y 是y的像素为单位的焦距。对于标准的OpenMV,应该等于2.8/2.952*488,这个值是用毫米为单位的焦距除以y方向的感光元件的长度,乘以y方向的感光元件的像素(OV7725)

# c_x 是图像的x中心位置
# c_y 是图像的y中心位置

f_x = (2.8 / 3.984) * 160 # 默认值
f_y = (2.8 / 2.952) * 120 # 默认值
c_x = 160 * 0.5 # 默认值(image.w * 0.5)
c_y = 120 * 0.5 # 默认值(image.h * 0.5)

def degrees(radians):
    return (180 * radians) / math.pi

while(True):
    clock.tick()
    img = sensor.snapshot()
    for tag in img.find_apriltags(fx=f_x, fy=f_y, cx=c_x, cy=c_y): # 默认为TAG36H11
        img.draw_rectangle(tag.rect(), color = (255, 0, 0))
        img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
        print_args = (tag.x_translation(), tag.y_translation(), tag.z_translation(), \
            degrees(tag.x_rotation()), degrees(tag.y_rotation()), degrees(tag.z_rotation()))
        # 位置的单位是未知的,旋转的单位是角度
        print("Tx: %f, Ty %f, Tz %f, Rx %f, Ry %f, Rz %f" % print_args)
    print(clock.fps())

测距

方法一:

利用Apriltag进行3D定位

方法二:

选参照物,利用参照物的大小比例来计算距离

距离 = 一个常数/直径的像素

这个常数的值,就是先让球距离摄像头10cm,打印出摄像头里直径的像素值,然后相乘,就得到了k的值!

# Measure the distance
#
# This example shows off how to measure the distance through the size in imgage
# This example in particular looks for yellow pingpong ball.

import sensor, image, time

# For color tracking to work really well you should ideally be in a very, very,
# very, controlled enviroment where the lighting is constant...
yellow_threshold   = ( 56,   83,    5,   57,   63,   80)
# You may need to tweak the above settings for tracking green things...
# Select an area in the Framebuffer to copy the color settings.

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # use RGB565.
sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # turn this off.
clock = time.clock() # Tracks FPS.

K=5000#the value should be measured

while(True):
    clock.tick() # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot() # Take a picture and return the image.

    blobs = img.find_blobs([yellow_threshold])
    if len(blobs) == 1:
        # Draw a rect around the blob.
        b = blobs[0]
        img.draw_rectangle(b[0:4]) # rect
        img.draw_cross(b[5], b[6]) # cx, cy
        Lm = (b[2]+b[3])/2
        length = K/Lm
        print(length)

    #print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while
    # connected to your computer. The FPS should increase once disconnected.

颜色形状同时识别

首先我们进行形状识别,然后在识别到的区域内进行颜色统计

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot().lens_corr(1.8)
    for c in img.find_circles(threshold = 3500, x_margin = 10, y_margin = 10, r_margin = 10,
            r_min = 2, r_max = 100, r_step = 2):
        area = (c.x()-c.r(), c.y()-c.r(), 2*c.r(), 2*c.r())
        #area为识别到的圆的区域,即圆的外接矩形框
        statistics = img.get_statistics(roi=area)#像素颜色统计
        print(statistics)
        #(0,100,0,120,0,120)是红色的阈值,所以当区域内的众数(也就是最多的颜色),范围在这个阈值内,就说明是红色的圆。
        #l_mode(),a_mode(),b_mode()是L通道,A通道,B通道的众数。
        if 0<statistics.l_mode()<100 and 0<statistics.a_mode()<127 and 0<statistics.b_mode()<127:#if the circle is red
            img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0))#识别到的红色圆形用红色的圆框出来
        else:
            img.draw_rectangle(area, color = (255, 255, 255))
            #将非红色的圆用白色的矩形框出来
    print("FPS %f" % clock.fps())

颜色与模板匹配同时识别

首先我们进行颜色识别,然后在识别到的颜色区域内进行模板识别。

视觉小车

pyb各种外设

详情看这里,pyb各种外设 · OpenMV中文入门教程

json

OpenMV有json的模块,json.dumps(obj)和ujson.loads(str)可以很容的生成json字符串和解析json字符串。

串口通信

串口连接

from machine import UART
uart = UART(1, baudrate=115200)     # 初始化串口 波特率设置为115200 TX是B12 RX是B13
uart.write("uart test\r\n")         # 发送字符串
uart_num = 0                        # 定义一个变量
uart_array = [48,49,50,51,52,53,54,55,56,57]  # 定义一个列表 保存数字
uart.write(bytearray(uart_array))   # 发送列表
uart.write(bytearray([0x41]))       # 发送一个十六进制数据
while(True):

    uart_num = uart.any()       # 获取当前串口数据数量
    if(uart_num):
        uart_str = uart.read(uart_num) # 读取串口数据
        uart.write(uart_str)    # 将读取到的串口数据发回
        # uart.read会自动在数据末尾添加\n的操作,如果想去掉可以用strip()去掉
        # 例如 uart_str = uart.read(uart_num).strip()
        # 这样 uart_str得到的数据就不会被自动添加\n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值