首页 > 分享 > 【K230 CanMV】图像识别 色块追踪 颜色识别 blobs 全面详解

【K230 CanMV】图像识别 色块追踪 颜色识别 blobs 全面详解

引言:在计算机视觉和图像处理领域,颜色识别和色块追踪是实现目标检测、物体追踪、智能交互等应用的基础技术之一。通过分析图像中颜色的分布,我们可以识别并跟踪特定的物体或区域,进而为智能系统提供精确的视觉反馈。在嵌入式系统中,图像处理通常受限于硬件资源,因此需要高效且精确的算法来实现实时识别和追踪。
本文将以 K230 CanMV 开发平台为例,深入探讨如何利用其强大的图像处理能力,通过颜色识别技术实现对特定颜色物体的色块追踪。我们将介绍颜色识别函数 find_blobs 的原理与用法,详细讲解如何使用该函数进行图像中的色块追踪,最后提供一个实际案例,帮助读者在实际项目中运用这一技术。

目录

一、颜色识别(find_blobs)概述

二、函数讲解

三、图像色块追踪方法介绍

四、示例模版

五、实际案例

一、颜色识别(find_blobs)概述

find_blobs 是 OpenMV 的图像处理函数,用于在图像中寻找并识别“斑点”(blobs)。这些斑点是指图像中具有相似颜色或亮度的区域。这个函数通常用于视觉检测和识别应用中,例如物体跟踪、颜色识别等。

CanMV支持OpenMV算法,同样可以使用find_blobs

二、函数讲解

blobs = img.find_blobs([thresholds], area_threshold=area_threshold, pixels_threshold=pixels_threshold, merge=True, margin=0)

thresholds: 这是一个包含颜色范围的列表,用于定义要查找的斑点的颜色范围。通常是一个包含两个或三个元素的元组。例如,(100, 200, -64, 127, -128, 127) 表示 HSV 颜色空间中的范围,其中第一个和第二个值是 Hue,第三和第四值是 Saturation,最后两个值是 Value。

area_threshold: 斑点的面积阈值。只有面积大于这个值的斑点才会被返回。默认值是 0。

pixels_threshold: 斑点的像素数阈值。只有包含的像素数大于这个值的斑点才会被返回。默认值是 0。

merge: 是否合并相邻的斑点。设为 True 时,相邻的斑点会被合并成一个大斑点;设为 False 时,斑点不会合并。默认值是 True。

margin: 用于合并斑点时的边距。设置为一个正整数,表示合并斑点时的最大距离。默认值是 0。

返回值:

find_blobs 函数返回一个包含斑点信息的列表。每个斑点都是一个 Blob 对象,通常包含以下属性:

cx 和 cy:斑点的中心坐标。

x 和 y:斑点的左上角坐标。

w 和 h:斑点的宽度和高度。

area:斑点的面积(像素数)。

三、图像色块追踪方法介绍

image 模块为 Image 对象提供了 find_blobs()方法,用于查找图像中的所有色块,find_blobs() 方法如下所示:

image.find_blobs(thresholds, invert=False, roi, x_stride=2, y_stride=1,

area_threshold=10, pixels_threshold=10, merge=False, margin=0, threshold_cb,

merge_cb)

find_blobs() 方法在图像处理中用于根据指定的颜色阈值查找图像中的色块,并返回符合条件的 image.blob 对象列表。色块通常是指在图像中某一特定颜色范围内的连续像素区域。该方法支持对不同颜色空间和图像类型进行处理,允许在一定条件下筛选、合并或过滤色块。

方法参数解释

thresholds
该参数指定了颜色的阈值,用于定义哪些颜色区域需要被识别。它是一个元组列表,针对不同的图像和颜色空间,具体形式有所不同:

灰度图像:对于灰度图像,thresholds 应该是一个包含两个数值的元组 (min_gray_value, max_gray_value),表示允许的灰度值范围。RGB565 图像:对于 RGB565 格式的图像,thresholds 应该是包含六个值的元组 (min_L, max_L, min_A, max_A, min_B, max_B),这六个值分别表示在 LAB 色彩空间下的 L、A 和 B 三个通道的最小值和最大值。LAB 色彩空间具有较好的色差感知效果,适用于在不同光照条件下进行色彩追踪。

例如,若要追踪红色和蓝色的色块,可以在阈值元组列表中分别传入对应的颜色范围。

