当前位置: 首页 > ops >正文

机器视觉opencv教程(四):图像颜色识别与颜色替换

图像颜色识别与颜色替换

前言

图像颜色识别与替换是计算机视觉的基础应用(如交通灯识别、产品分拣、图像美化等),核心是通过HSV 颜色空间实现更直观的颜色定位,并借助掩膜(Mask) 选择性提取或修改目标颜色。相较于 RGB 颜色空间,HSV 更符合人类对颜色的感知逻辑,是颜色相关任务的首选方案。

一、核心基础:HSV 颜色空间

HSV(Hue - 色调、Saturation - 饱和度、Value - 亮度)是一种基于人眼对颜色感知的颜色模型,与 RGB(红、绿、蓝)的 “三原色叠加” 逻辑完全不同,更适合颜色分割与识别。

1.1 HSV 与 RGB 的核心区别

维度RGB 颜色空间HSV 颜色空间
表示逻辑加色法模型,通过红、绿、蓝三通道强度叠加表示颜色基于 “颜色属性”,通过色调、饱和度、亮度三维度描述颜色
人类感知匹配不直观(调整红色需同时修改 R、G、B 通道)高度匹配(人类对颜色的认知就是 “什么色、艳不艳、亮不亮”)
颜色分割难度高(通道耦合性强,易受光照影响)低(色调 H 独立区分颜色,光照影响可通过亮度 V 调整)
适用场景图像显示(屏幕、相机)颜色识别、分割、替换(计算机视觉任务)

1.2 HSV 三分量详解

HSV 通过三个独立分量精准描述颜色,各分量的定义、取值范围(含 OpenCV 适配)及意义如下:

分量中文名称定义(核心作用)标准取值范围OpenCV 取值范围(8 位像素)关键说明
H色调区分颜色种类(如红、黄、绿)0°~360°0~179(360° 压缩为 0~179)0 = 红,60 = 黄,120 = 绿,180 = 青,240 = 蓝,300 = 紫
S饱和度描述颜色纯度(鲜艳程度)0%~100%0~255S=0→灰度(无色),S=255→纯色(最鲜艳)
V亮度描述颜色明暗程度0%~100%0~255V=0→黑色,V=255→最亮(白色或纯色最亮状态)

例:纯红色的 HSV 值(标准)为 (0°, 100%, 100%),在 OpenCV 中对应 (0, 255, 255);浅红色(偏灰、较暗)可能为 (0, 100, 150)。

1.3 HSV 色域图

HSV 色域可理解为“圆锥体”结构:

  • 圆锥的高度对应亮度 V(从下到上:0→255,黑色→白色);
  • 圆锥的半径对应饱和度 S(从中心到边缘:0→255,灰度→纯色);
  • 圆锥的圆周角度对应色调 H(0°→360°,红→黄→绿→蓝→紫→红)。
    在这里插入图片描述
    在这里插入图片描述

二、关键操作:掩膜(Mask)

掩膜是颜色识别与替换的 “筛选工具”,通过二值化图像实现对目标区域的选择性操作。

2.1 掩膜的定义与特点

  • 定义:与原始图像尺寸完全相同的二值化图像(仅含 0 和 255 两个像素值)。

  • 核心特点:

    • 白色区域(像素值 = 255):“保留区”—— 后续操作仅作用于该区域;
    • 黑色区域(像素值 = 0):“遮挡区”—— 后续操作忽略该区域。

2.2 掩膜的核心作用

  1. 选择性提取:仅保留图像中符合条件的区域(如 “只提取黄色区域”);
  2. 选择性修改:仅修改图像中符合条件的区域(如 “只把红色区域换成蓝色”);
  3. 噪声过滤:结合形态学操作(如开运算),去除掩膜中的细小杂点。

三、实战 1:图像颜色识别(提取目标颜色)

通过 “HSV 转换→生成掩膜→位与运算” 三步,从图像中精准提取指定颜色(以提取黄色为例)。

