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

机器视觉学习-day05-图片颜色识别及颜色替换

1 颜色识别

图片颜色识别主要通过掩膜对原图像进行与运算来找到要识别的颜色。

1.1 RGB颜色空间

在图像处理中,最常见的就是RGB颜色空间。RGB颜色空间是我们接触最多的颜色空间,是一种用于表示和显示彩色图像的一种颜色模型。RGB代表红色(Red)、绿色(Green)和蓝色(Blue),这三种颜色通过不同强度的光的组合来创建其他颜色。

2 HSV颜色空间

HSV颜色空间(HSV颜色模型,也成为HSL)是一种与RGB颜色模型并列的颜色空间表示法。

HSV颜色空间使用色调或色相(Hue)、饱和度(Saturation)和亮度或明度(Value)三个参数来表示颜色,色调 H 表示颜色的种类,如红色、绿色、蓝色等;饱和度 S 表示颜色的纯度或强度,如红色越纯,饱和度就越高;亮度 V 表示颜色的明暗程度,如黑色比白色亮度低。

由于HSV的颜色是连续的,比RGB更适合进行颜色范围划分,常见的颜色经过试验得到的范围如下:

代码运行步骤:图片输入→HSV空间转换→制作掩膜→与运算→图片输出

掩膜(Mask)是一种在图像处理中常见的操作(类似于PS中的蒙版),它可以选择性地遮挡图像的某个部分,从而实现特定任务的目标。掩膜通常是一个二值化图像,并且与原图相同大小,其中目标区域被设置为255(白色),而其他区域设置为0(黑色),目标区域可以根据HSV的参数修改,通过掩膜可以使用白色区域操作原图中的同位置像素。

与运算在图像处理中,与运算被用来对像素进行操作,可以将两个图像中的所有对应像素值进行与运算操作。

原图名称:demo.jpg

import cv2
import numpy as npif __name__ == '__main__':# 1.图片输入path = 'demo.jpg'  # 图像文件路径image_np = cv2.imread(path)  # 读取图像为NumPy数组(BGR格式)# 2.HSV空间转换hsv_image_np = cv2.cvtColor(image_np, cv2.COLOR_BGR2HSV)  # BGR转HSV# print(hsv_image_np.shap) # 打印HSV图像的维度(高度, 宽度, 通道数)# print(hsv_image_np)           # (注释)打印HSV像素值数组# 3. 制作掩膜# 定义红色范围1red_low = np.array([0, 43, 46])  # 红色下限(Hmin, Smin, Vmin)red_high = np.array([10, 255, 255])  # 红色上限(Hmax, Smax, Vmax)mask1 = cv2.inRange(  # 创建二值掩膜hsv_image_np,  # 基于哪个图像, 输入HSV图像red_low,  # 颜色下限red_high  # 颜色上限)# print(mask1.shape)# print(mask1)# 定义红色范围2red_low = np.array([156, 43, 46])  # 红色第二范围下限(深红色)red_high = np.array([180, 255, 255])  # 第二范围上限# 制作掩膜mask2 = cv2.inRange(  # 创建第二个掩膜hsv_image_np,red_low,red_high)# 合并掩膜mask_image_np = cv2.bitwise_or(mask1, mask2)  # 创建第二个掩膜# print(mask_image_np.shape)# print(mask_image_np)# 原图和掩膜进行 与操作color_image_np = cv2.bitwise_and(  # 按位与操作image_np,  # 原始图像image_np,  # 再次使用原始图像mask=mask_image_np  # 应用合并后的掩膜)  # 掩膜# print(color_image_np.shape) # 输出结果图像维度# print(color_image_np)# 输出结果像素数组# 图片输出cv2.imshow('mask1:', mask1)  # 显示第一个红色掩膜cv2.imshow('mask2:', mask2)  # 显示第二个红色掩膜cv2.imshow('mask_image_np', mask_image_np)  # 显示合并掩膜cv2.imshow('color_image_np', color_image_np)  # 显示提取的红色区域cv2.waitKey(0)  # 等待按键(0表示无限等待)

运行后结果:

mask1.png 

mask2.png

合并后的掩膜:

color_red_np.png:

3 颜色替换

在图像中识别某一种(多种)颜色,那么就可以对这些颜色进行单独操作,比如替换成其他的颜色,原理就是在得到掩膜后,对掩膜中白色区域的原图进行一个像素值的修改。

代码运行步骤:图片输入→HSV空间转换→制作掩膜→开运算→颜色替换→图片输出

在形态学变换章节中学习了腐蚀和膨胀的工作原理,开运算就是先对图像进行腐蚀操作,再进行膨胀操作,开运算的效果是可以去除二值化图中的小噪点,并分离相连的物体。

由于掩膜与原图的大小相同,并且像素的一一对应的,可以得到掩膜中的白色区域坐标,把掩膜中所有白色区域的坐标带入到原图中,就可以得到原图中所有红色区域的坐标。拿到原图红色的坐标后,可以进行任何红色像素值的操作,例如修改颜色。