invert
该参数控制是否对颜色阈值进行反转操作。如果设置为 True,则追踪的不是在指定阈值内的色块,而是阈值之外的色块。默认为 False,即只关注在阈值范围内的色块。

roi (Region of Interest)
指定图像中感兴趣的区域。它用于限制图像处理的范围,减少计算量。若未指定该参数,则处理整个图像。

x_stride 和 y_stride
这些参数用于定义在图像处理中每次跳过多少个像素。若色块较大,增加这些步长可以提高效率,减少计算量。例如,x_stride=2 会让每次在 X 轴方向上跳过 2 个像素,y_stride=2 会在 Y 轴方向上跳过 2 个像素。

area_threshold
该参数用于过滤掉那些边界框区域小于指定值的色块。设定较大的 area_threshold 可以去除一些过小的色块,以减小检测的噪声。

pixels_threshold
用于过滤掉那些像素数量少于指定值的色块。该参数通常用于避免误识别一些微小的、无意义的色块。

merge
该参数控制是否对相互重叠的色块进行合并。如果设置为 True,则会将边缘矩形相互交错且没有被过滤的色块合并成一个色块。若设置为 False,则不合并重叠的色块。

margin
该参数用于增大或减小检测到的色块边界矩形的大小,通常用于修正边界矩形的形状,确保色块的完整性。

threshold_cb (Threshold callback function)
这是一个回调函数,作用是在颜色阈值过滤过程中对被过滤的色块进行进一步筛选。该函数会接收到一个 image.blob 对象,返回 True 表示保留该色块,返回 False 则表示过滤掉该色块。

merge_cb (Merge callback function)
这是一个回调函数,用于决定是否将两个即将合并的色块合并成一个。该函数会接收到两个 image.blob 对象,返回 True 表示合并色块,返回 False 则禁止合并。

方法返回值

find_blobs() 方法返回一个包含 image.blob 对象的列表,每个 image.blob 对象表示一个在图像中找到的色块。每个色块包含以下信息:

色块的边界框位置和大小色块的质心坐标色块内像素的颜色值信息

import image

img = image.Image(size=(320, 240))

threshold = (8, 63, 8, 49, -77, -36)

blobs = img.find_blobs([threshold], False, (0, 0, img.width(), img.height()),

x_stride=2, y_stride=1, area_threshold=10, pixels_threshold=10, merge=True,

margin=10)

for b in blobs:

img.draw_rectangle(b.rect(), color=(255, 0, 0))

关于颜色阈值的设定,CanMV IDE 软件提供了“阈值编辑器”工具,可以方便地获取到想 要的阈值。通过依次点击 CanMV IDE 软件上方工具栏中的“工具”→“机器视觉”→“阈值编 辑器”,即可打开“阈值编辑器”工具,打开时会提示需要导入一张源图像,可以直接使用“帧 缓冲区”窗口中的图像,也可以从本地文件系统中选取,如下图所示:

四、示例模版

这里只列举一个单独的颜色追踪例子,具体demo还请查看固件自带虚拟U盘中的例程

初始化:导入库,设置摄像头和显示参数,初始化传感器和媒体管理器。循环获取图像:通过传感器不断获取图像帧。色块检测:通过 find_blobs 函数检测符合阈值条件的色块,并根据颜色编码进一步筛选。绘制标识:对符合条件的色块进行绘制,如矩形框、十字标记、旋转角度等。显示图像:将处理后的图像显示在屏幕上。性能监控:输出帧率,监控程序性能。清理资源:程序退出时清理传感器和显示资源。

import time, os, gc, sys, math

from media.sensor import *

from media.display import *

from media.media import *

DETECT_WIDTH = 640

DETECT_HEIGHT = 480

thresholds = [(12, 100, -47, 14, -1, 58),

(30, 100, -64, -8, -32, 32)]

sensor = None

try:

sensor = Sensor(width = DETECT_WIDTH, height = DETECT_HEIGHT)

sensor.reset()

sensor.set_framesize(width = DETECT_WIDTH, height = DETECT_HEIGHT)

sensor.set_pixformat(Sensor.RGB565)

Display.init(Display.VIRT, width = DETECT_WIDTH, height = DETECT_HEIGHT, fps = 100)

MediaManager.init()

sensor.run()

fps = time.clock()

while True:

fps.tick()

os.exitpoint()

img = sensor.snapshot()