# 图像颜色识别:提取指定颜色(黄色)
import cv2
import numpy as np# 步骤1:图像读取与预处理
# cv2.imread:读取图像(OpenCV默认读取为BGR格式,非RGB)
image_np = cv2.imread('./color.png')
# cv2.resize:调整图像大小(700x700),方便观察(非必需,按需调整)
image_np = cv2.resize(image_np, (700, 700))# 步骤2:将BGR图像转换为HSV图像(颜色识别的关键一步)
# cv2.COLOR_BGR2HSV:OpenCV专用的BGR→HSV转换标识(必须用这个,不能用COLOR_RGB2HSV)
hsv_image_np = cv2.cvtColor(image_np, cv2.COLOR_BGR2HSV)# 步骤3:定义目标颜色(黄色)的HSV范围,生成掩膜
# lowerb:HSV范围下限(H=26, S=43, V=46)——黄色的最低阈值
lowerb = np.array([26, 43, 46])
# upperb:HSV范围上限(H=34, S=255, V=255)——黄色的最高阈值
upperb = np.array([34, 255, 255])
# cv2.inRange:生成掩膜——HSV值在[lowerb, upperb]内的像素设为255(白),否则设为0(黑)
mask_image_np = cv2.inRange(hsv_image_np, lowerb, upperb)# 步骤4:位与运算——用掩膜提取目标颜色
# cv2.bitwise_and:仅保留掩膜中白色区域(255)的原图像素,其他区域设为0(黑)
color_image_np = cv2.bitwise_and(image_np, image_np, mask=mask_image_np)# 步骤5:显示结果
cv2.imshow("掩膜(Mask)", mask_image_np)    # 显示掩膜
cv2.imshow("提取的黄色区域", color_image_np)  # 显示提取的目标颜色
cv2.waitKey(0)  # 等待任意按键关闭窗口(0表示无限等待)
cv2.destroyAllWindows()  # 释放窗口资源

3.2 关键步骤解析

(1)图像读取:注意 BGR 格式
  • OpenCV 的cv2.imread()默认将图像读取为BGR 格式(红和蓝通道颠倒),后续转 HSV 必须用cv2.COLOR_BGR2HSV,而非COLOR_RGB2HSV(否则颜色转换错误)。
(2)HSV 范围确定:核心难点
  • 目标颜色的 HSV 范围(lowerbupperb)需根据实际需求调整,可通过 “颜色拾取工具” 或 “调试法” 确定(例:红色的 HSV 范围可能是[0,43,46]~[10,255,255])。
  • 参考常用颜色的 OpenCV-HSV 范围:
    红色:[0,43,46]~[10,255,255] | 绿色:[35,43,46]~[77,255,255] | 蓝色:[100,43,46]~[124,255,255]
(3)位与运算:掩膜的应用
  • cv2.bitwise_and(src1, src2, mask):当src1=src2=原图时,掩膜mask会筛选出原图中需保留的区域 —— 仅mask=255的位置保留src1&src2(即原图像素),mask=0的位置结果为 0(黑色)。

四、实战 2:图片颜色替换(修改目标颜色)

在颜色识别的基础上,增加 “掩膜优化(开运算去噪)” 和 “颜色替换” 步骤,将指定颜色修改为目标颜色(以 “红色→蓝色” 为例)。

4.1 完整代码

# 图片颜色替换:将红色区域替换为蓝色
import cv2
import numpy as np# 步骤1:图像读取与初始显示
image_np = cv2.imread('./color.png')
cv2.imshow("原始图像", image_np)  # 显示原图# 步骤2:将BGR图像转换为HSV图像(减少光照干扰,便于颜色定位)
image_hsv = cv2.cvtColor(image_np, cv2.COLOR_BGR2HSV)# 步骤3:制作目标颜色(红色)的掩膜,并优化(开运算去噪)
# 3.1 定义红色的HSV范围
color_lower = np.array([0, 43, 46])    # 红色HSV下限
color_high = np.array([10, 255, 255])  # 红色HSV上限
# 3.2 生成初始掩膜
image_mask = cv2.inRange(image_hsv, color_lower, color_high)
# 3.3 开运算:先腐蚀再膨胀,去除掩膜中的细小白色噪点(避免替换时误改杂点)
# 构建3x3矩形核(结构化元素)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 执行开运算(cv2.MORPH_OPEN表示开运算)
image_mask_open = cv2.morphologyEx(image_mask, cv2.MORPH_OPEN, kernel)# 步骤4:执行颜色替换(核心步骤)
# 方式1:数组索引(高效,推荐)——直接将掩膜白色区域的像素设为蓝色(BGR格式:(255,0,0))
image_np[image_mask_open == 255] = (255, 0, 0)  # 注意:OpenCV中蓝色是(255,0,0),非(0,0,255)# 方式2:循环遍历(低效,不推荐)——适合理解原理,大图像耗时
# for i in range(image_mask_open.shape[0]):  # 遍历行(高度)
#     for j in range(image_mask_open.shape[1]):  # 遍历列(宽度)
#         if image_mask_open[i, j] == 255:  # 若为掩膜白色区域
#             image_np[i, j] = (255, 0, 0)  # 替换为蓝色# 步骤5:显示结果
cv2.imshow("优化后的掩膜", image_mask_open)  # 显示去噪后的掩膜
cv2.imshow("颜色替换后图像", image_np)      # 显示替换结果
cv2.waitKey(0)
cv2.destroyAllWindows()

