OpenMV使用心得(二)如何不受干扰准确识别一个色块

目录

目录

一、硬件层面

1.偏振片

2.OpenMV光源扩展板

 二、软件层面

1.参数层面

1.1 详解Lab色彩模式

1.2 详解OpenMV感光元件库

1.3 详解find_blobs()函数

1.3.1 find_blobs()函数roi参数处理

1.3.2 find_blobs()函数返回值处理

2.算法层面

2.1 多个阈值范围对应同一个物体

2.2 如何实现自适应阈值(附完整代码)


前言

视觉处理易受光源和环境干扰,本篇介绍了几种提高OpenMV识别色块稳定性的方法,从硬件层面和软件层面提供一些经过笔者验证的优化思路,希望能对你有所帮助。

一、硬件层面

1.偏振片

在视觉检测中,由于金属和绝缘表面反射时会产生部分偏振,造成镜面反射,也就是反光,影响检测。

一般情况下OpenMV镜头上加一个偏振片就有效果,想要更详细的了解偏振片可以跳转郑佬的文章,链接附下。

机器视觉中偏振片的应用_郑建广视觉的博客-CSDN博客

2.OpenMV光源扩展板

光源扩展板可以给OpenMV提供一个相对稳定的光环境, 尤其在小车巡线时效果尤其好, 可以自己DIY自制一个补光板, 也可以去OpenMV官方去购买,下图是OpenMV官方提供的光源扩展板。

二、软件层面

1.参数层面

1.1 详解Lab色彩模式

在 OpenMV 的查找色块的算法中,运用的就是这个LAB模式。

Lab颜色空间中,L代表亮度;a的正数代表红色,负端代表绿色;b的正数代表黄色,负端代表兰色。不像RGB和CMYK色彩空间,Lab颜色被设计来接近人类视觉。因此L分量可以调整亮度对,修改a和b分量的输出色阶来做精确的颜色平衡,Lab色彩几何表示如图所示。

下图是OpenMV IDE的阈值编辑器,需要调试六个参数, 不难理解我们平时调的阈值其实是一个动态的阈值范围。即 LAB阈值 = (Lmin,Lmax,Amin,Amax,Bmin,Bmax)。随着光环境的变化, 我们需要一直调整则这个阈值范围,  但是电赛是不让现场烧录程序的, 所以一直通过阈值编辑器调阈值肯定不是好方法。

1.2 详解OpenMV感光元件库

这一部分OpenMV官网的入门教程写的非常详细链接附下, 我主要强调两个函数曝光度函数和图像大小函数。

1.曝光度函数: 过亮降低曝光度,过暗升高曝光度。

2.图像大小函数: OpenMV4 H7 plus运行QVGA帧率大概在40fps,运行VGA帧率则是10fps对于电赛都是足够的。如果你寻找的色块很小, 不妨将图像大小设置为VGA,此时小色块像素会变多,达到find_blobs的最小要求。

 

感光元件 · OpenMV中文入门教程

1.3 详解find_blobs()函数

1.3.1 find_blobs()函数roi参数处理

规定感兴趣区roi可以避免摄像头识别到其他东西, 减少环境对OpenMV的干扰。

1.3.2 find_blobs()函数返回值处理

find_blobs()函数返回值是所有找到的色块的集合, 是一个色块列表。采用最大的色块是一个很经典的减少干扰的方法, 因为小色块可能不在目标色块最中心, 或者是误识别, 这里找最大的色块相当于一种数据过滤, 关键代码附下。

def find_max(blobs):
    max_blob = None
    max_size = 0
    for blob in blobs:
        if blob[2]*blob[3]>max_size:#blob[2]*blob[3],计算包含色块的最小矩形面积大小
            max_blob=blob
            max_size=blob[2]*blob[3]
    return max_blob

while(True):
    clock.tick()
    img = sensor.snapshot().lens_corr(1.6)#鱼眼矫正
    blobs = img.find_blobs([red_threshold],roi=[80,80,320,320])
    if blobs:
        max_blob = find_max(blobs)#返回最大的色块
        img.draw_rectangle(max_blob.rect())#画出找到色块

2.算法层面

2.1 多个阈值范围对应同一个物体

一般我们追踪目标都是通过颜色追踪,颜色追踪的效果是最好的,一般我们对于一个物体只会用一个元组设置一个阈值,但随着环境中光源的不经意改变,早上取的阈值到了晚上就用不了了,或者是2023年电赛E题, 红色激光需要经过黑色胶带背景和白色屏幕背景,在两种背景下阈值范围也是不一样的。这时,我们可以通过设置多个阈值来捕捉不同环境下同一个目标。

2.2 如何实现自适应阈值(附完整代码)

这份代码可以直接copy运行,大致原理是取感兴趣区内Lab三通道的众数为基准值,然后上下取一个范围,最后结果是print出感兴趣区的阈值,然后在死循环里找该颜色阈值,代码附详细注释。 

# 自动RGB565颜色跟踪示例
#
# 这个例子展示了使用OpenMV的单色自动RGB565色彩跟踪。

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # 颜色跟踪必须关闭自动增益
sensor.set_auto_whitebal(False) # 颜色跟踪必须关闭白平衡
clock = time.clock()

# 捕捉图像中心的颜色阈值。
r = [(320//2)-(50//2), (240//2)-(50//2), 50, 50] #感兴趣区
for i in range(60):#这个60大概值,没有实际意义
    img = sensor.snapshot()
    img.draw_rectangle(r)#画出想确定阈值的感兴趣区

threshold = [50, 50, 0, 0, 0, 0] # Middle L, A, B values.
for i in range(60):
    img = sensor.snapshot().lens_corr(1.6)#镜头矫正
    hist = img.get_histogram(roi=r)
    lo = hist.get_percentile(0.01) # 获取1%范围的直方图的CDF(根据需要调整)!
    hi = hist.get_percentile(0.99) # 获取99%范围的直方图的CDF(根据需要调整)!
    # 平均百分位值。
    threshold[0] = (threshold[0] + int(lo.l_value()/2)) // 2#Lmin
    threshold[1] = (threshold[1] + int(hi.l_value()/2)) // 2#Lmax
    threshold[2] = (threshold[2] + int(lo.a_value()*1.2)) // 2#Amin
    threshold[3] = (threshold[3] + int(hi.a_value()*1.2)) // 2#Amax
    threshold[4] = (threshold[4] + int(lo.b_value()*1.2)) // 2#Bmin
    threshold[5] = (threshold[5] + int(hi.b_value()*1.2)) // 2#Bmax
    for blob in img.find_blobs([threshold], pixels_threshold=100, area_threshold=100, merge=True, margin=10):
        img.draw_rectangle(blob.rect())
        img.draw_cross(blob.cx(), blob.cy())
        img.draw_rectangle(r)


print("threshold",threshold)
#(30, 55, 29, 53, -9, 40)
while(True):
    clock.tick()
    img = sensor.snapshot()
    for blob in img.find_blobs([threshold], pixels_threshold=100, area_threshold=100, merge=True, margin=10):
        img.draw_rectangle(blob.rect())
        img.draw_cross(blob.cx(), blob.cy())
    #print(clock.fps())

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值