for blob in img.find_blobs(thresholds, pixels_threshold=100, area_threshold=100, merge=True):

if blob.code() == 3:

img.draw_rectangle([v for v in blob.rect()])

img.draw_cross(blob.cx(), blob.cy())

img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)

Display.show_image(img)

gc.collect()

print(fps.fps())

except KeyboardInterrupt as e:

print(f"user stop")

except BaseException as e:

print(f"Exception '{e}'")

finally:

if isinstance(sensor, Sensor):

sensor.stop()

Display.deinit()

os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)

time.sleep_ms(100)

MediaManager.deinit()

这段代码是一个基于色块跟踪的示例,使用 CanMV Cam 摄像头进行目标跟踪。它通过设定颜色阈值来识别图像中的特定颜色区域(色块),并结合色块的属性(如位置、旋转、长宽比等)进行进一步处理。下面将详细解析每个部分的作用和代码流程。
 

time:用于处理时间相关的操作,例如计算帧率(fps)。os:用于操作系统相关的功能,例如退出点检查。gc:垃圾回收库,用于管理内存。sys:提供对 Python 运行时环境的访问。math:提供数学函数,特别是 math.degrees() 用于角度转换。

接下来的导入是涉及到图像采集、显示和媒体管理的自定义模块:

media.sensor:提供摄像头传感器相关的功能。media.display:处理显示输出的相关功能。media.media:管理媒体相关的资源。 红色阈值:第一个元组 (12, 100, -47, 14, -1, 58) 用于识别红色区域(在 LAB 色彩空间中设置 L, A, B 三个通道的最小值和最大值)。绿色阈值:第二个元组 (30, 100, -64, -8, -32, 32) 用于识别绿色区域。

每个阈值元组代表 LAB 色彩空间中三个通道的范围,配合 find_blobs() 函数可以找出图像中符合这些颜色范围的色块。

初始化了传感器,设置图像的宽度和高度,并指定图像格式为 RGB565。这意味着每个像素会以 16 位存储,每个通道(红色、绿色、蓝色)分别使用 5 位、6 位和 5 位。

显示被初始化为虚拟显示 (Display.VIRT),并设置分辨率为 640x480,帧率为 100。这里的显示操作是虚拟显示,适合开发和调试时在 IDE 中查看输出。

通过 MediaManager.init() 初始化媒体管理器,接着启动传感器运行。这意味着图像采集开始实时进行。

fps.tick() 用于记录帧时间,计算当前帧率。os.exitpoint() 检查是否需要退出程序。sensor.snapshot() 捕获当前图像帧。 find_blobs():基于之前定义的 thresholds 参数,查找符合条件的色块。此方法返回一个包含色块的列表。 pixels_threshold=100:色块的像素数量必须大于 100。area_threshold=100:色块的面积必须大于 100。merge=True:合并重叠的色块,适用于多个颜色组合。blob.code() == 3:在本示例中,色块的代码为 3,即同时包含红色和绿色,这通过将 1 << 0 和 1 << 1 位运算或得到的结果。

色块处理:

blob.rect():获取色块的边界矩形,并绘制出来。blob.cx(), blob.cy():获取色块的质心坐标,并在图像上绘制十字。blob.rotation():获取色块的旋转角度,并绘制该角度的键点。 Display.show_image(img):将处理后的图像显示在屏幕上。gc.collect():进行垃圾回收,释放不再使用的内存。

通过 fps.fps() 输出当前帧率,用于调试和性能监控。

捕获 KeyboardInterrupt 异常(用户手动停止)以及其他基础异常,并打印出异常信息。在 finally 块中停止传感器,反初始化显示设备,释放资源并确保应用退出前能进入睡眠状态。

五、实际案例

这段代码是一个基于色块跟踪的示例,旨在通过摄像头捕捉图像并检测特定颜色(红色)的物体。代码利用了 find_blobs 函数来检测图像中的红色区域,并对符合条件的色块进行标记和显示。

 1. 导入必要的库

import time, os, gc, sys, math

from media.sensor import *

from media.display import *

from media.media import *

time:用于处理时间相关的功能,如计算帧率。os:提供与操作系统交互的功能,例如检查退出点。gc:垃圾回收库,用于管理内存,避免内存泄漏。sys:提供对Python运行时环境的访问,通常用于调试或获取程序的系统信息。math:提供数学函数,这里使用 math.degrees() 来将弧度转换为度。