4.2 关键步骤解析

(1)掩膜优化:开运算的作用
  • 初始掩膜(image_mask)可能包含细小白色噪点(如图像中的灰尘、光斑),若直接用于替换,会导致 “误改无关区域”。
  • 开运算(cv2.MORPH_OPEN):先腐蚀(消除小噪点)再膨胀(恢复目标区域大小),既能去除噪点,又不影响目标区域的整体形状。
(2)颜色替换:注意 BGR 通道顺序
  • OpenCV 中颜色用BGR 格式表示,而非 RGB:
    蓝色 → (255, 0, 0)(B=255,G=0,R=0);
    红色 → (0, 0, 255)(B=0,G=0,R=255);
    绿色 → (0, 255, 0)(B=0,G=255,R=0)。
  • 数组索引方式(image_np[image_mask_open == 255] = (255,0,0))比循环遍历高效 10~100 倍,尤其适合大图像。

五、关键总结与注意事项

5.1 常见问题与解决方案

  1. 颜色提取错误
    • 原因:HSV 范围设置不当,或用了COLOR_RGB2HSV(而非COLOR_BGR2HSV)。
    • 解决:调整lowerbupperb(参考常用颜色范围),确保转换标识正确。
  2. 替换后有杂色
    • 原因:掩膜含细小噪点,导致误替换。
    • 解决:增加开运算(cv2.MORPH_OPEN),或调大核尺寸(如(5,5))。
  3. 颜色替换后显示异常
    • 原因:混淆 BGR 和 RGB 格式(如将蓝色设为(0,0,255))。
    • 解决:牢记 OpenCV 用 BGR,蓝色是(255,0,0),红色是(0,0,255)

5.2 操作流程梳理

任务核心流程关键差异
颜色识别读取图像→BGR 转 HSV→生成掩膜→位与提取→显示无需形态学操作(简单场景),需位与运算
颜色替换读取图像→BGR 转 HSV→掩膜制作→开运算去噪→颜色替换→显示需掩膜优化(开运算),需数组索引替换
http://www.xdnf.cn/news/19261.html

相关文章:

  • Linux中的ss命令
  • kotlin - 2个Activity实现平行视图,使用SplitPairFilter
  • 网络流量分析——使用Wireshark进行分析
  • Shell脚本编程——变量用法详解
  • Ruoyi-vue-plus-5.x第二篇MyBatis-Plus数据持久层技术:2.2 分页与性能优化
  • DAY17-新世纪DL(DeepLearning/深度学习)战士:Q(机器学习策略)2
  • AI 应用 图文 解说 (二) -- 百度智能云 ASR LIM TTS 语音AI助手源码
  • 自定义AXI_PWM_v1.0——ZYNQ学习笔记15
  • Spring Task快速上手
  • Maven学习笔记01
  • 【stm32】对射式红外传感器计次以及旋转编码器计次
  • SpringBoot 自研运行时 SQL 调用树,3 分钟定位慢 SQL!
  • 用产品经理的思维,重构AI时代的增长Playbook
  • 企业数据湖:从混沌到秩序的分层设计与治理策略
  • 11.1.5 实现文件删除,共享和共享下载排行榜
  • 分布式测试平台ITP:让自动化测试更高效、更稳定
  • SW - 用装配图的方式组合多个子零件然后转换成为零件,可维护性好
  • 组件通信终极指南:从Props Drilling到Context API
  • react-virtualized React 应用中高效渲染大型列表和表格数据的库
  • 扣子(coze)实践指南进阶篇——创建工作流,并将工作流接入智能体
  • 2025年8月个人工作生活总结
  • [Windows] 某音下载工具——自用
  • Selenium 等待机制:编写稳定可靠的自动化脚本
  • Kubernetes中kubeadm、kubectl、kubelet的区别与作用
  • 动态规划入门(三):一些经典动态规划模型
  • arnold图像加密(猫脸变换)
  • 一个从7zip中分离出来的高压缩比文本压缩工具ppmd
  • 文件系统深度解析:从核心概念到代码实践
  • 【MLLM】多模态理解Ovis2.5模型和训练流程(更新中)
  • 手写MyBatis第43弹:插件拦截原理与四大可拦截对象详解