立创·庐山派K230CanMV开发板的进阶学习——颜色识别
学习目标:立创·庐山派K230CanMV开发板的进阶学习——颜色识别
学习内容:颜色识别
颜色识别
1. 本节介绍
📝 学习内容:本节将学习基于颜色阈值的色块检测技术,通过定义特定颜色范围,从摄像头采集的图像中识别并标记目标色块,同时结合图像绘制功能实现可视化指示。
🏆 学习目标:
- 掌握使用庐山派开发板寻找图像色块的方法;
- 理解颜色阈值的调节逻辑,提升颜色识别的准确性。
⚠️ 注意事项:
- 颜色识别依赖颜色空间转换与阈值匹配,需重点关注
LAB
色彩空间的参数设置; - 例程默认通过“立创·3.1寸屏幕扩展板”显示,无屏幕时可在IDE缓冲区查看(可能因USB带宽导致帧率低或卡顿)。
2. 颜色识别的基本原理
颜色识别通过以下核心步骤实现,庐山派内置图像处理库会自动完成中间关键环节,开发者仅需定义颜色范围:
- 获取图像:通过摄像头捕获一帧画面,转换成数字信号,供算法处理。
- 颜色空间转换:将图像从默认的颜色空间(一般是RGB)转换到适合分析的颜色空间(本节是LAB)。
- 阈值匹配:根据预先设定的颜色范围,筛选出符合条件的像素。
- 区域分析:将相邻的符合条件的像素组合成“区域”(Blob),并提取区域的特征(比如位置、大小、形状等)。
- 标记与输出:对识别出的区域进行标记,并输出相关信息。
3. 什么是LAB色彩空间?
LAB
是基于人眼视觉感知设计的颜色空间,核心优势是分离“亮度”与“颜色”信息,比RGB
更适合颜色识别。
3.1 RGB VS LAB
维度 | RGB色彩空间 | LAB色彩空间 |
---|---|---|
通道组成 | 红(R)、绿(G)、蓝(B)三通道 | 亮度(L)、红-绿(A)、蓝-黄(B)三通道 |
亮度与颜色关系 | 亮度与颜色信息混合,无法单独分离 | 亮度(L)与颜色(A/B)完全分离 |
光照敏感性 | 光照变化会显著影响RGB值,稳定性差 | 仅L通道受光照影响,A/B通道(颜色)鲁棒性强 |
直观性 | 人眼感知与RGB值无直观关联 | A/B通道直接对应颜色范围,贴近人眼感知 |
色域范围 | 设备相关(如sRGB仅覆盖人眼可见色35%) | 设备无关,理论可表示所有人眼可见色 |
LAB通道详解:
- L通道:亮度范围
0-100
,0为纯黑,100为纯白; - A通道:颜色范围
-128-127
,负值偏绿,正值偏红; - B通道:颜色范围
-128-127
,负值偏蓝,正值偏黄。
3.2 关键提示
尽管LAB
对光照的鲁棒性优于RGB
,但实际场景中环境光仍会影响识别效果:
- 需保证检测环境的光照一致性(如避免强光直射或逆光);
- 调节阈值时,需在目标使用环境下进行,确保阈值匹配实际光照条件。
4. find_blobs
(寻找图像中色块)
find_blobs
是颜色识别的核心API,用于从图像中筛选符合颜色阈值的色块,并返回包含色块特征的对象列表。
4.1 API原型
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=None[, merge_cb=None]]]]]]]]]])
4.2 核心参数解释
参数名 | 功能说明 |
---|---|
thresholds | 颜色阈值列表,格式为[(lo, hi), ...] :- 灰度图:每个元组为 (最小灰度, 最大灰度) ;- RGB565图(彩色):每个元组为 (L_min, L_max, A_min, A_max, B_min, B_max) ,对应LAB三通道范围。 |
invert | 布尔值,True 时反转阈值(仅匹配阈值外的像素),默认False 。 |
roi | 感兴趣区域,格式(x, y, w, h) ,仅对该区域检测,默认全图。 |
area_threshold | 面积阈值,过滤掉边界框面积小于此值的色块(避免噪点误识别)。 |
pixels_threshold | 像素阈值,过滤掉像素数量小于此值的色块。 |
merge | 布尔值,True 时合并重叠的色块,默认False 。 |
4.3 阈值获取方法
通过CanMV IDE便捷获取目标颜色的LAB
阈值:
- 在IDE帧缓冲区内单击并拖动,框选目标颜色区域,直方图会实时更新;
- 记录直方图中L、A、B通道的分布范围,作为
thresholds
的参数; - 或通过IDE菜单“工具”→“机器视觉”→“阈值编辑器”,拖动滑块可视化调节阈值。
5. 寻找特定颜色色块(代码示例)
以下代码实现“识别特定颜色色块并标记”的功能,以自定义LAB
阈值为例(可根据目标颜色调整):
import time, os, sys
from media.sensor import *
from media.display import *
from media.media import *sensor_id = 2
sensor = None# 显示模式选择:"VIRT"(虚拟)、"LCD"(3.1寸屏)、"HDMI"(HDMI扩展板)
DISPLAY_MODE = "LCD"# 根据显示模式设置宽高
if DISPLAY_MODE == "VIRT":DISPLAY_WIDTH = ALIGN_UP(1920, 16)DISPLAY_HEIGHT = 1080
elif DISPLAY_MODE == "LCD":DISPLAY_WIDTH = 800DISPLAY_HEIGHT = 480
elif DISPLAY_MODE == "HDMI":DISPLAY_WIDTH = 1920DISPLAY_HEIGHT = 1080
else:raise ValueError("未知的 DISPLAY_MODE,请选择 'VIRT', 'LCD' 或 'HDMI'")try:# 初始化摄像头sensor = Sensor(id=sensor_id)sensor.reset()# 配置摄像头参数:分辨率与像素格式(RGB565支持LAB转换)sensor.set_framesize(width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, chn=CAM_CHN_ID_0)sensor.set_pixformat(Sensor.RGB565, chn=CAM_CHN_ID_0)# 初始化显示器if DISPLAY_MODE == "VIRT":Display.init(Display.VIRT, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, fps=60)elif DISPLAY_MODE == "LCD":Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)elif DISPLAY_MODE == "HDMI":Display.init(Display.LT9611, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)# 初始化媒体管理器并启动摄像头MediaManager.init()sensor.run()# 1. 定义颜色阈值(LAB格式):[(L_min, L_max, A_min, A_max, B_min, B_max)]# 示例:识别偏红的颜色(可根据目标颜色调整)color_threshold = [(0, 79, 31, 67, 26, 60)]while True:os.exitpoint() # 系统安全退出检查# 2. 捕获一帧图像img = sensor.snapshot(chn=CAM_CHN_ID_0)# 3. 寻找色块:过滤面积小于2000的色块(避免噪点)blobs = img.find_blobs(color_threshold, area_threshold=2000)# 4. 标记色块并输出信息if blobs: # 若检测到色块for blob in blobs:# 绘制色块外接矩形(blob[0:4] = [x, y, w, h])img.draw_rectangle(blob[0:4], color=(255, 0, 0), thickness=2)# 绘制色块中心点十字(blob[5], blob[6] = 中心点x, y)img.draw_cross(blob[5], blob[6], color=(0, 255, 0), size=10, thickness=2)# 打印中心点坐标print(f"色块中心:X={blob[5]}, Y={blob[6]}")# 5. 显示处理后的图像Display.show_image(img)except KeyboardInterrupt as e:print("用户停止:", e)
except BaseException as e:print(f"异常:{e}")
finally:# 资源释放if isinstance(sensor, Sensor):sensor.stop()Display.deinit()os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)time.sleep_ms(100)MediaManager.deinit()
5.1 代码关键说明
- 颜色阈值配置:
color_threshold
需根据目标颜色的LAB
范围调整,例如识别蓝色时可设置为[(0, 50, -128, -20, -128, -30)]
; - 色块过滤:
area_threshold=2000
过滤小面积噪点,可根据目标大小调整(如识别小物体时减小阈值); - 可视化标记:通过
draw_rectangle
和draw_cross
分别标记色块边界与中心点,便于直观观察。
5.2 效果优化建议
- 阈值微调:若出现“误识别”(识别无关色块),可缩小
LAB
通道范围;若“漏识别”,可扩大范围; - 设置ROI:通过
roi=(x, y, w, h)
限定检测区域(如仅检测画面中心),减少干扰并提升效率; - 光照控制:在固定光照环境下调试阈值,避免强光、阴影等导致阈值失效。
6 如何进行阈值调节
首先运行一个能够在帧缓冲区显示图像的程序,将庐山派的摄像头对准你需要调节颜色阈值的对象,然后点击帧缓冲区右上角的【禁用】,先把图像固定,方便后续步骤。 位置如下图所示:
注意
调节完阈值之后注意需要单击这个【禁用】来取消,否则即使你重新运行程序,帧缓冲区也会一直不更新图像。
单击CanMV IDE K230上方菜单栏中的【工具】->【机器视觉】->【阈值编辑器】
在新弹出来的对话框中单击【帧缓冲区】,设定图像来源为帧缓冲区。
弹出来的框就是阈值编辑器,在下面的六个通道中来回拖动选定,需要注意的是左边是原图像,右边图像中展示为白色的就是我们要跟踪的图像。
首先需要确定你需要提取的颜色阈值范围,我这里选定的是图中的红色,也就是左边图像中从上往下数的第三个方块。上图中的阈值范围是我已经调节好的,我们如果要寻找红色,其实就是让右边这个二进制图像中显示白色的位置和左边的源图像中的红色位置是一致的。
在调节的过程中,要实时观察右边的二进制图像。从默认的LAB值范围开始,逐步缩小或扩大值的范围,直到目标区域完全呈现为白色,背景为黑色。然后记录最下面的LAB阈值,在这里是(0, 79, 31, 67, 26, 60),就是当前环境下我的屏幕上红色的阈值。具体调节的效果可以看下面这个动图:
学习时间:8月10日
1. 本节介绍
内容解读
本节明确了学习核心是基于颜色阈值的色块检测技术,通过定义特定颜色范围,从摄像头图像中识别并标记目标色块,同时结合图像绘制实现可视化。学习目标聚焦于两点:掌握庐山派开发板寻找色块的方法,以及理解颜色阈值调节逻辑以提升识别准确性。注意事项强调了LAB色彩空间参数设置的重要性,以及无屏幕时IDE缓冲区查看可能出现的帧率问题。
理解与感悟
这部分起到了提纲挈领的作用,让学习者一开始就清楚学习的方向和重点。颜色识别的关键在于准确捕捉目标颜色的特征范围,而LAB色彩空间在其中扮演重要角色,这提示我在后续学习中要重点关注该色彩空间的特性。同时,注意事项也很实用,提前告知了可能遇到的硬件相关问题,让学习者有心理预期。
2. 颜色识别的基本原理
内容解读
颜色识别的核心步骤包括获取图像、颜色空间转换、阈值匹配、区域分析、标记与输出。庐山派内置的图像处理库会自动完成中间关键环节,开发者只需定义颜色范围。
理解与感悟
这个原理框架清晰地展现了颜色识别的流程。获取图像是基础,就像人眼观察事物一样,首先要“看到”东西。颜色空间转换则是将原始图像信息转换为更便于分析的形式,如同将一种语言翻译成另一种更适合特定场景的语言。阈值匹配是筛选目标的关键,类似于设置一个标准,符合标准的才被选中。区域分析能将零散的符合条件的像素整合,便于整体研究。最后的标记与输出则是将结果直观呈现,让我们能清晰看到识别效果。开发板内置库简化了中间步骤,让开发者能更专注于颜色范围的定义,降低了开发门槛。
3. 什么是LAB色彩空间?
3.1 RGB VS LAB
内容解读
表格对比了RGB和LAB色彩空间的通道组成、亮度与颜色关系、光照敏感性、直观性和色域范围。LAB色彩空间中,L通道表示亮度(0-100),A通道表示红-绿(-128-127,负值偏绿,正值偏红),B通道表示蓝-黄(-128-127,负值偏蓝,正值偏黄)。
理解与感悟
通过对比,能明显看出LAB色彩空间在颜色识别中的优势。RGB的亮度和颜色信息混合,光照变化对其影响大,这会导致在不同光照条件下,同一颜色的RGB值可能差异很大,不利于稳定识别。而LAB将亮度和颜色分离,A、B通道受光照影响小,更能稳定地表示颜色特征,这也解释了为什么本节要使用LAB色彩空间进行颜色识别。比如在实际场景中,同一红色物体在强光和弱光下,其亮度会变化,但红色的本质特征在A通道中能更稳定地体现,从而提高识别的准确性。
3.2 关键提示
内容解读
尽管LAB对光照的鲁棒性优于RGB,但实际场景中环境光仍会影响识别效果,需保证检测环境光照一致性,且调节阈值时要在目标使用环境下进行。
理解与感悟
这提示我们理论优势在实际应用中会受到环境因素的制约。即使LAB相对稳定,也不能完全忽视光照的影响。在实际开发中,要尽量为识别场景创造稳定的光照条件,比如避免强光直射、逆光等。同时,阈值调节必须结合实际使用环境,不能在实验室调好后就一成不变,因为不同环境的光照差异可能导致阈值失效,这体现了理论联系实际的重要性。
4. find_blobs
(寻找图像中色块)
4.1 API原型
内容解读
给出了find_blobs
函数的原型,该函数用于从图像中筛选符合颜色阈值的色块,并返回包含色块特征的对象列表。
理解与感悟
API原型是函数使用的基础,它明确了函数的参数和返回值形式。对于开发者来说,熟悉原型是正确调用函数的前提,只有知道每个参数的含义和用法,才能根据实际需求进行合理设置。
4.2 核心参数解释
内容解读
表格解释了thresholds
、invert
、roi
、area_threshold
、pixels_threshold
、merge
等核心参数的功能。其中thresholds
根据图像类型有不同的格式,roi
用于限定检测区域,area_threshold
和pixels_threshold
用于过滤噪点,merge
用于合并重叠色块。
理解与感悟
这些参数的设置直接影响色块识别的效果。thresholds
是核心中的核心,它决定了哪些颜色会被识别出来,其格式的不同要求也体现了函数的灵活性。roi
参数很实用,通过限定检测区域,可以减少无关区域的干扰,提高识别效率,比如在一些特定场景中,我们只需要关注图像的某个部分。area_threshold
和pixels_threshold
能有效过滤掉一些小的噪点色块,避免误识别,让结果更准确。merge
参数则在处理多个重叠色块时很有用,能将它们合并为一个整体进行分析。
4.3 阈值获取方法
内容解读
介绍了通过CanMV IDE获取目标颜色LAB阈值的方法:在IDE帧缓冲区内框选目标颜色区域查看直方图分布范围,或通过“工具”→“机器视觉”→“阈值编辑器”可视化调节。
理解与感悟
这些方法为获取准确的阈值提供了便利。手动框选区域查看直方图能让我们直观地了解目标颜色在LAB各通道的分布范围,而阈值编辑器的可视化调节更是降低了阈值设置的难度,通过实时观察调节效果,能快速找到合适的阈值范围,提高开发效率。
5. 寻找特定颜色色块(代码示例)
代码结构分析
1. 初始化部分
sensor.reset() # 重置摄像头
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为RGB565
sensor.set_framesize(sensor.QVGA) # 设置帧大小为QVGA (320x240)
sensor.skip_frames(time=2000) # 跳过2秒,等待摄像头稳定
这部分代码完成了摄像头的初始化工作:
sensor.reset()
是硬件复位操作,确保摄像头处于初始状态- 选择RGB565格式是因为大多数图像处理API都支持这种格式
- QVGA分辨率(320x240)在保证一定清晰度的同时,能减少计算量
- 等待2秒是为了让摄像头的自动曝光、白平衡等参数稳定下来
2. 显示设备初始化
这部分代码体现了开发板的灵活性,通过异常处理机制适配不同的显示设备:
- 优先尝试初始化LCD屏幕
- 失败则尝试HDMI显示
- 最后使用虚拟显示器(IDE中查看)
这种设计使得代码可以在不同硬件配置下运行,提高了代码的可移植性。
3. 颜色阈值定义
red_threshold = [(30, 100, 15, 127, 15, 127)] # 红色的LAB阈值范围
这是颜色识别的核心参数,每个阈值是一个六元组,分别代表:
- (L_min, L_max, A_min, A_max, B_min, B_max)
- 这里定义的是红色的LAB范围,实际应用中需要根据目标颜色调整
4. 主循环与色块检测
while True:img = sensor.snapshot() # 拍摄一帧图像blobs = img.find_blobs(red_threshold, merge=True) # 寻找色块
主循环中,程序不断采集图像并进行色块检测:
sensor.snapshot()
获取当前帧图像find_blobs()
是核心函数,参数说明:red_threshold
:要检测的颜色阈值merge=True
:合并重叠或相邻的色块,避免同一物体被识别为多个色块
5. 色块处理与可视化
for blob in blobs:# 绘制矩形框住色块img.draw_rectangle(blob.rect(), color=(0, 255, 0))# 在色块中心绘制十字img.draw_cross(blob.cx(), blob.cy(), color=(0, 255, 0))
这部分实现了识别结果的可视化:
draw_rectangle()
用绿色矩形框出每个色块draw_cross()
在色块中心绘制十字标记- 这些可视化操作不影响原始图像数据,仅用于展示
6. 色块信息输出
代码打印了色块的关键信息,这些信息在实际应用中非常有用:
- 位置坐标(x, y):色块左上角位置
- 尺寸信息(w, h):色块的宽度和高度
- 中心坐标(cx, cy):色块中心点,可用于目标跟踪
- 面积(area):色块包含的像素数量,可用于判断目标大小
关键技术点解析
-
颜色空间选择:虽然代码中设置的是RGB565格式,但
find_blobs
函数内部会自动将图像转换为LAB色彩空间进行处理,这也是为什么阈值需要用LAB格式定义。 -
阈值调节:代码中使用的红色阈值是示例值,实际应用中需要:
- 通过CanMV IDE的阈值编辑器获取准确值
- 在实际使用环境中进行校准,考虑光照影响
-
性能优化:
- 使用QVGA分辨率而非更高分辨率,平衡识别精度和速度
merge=True
减少了后续处理的工作量- 适当的延时(
time.sleep_ms(100)
)降低系统负载
-
错误处理:显示设备初始化部分使用了try-except结构,增强了代码的健壮性。
实际应用扩展思路
- 多颜色识别:可以定义多个颜色阈值,如同时识别红、绿、蓝三种颜色
- 目标跟踪:利用色块中心坐标(cx, cy)实现简单的目标跟踪功能
- 尺寸过滤:通过面积(area)或宽高(w, h)过滤掉过小或过大的色块,减少误识别
- 区域限制:使用
roi
参数限定检测区域,提高识别效率和准确性
这段代码虽然简单,但包含了颜色识别的核心流程,是实现更复杂机器视觉应用的基础。在实际使用中,最关键的是根据具体场景调整颜色阈值和其他参数,以获得最佳的识别效果。
6. 如何进行阈值调节
内容解读
详细介绍了阈值调节的步骤:运行程序在帧缓冲区显示图像并固定,通过CanMV IDE的阈值编辑器,设定图像来源为帧缓冲区,拖动通道范围使目标区域在二进制图像中呈现白色,背景为黑色,最后记录LAB阈值。
理解与感悟
阈值调节是颜色识别中非常关键的操作,直接影响识别的准确性。这个详细的步骤指南让初学者能够轻松上手。固定图像便于精确调节,阈值编辑器的可视化操作让调节过程更加直观,通过观察二进制图像中目标区域的变化,能快速找到最佳的阈值范围。同时,注意调节后取消禁用帧缓冲区的提示也很重要,避免后续程序运行出现问题。这部分内容体现了开发工具的人性化设计,为开发者提供了便利。
学习总结:
通过对各章节的学习,我对基于立创·庐山派K230CanMV开发板的颜色识别技术有了全面的认识。从颜色识别的基本原理,到LAB色彩空间的优势,再到find_blobs
函数的使用和阈值调节方法,形成了一个完整的知识体系。理论知识为实践提供了指导,而代码示例和操作步骤则让理论得以落地。在实际应用中,需要综合考虑光照条件、阈值设置、区域选择等因素,不断优化识别效果。这次学习不仅掌握了具体的技术,更体会到了理论与实践相结合的重要性,以及在开发过程中不断调试和优化的必要性。