接下来的导入是与硬件和显示相关的自定义模块:

media.sensor:提供与摄像头传感器相关的功能。media.display:处理图像显示的功能。media.media:用于初始化和管理媒体资源,如缓冲区。

2. 设置摄像头分辨率和颜色阈值

DETECT_WIDTH = 640

DETECT_HEIGHT = 480

red_thresholds = [(30, 68, 9, 127, -12, 73)]

DETECT_WIDTH 和 DETECT_HEIGHT 设置图像的分辨率为 640x480,这是大多数视觉应用的标准分辨率。

红色阈值 (red_thresholds): 这个阈值使用的是 LAB 色彩空间中的三个通道 L, A, B 的范围。该阈值定义了一个色块的颜色范围,用于识别红色物体。

L (亮度) 最小值 30,最大值 68;A (绿色到红色的色差) 最小值 9,最大值 127;B (蓝色到黄色的色差) 最小值 -12,最大值 73。

红色的色块会被识别并标记为代码 1(因为索引是 0,所以在 find_blobs() 中,1 << 0 表示红色)。

3. 初始化摄像头和显示器

sensor = None

try:

sensor = Sensor(width=DETECT_WIDTH, height=DETECT_HEIGHT)

sensor.reset()

sensor.set_framesize(width=DETECT_WIDTH, height=DETECT_HEIGHT)

sensor.set_pixformat(Sensor.RGB565)

创建一个传感器对象 sensor,并指定其分辨率为 640x480。调用 sensor.reset() 来重置摄像头设置。sensor.set_framesize() 设置图像输出的分辨率。sensor.set_pixformat(Sensor.RGB565) 设置输出图像格式为 RGB565,每个像素占用 16 位存储(5 位红色,6 位绿色,5 位蓝色)。

4. 设置显示

Display.init(Display.VIRT, width=DETECT_WIDTH, height=DETECT_HEIGHT, fps=100)

这里使用虚拟显示 (Display.VIRT) 初始化显示屏,并设置分辨率为 640x480,帧率为 100 帧每秒。

5. 初始化媒体管理器和启动传感器

MediaManager.init()

sensor.run()

MediaManager.init() 初始化媒体管理器,管理摄像头捕捉的图像和相关的缓存。sensor.run() 启动摄像头的图像捕捉过程。

6. 主循环:图像捕捉、色块检测和显示

fps = time.clock()

while True:

fps.tick()

os.exitpoint()

img = sensor.snapshot()

fps.tick():记录并更新帧时间,用于计算实时帧率。os.exitpoint():检查是否应退出程序。sensor.snapshot():捕获一帧图像。

7. 查找红色物体

for blob in img.find_blobs(red_thresholds, pixels_threshold=100, area_threshold=100, merge=True):

if blob.code() == 1:

img.draw_rectangle([v for v in blob.rect()])

img.draw_cross(blob.cx(), blob.cy())

img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)

find_blobs(red_thresholds, pixels_threshold=100, area_threshold=100, merge=True):

red_thresholds:提供红色物体的颜色范围。pixels_threshold=100:只有像素数量超过 100 的色块才会被返回。area_threshold=100:只有面积大于 100 的色块才会被返回。merge=True:如果设置为 True,会合并相互重叠的色块。

if blob.code() == 1:检查该色块是否是红色,红色色块的代码为 1,即 1 << 0。

绘制操作:

blob.rect():获取色块的矩形边界并绘制。blob.cx(), blob.cy():获取色块的质心坐标,并绘制十字准星。blob.rotation():获取色块的旋转角度,使用 math.degrees() 将其从弧度转换为度数,并绘制旋转角度的标记。

相关知识

图像识别算法有哪些
MATLAB图像识别技术在绿叶面病虫害识别
MATLAB图像识别技术在棉花叶面病虫害识别
植物识别接口 花卉识别 植物花卉识别 图像识别
花卉图像识别
图像识别—郁金香花数据集
色块和地被类花卉浇灌步骤
向日葵图像识别深度学习数据集
什么是图像识别
园林景观中色块的配置设计和色块植物选择应用

网址: 【K230 CanMV】图像识别 色块追踪 颜色识别 blobs 全面详解 https://m.huajiangbk.com/newsview1094025.html

所属分类:花卉
上一篇: 杜鹃花颜色有哪些
下一篇: 不可错过!舌尖上的四川:7道必尝