OpenMV学习笔记2——颜色识别

目录

一、打开单颜色识别实例代码

二、代码基础部分

 三、阈值选择

四、给识别到的颜色画框

五、多颜色识别 


 

一、打开单颜色识别实例代码

如图,双击打开对应文件即可进入实例代码。

二、代码基础部分

# Single Color RGB565 Blob Tracking Example
#
# This example shows off single color RGB565 tracking using the OpenMV Cam.

import sensor
import time
import math

threshold_index = 0  # 0 for red, 1 for green, 2 for blue

# Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max)
# The below thresholds track in general red/green/blue things. You may wish to tune them...
thresholds = [
    (30, 100, 15, 127, 15, 127),  # generic_red_thresholds
    (30, 100, -64, -8, -32, 32),  # generic_green_thresholds
    (0, 30, 0, 64, -128, 0),      # generic_blue_thresholds
]  

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
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()

# Only blobs that with more pixels than "pixel_threshold" and more area than "area_threshold" are
# returned by "find_blobs" below. Change "pixels_threshold" and "area_threshold" if you change the
# camera resolution. "merge=True" merges all overlapping blobs in the image.

while True:
    clock.tick()
    img = sensor.snapshot()
    for blob in img.find_blobs(
        [thresholds[threshold_index]],
        pixels_threshold=200,
        area_threshold=200,
        merge=True,
    ):
        # These values depend on the blob not being circular - otherwise they will be shaky.
        if blob.elongation() > 0.5:
            img.draw_edges(blob.min_corners(), color=(255, 0, 0))
            img.draw_line(blob.major_axis_line(), color=(0, 255, 0))
            img.draw_line(blob.minor_axis_line(), color=(0, 0, 255))
        # These values are stable all the time.
        img.draw_rectangle(blob.rect())
        img.draw_cross(blob.cx(), blob.cy())
        # Note - the blob rotation is unique to 0-180 only.
        img.draw_keypoints(
            [(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20
        )
    print(clock.fps())

首先,还是要先导入所依赖的库,有“sensor”、“time”和“math”。 

代码的第九行定义了一个名为“threshold_index”的变量,注释上写明了0代表红色,1代表绿色,2代表蓝色。直接跳到13行代码可以看到,这里定义了一个成员为元组的列表,每个元组有六个值,分别代表了LAB的三个最大值与最小值,组合在一起即可表示一个颜色。每行后面的注释都写明了所代表的颜色。

注:LAB指的是一种特殊的颜色模式,Lab颜色模型由三个要素组成,一个要素是亮度(L),a 和b是两个颜色通道。a包括的颜色是从深绿色(低亮度值)到灰色(中亮度值)再到亮粉红色(高亮度值);b是从亮蓝色(低亮度值)到灰色(中亮度值)再到黄色(高亮度值)。因此,这种颜色混合后将产生具有明亮效果的色彩。

 在循环中,我们通过“thresholds[threshold_index]”的方式来访问设定好的颜色中的某个成员的LAB参数。

接下来19~22行代码是重置感光元件、重置摄像机;设置颜色格式为RGB565;图像大小为QVGA;跳过2000帧使设置生效。这些都是上节见过的代码,这里不再赘述。

需要注意的是,在颜色识别中一定要关闭白平衡和自动增益,如果打开的话会影响颜色识别的效果,可能会使颜色的阈值发生改变。也就是23、24两行代码所代表的意思。

然后我们进入while循环。“img = sensor.snapshot”首先截取感光元件的一张图片,接下来在“img.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方法,来判断是什么颜色的色块。
red = (xxx,xxx,xxx,xxx,xxx,xxx)
blue = (xxx,xxx,xxx,xxx,xxx,xxx)
yellow = (xxx,xxx,xxx,xxx,xxx,xxx)

img=sensor.snapshot()
red_blobs = img.find_blobs([red])

color_blobs = img.find_blobs([red,blue, yellow])
  • roi是“感兴趣区”。在使用统计信息中已经介绍过了。

    left_roi = [0,0,160,240]
    blobs = img.find_blobs([red],roi=left_roi)

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

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

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

    blobs = img.find_blobs([red],y_stride=5)

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

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

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

  • merge 合并,如果设置为True,那么合并所有重叠的blob为一个。
    注意:这会合并所有的blob,无论是什么颜色的。如果你想混淆多种颜色的blob,只需要分别调用不同颜色阈值的find_blobs。

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

red_blobs = img.find_blobs([red],merge=True)
blue_blobs = img.find_blobs([blue],merge=True)
yellow_blobs = img.find_blobs([yellow],merge=True)
  • margin 边界,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并。

 三、阈值选择

 打开如图所示的位置,在弹出的窗口中选择帧缓冲区,即可在摄像头捕捉到的画面内调整LAB的阈值。调整滑块,可以看到右边对应的图像也在做出变化。

 在弹出窗口的下方有一个LAB阈值的栏,右键即可复制当前滑块位置下的LAB阈值。

初次之外,我们也可以使用右下角的图像直方图来进行颜色阈值的选择。我们在下拉三角中选择LAB色彩空间,之后在右上角的图像中框出一个框框来,可以看到下面的直方图也在发生变化。

这里我们只需要按照顺序,将L的最小最大、a的最小最大、b的最小最大填进去,就写好了一个新的阈值。

如果我们不框住任何色块,下方的直方图就显示的是整个图像的色彩。

四、给识别到的颜色画框

代码中的“blob”是函数“find_blobs”所返回的对象列表,它包含以下内容(以下内容来自官方文档):

  • 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()是圆的外接正方形的面积。

“img.draw_rectangle(blob.rect())”意思是如果识别到了制定的颜色,我们就在这个色块周围画一个框框把它圈出来。“img.draw_cross(blob.cx(), blob.cy())”意思是在色框中间画一个十字,blob.cx()与blob.cy()指的是色块的中心位置坐标。

我们也可以在循环中加一句“print(blob)”来获取所有blob参数,运行结果如下:

{"x":0, "y":198, "w":23, "h":42, "pixels":329, "cx":8, "cy":218, "rotation":1.690989, "code":1, "count":1, "perimeter":257, "roundness":0.199382}

五、多颜色识别 

在循环中,我们可以将第36行代码改写成“[thresholds],” ,也就是删掉后面的“[threshold_index],”,此时再次运行可以看到红、蓝、绿三种颜色都被框选显示了出来。

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风痕天际

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值