图片名称:image.jpg

import cv2
import numpy as npif __name__ == '__main__':# 1.图片输入path = 'image.jpg'image_np = cv2.imread(path)  # 读取图片到NumPy数组(BGR格式)# 2.HSV空间转换hsv_image_np = cv2.cvtColor(image_np, cv2.COLOR_BGR2HSV)  # 将图片从BGR颜色空间转换为HSV颜色空间# print(hsv_image_np) # 打印HSV图像的维度(高度, 宽度, 通道数)# 3. 制作掩膜# 定义红色范围1(HSV格式:0°-10°)red_low = np.array([0, 43, 46])red_high = np.array([10, 255, 255])# 制作掩膜1mask1 = cv2.inRange(hsv_image_np,  # 基于哪个图像就输入哪个图像(HSV图像)red_low,  # 颜色下限red_high  # 颜色上限)  # 创建二值掩膜:在红色范围内的像素为255(白色),其余为0(黑色)# print(mask1.shape)  # 打印掩膜维度(单通道)# print(mask1)        # 打印掩膜数据(二维数组)# 定义红色范围2(HSV格式:156°-180°)red_low = np.array([156, 43, 46])red_high = np.array([180, 255, 255])# 制作掩膜mask2 = cv2.inRange(hsv_image_np,red_low,  # 颜色下限red_high  # 颜色上限)# 合并掩膜mask_image_np = cv2.bitwise_or(mask1, mask2)  # 将两个掩膜合并(逻辑OR操作)# print(mask_image_np.shape)  # 打印合并后掩膜维度# print(mask_image_np)  # 打印合并掩膜数据# 4.图片矫正. 开运算(去噪)# 创建一个5x5矩形核kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 执行开运算open_image_np = cv2.morphologyEx(src=mask_image_np,  # 输入掩膜op=cv2.MORPH_OPEN,  # 开运算类型(先腐蚀后膨胀)kernel=kernel  # 使用的结构核)  # 去除小噪点,平滑物体边界# 颜色替换for i in range(open_image_np.shape[0]):  # 遍历高度方向for j in range(open_image_np.shape[1]):  # 遍历宽度方向# 如果当前遍历的像素点是掩膜的白色if open_image_np[i, j] == 255:  # 当开运算掩膜中为白色区域时# 给原图进行颜色替换为蓝色image_np[i, j] = (255, 0, 0)  # 将原图对应像素改为蓝色(BGR格式)# 6. 图片输出cv2.imshow('mask_image_np', mask_image_np)  # 显示原始掩膜cv2.imshow('open_image_np', open_image_np)  # 显示开运算后的掩膜cv2.imshow('image_np', image_np)  # 显示处理后的原图(红色变蓝)cv2.waitKey(0)  # 等待任意按键关闭窗口cv2.imwrite('blue.png', image_np)

原始掩膜:mask_image_np.png

开运算后的掩膜:open_image_np.png

最终结果:blue.png

http://www.xdnf.cn/news/1377253.html

相关文章:

  • 指针 (六):sizeof和strlen细节强化之“做题篇”
  • 深度学习:常用的损失函数的使用
  • Python随机选择完全指南:从基础到高级工程实践
  • 数据库:缓冲池和磁盘I/O
  • FPGA入门学习路径
  • 【Python 提高】GUI 界面 Tkinter 库布局管理器 Pack 方法开发指南
  • 树的常见算法及Java实现
  • 【yocto】Yocto Project 核心:深入了解.inc文件
  • Java循环结构全解析
  • android 嵌套webview 全屏展示 页面延伸到状态栏且不被底部导航栏遮挡
  • 高并发内存池(11)-PageCache获取Span(下)
  • 【C++标准库】<ios>详解基于流的 I/O
  • 腾讯云 CVM 上的 SpringBoot 应用避免非法访问
  • 寄存器的原理
  • YOLOv8-SMOT:一种高效鲁棒的实时小目标跟踪框架:基于切片辅助训练与自适应关联
  • 人工智能-python-深度学习-反向传播优化算法
  • ESP32使用场景及大规模物联网IoT
  • 流水线用到的Dockerfile和构建脚本build.sh
  • 如何安装 mysql-installer-community-8.0.21.0.tar.gz(Linux 详细教程附安装包下载)​
  • 神经网络学习笔记11——高效卷积神经网络架构SqueezeNet
  • 聊一聊 单体分布式 和 微服务分布式
  • 深度学习——优化函数
  • 自学嵌入式第二十九天:Linux系统编程-线程
  • flume监控文件写入 Kafka 实战:解耦应用与消息队列的最佳实践
  • 在语言模型监督式微调(SFT)中的 负对数似然(Negative Log-Likelihood, NLL)等价于最大化似然
  • 软考-系统架构设计师 管理信息系统(MIS)详细讲解
  • 为什么编码智能体可以重塑开发范式?
  • 【Mascaret】QGIS中Mascaret插件的使用
  • ESP8266:Arduino学习
  • 高并发内存池(12)-ThreadCache回收内存