【IP101】图像处理基础:从零开始学习颜色操作(RGB、灰度化、二值化、HSV变换)

🎨 颜色操作详解

🌟 在图像处理的世界里,颜色操作就像是一个魔术师的基本功。今天,让我们一起来解锁这些有趣又实用的"魔法"吧!

📚 目录

  1. 通道替换 - RGB与BGR的"调包"游戏
  2. 灰度化 - 让图像"褪色"的艺术
  3. 二值化 - 非黑即白的世界
  4. 大津算法 - 自动寻找最佳阈值的智慧之眼
  5. HSV变换 - 探索更自然的色彩空间

🔄 通道替换

理论基础

在计算机视觉中,我们经常会遇到RGB和BGR两种颜色格式。它们就像是"外国人"和"中国人"的称呼顺序,一个是姓在后,一个是姓在前。😄

对于一个彩色图像 I I I,其RGB通道可以表示为:

I R G B = [ R G B ] I_{RGB} = \begin{bmatrix} R & G & B \end{bmatrix} IRGB=[RGB]

通道替换操作可以用矩阵变换表示:

I B G R = I R G B [ 0 0 1 0 1 0 1 0 0 ] I_{BGR} = I_{RGB} \begin{bmatrix} 0 & 0 & 1 \\ 0 & 1 & 0 \\ 1 & 0 & 0 \end{bmatrix} IBGR=IRGB 001010100

代码实现

// C++实现
vector<Mat> channels;
split(src, channels);
vector<Mat> new_channels = {channels[2],  // Rchannels[1],  // Gchannels[0]   // B
};
# Python实现
b, g, r = cv2.split(img)
result = cv2.merge([r, g, b])

🌫️ 灰度化

理论基础

将彩色图像转换为灰度图像,就像是把一幅油画变成素描。我们使用加权平均的方法,因为人眼对不同颜色的敏感度不同。

标准RGB到灰度的转换公式:

Y = 0.2126 R + 0.7152 G + 0.0722 B Y = 0.2126R + 0.7152G + 0.0722B Y=0.2126R+0.7152G+0.0722B

这个公式来自于ITU-R BT.709标准,考虑了人眼对不同波长光的敏感度。更一般的形式是:

Y = ∑ i ∈ { R , G , B } w i ⋅ C i Y = \sum_{i \in \{R,G,B\}} w_i \cdot C_i Y=i{R,G,B}wiCi

其中 w i w_i wi 是权重系数, C i C_i Ci 是对应的颜色通道值。

为什么是这些权重?

  • 👁️ 人眼对绿色最敏感 (0.7152)
  • 👁️ 其次是红色 (0.2126)
  • 👁️ 对蓝色最不敏感 (0.0722)

代码实现

// C++实现
result.at<uchar>(y, x) = static_cast<uchar>(0.2126 * r + 0.7152 * g + 0.0722 * b
);

⚫⚪ 二值化

理论基础

二值化就像是给图像下"最后通牒":要么是黑色,要么是白色,没有中间地带!

数学表达式:

g ( x , y ) = { 255 , if  f ( x , y ) > T 0 , if  f ( x , y ) ≤ T g(x,y) = \begin{cases} 255, & \text{if } f(x,y) > T \\ 0, & \text{if } f(x,y) \leq T \end{cases} g(x,y)={255,0,if f(x,y)>Tif f(x,y)T

其中:

  • f ( x , y ) f(x,y) f(x,y) 是输入图像在点 ( x , y ) (x,y) (x,y) 的灰度值
  • g ( x , y ) g(x,y) g(x,y) 是输出图像在点 ( x , y ) (x,y) (x,y) 的值
  • T T T 是阈值

应用场景

  • 📄 文字识别
  • 🎯 目标检测
  • 🔍 边缘检测

代码实现

// C++实现
result.at<uchar>(y, x) = (gray.at<uchar>(y, x) > threshold) ? 255 : 0;

🎯 大津算法

理论基础

大津算法就像是一个"智能裁判",能自动找到最佳的分割阈值。它通过最大化类间方差来实现这一目标。

类间方差的计算公式:

σ B 2 ( t ) = ω 0 ( t ) ω 1 ( t ) [ μ 0 ( t ) − μ 1 ( t ) ] 2 \sigma^2_B(t) = \omega_0(t)\omega_1(t)[\mu_0(t) - \mu_1(t)]^2 σB2(t)=ω0(t)ω1(t)[μ0(t)μ1(t)]2

其中:

  • ω 0 ( t ) \omega_0(t) ω0(t) 是前景像素的概率
  • ω 1 ( t ) \omega_1(t) ω1(t) 是背景像素的概率
  • μ 0 ( t ) \mu_0(t) μ0(t) 是前景像素的平均灰度值
  • μ 1 ( t ) \mu_1(t) μ1(t) 是背景像素的平均灰度值

最优阈值的选择:

t ∗ = arg ⁡ max ⁡ t { σ B 2 ( t ) } t^* = \arg\max_{t} \{\sigma^2_B(t)\} t=argtmax{σB2(t)}

算法步骤

  1. 📊 计算图像直方图
  2. 🔄 遍历所有可能的阈值
  3. 📈 计算类间方差
  4. 🎯 选择方差最大的阈值

代码实现

// 计算类间方差
double variance = wBack * wFore * pow(meanBack - meanFore, 2);

🌈 HSV变换

理论基础

HSV色彩空间更符合人类对颜色的感知方式,就像是把RGB这个"理工男"变成了更感性的"艺术家"。

  • 🎨 H (Hue) - 色相:颜色的种类
  • 💫 S (Saturation) - 饱和度:颜色的纯度
  • ✨ V (Value) - 明度:颜色的明暗

RGB到HSV的转换公式:

V = max ⁡ ( R , G , B ) V = \max(R,G,B) V=max(R,G,B)

S = { V − min ⁡ ( R , G , B ) V , if  V ≠ 0 0 , if  V = 0 S = \begin{cases} \frac{V-\min(R,G,B)}{V}, & \text{if } V \neq 0 \\ 0, & \text{if } V = 0 \end{cases} S={VVmin(R,G,B),0,if V=0if V=0

H = { 60 ( G − B ) / Δ , if  V = R 120 + 60 ( B − R ) / Δ , if  V = G 240 + 60 ( R − G ) / Δ , if  V = B H = \begin{cases} 60(G-B)/\Delta, & \text{if } V = R \\ 120 + 60(B-R)/\Delta, & \text{if } V = G \\ 240 + 60(R-G)/\Delta, & \text{if } V = B \end{cases} H= 60(GB),120+60(BR),240+60(RG),if V=Rif V=Gif V=B

其中 Δ = V − min ⁡ ( R , G , B ) \Delta = V - \min(R,G,B) Δ=Vmin(R,G,B)

应用场景

  • 🎨 颜色分割
  • 🎯 目标跟踪
  • 🌈 图像增强

代码实现

    // 手动实现RGB到HSV的转换for (int y = 0; y < src.rows; y++) {for (int x = 0; x < src.cols; x++) {Vec3b pixel = src.at<Vec3b>(y, x);float b = pixel[0] / 255.0f;float g = pixel[1] / 255.0f;float r = pixel[2] / 255.0f;float maxVal = max(max(r, g), b);float minVal = min(min(r, g), b);float diff = maxVal - minVal;// 计算Hfloat h = 0;if (diff != 0) {if (maxVal == r) {h = 60 * (fmod(((g - b) / diff), 6));} else if (maxVal == g) {h = 60 * ((b - r) / diff + 2);} else {h = 60 * ((r - g) / diff + 4);}if (h < 0) h += 360;}// 计算Sfloat s = (maxVal == 0) ? 0 : diff / maxVal;// 计算Vfloat v = maxVal;// 转换到OpenCV的HSV范围result.at<Vec3b>(y, x) = Vec3b(static_cast<uchar>(h / 2),     // H: [0, 180]static_cast<uchar>(s * 255),   // S: [0, 255]static_cast<uchar>(v * 255)    // V: [0, 255]);}}

📝 实践小贴士

1. 数据类型转换注意事项

  • ⚠️ 防止数据溢出
  • 🔍 注意精度损失
  • 💾 考虑内存使用

2. 性能优化建议

  • 🚀 使用向量化操作
  • 💻 利用CPU的SIMD指令
  • 🔄 减少不必要的内存拷贝

3. 常见陷阱

  • 🕳️ 除零错误处理
  • 🌡️ 边界条件检查
  • 🎭 颜色空间转换精度

🎓 小测验

  1. 为什么RGB转灰度时绿色的权重最大?
  2. 大津算法的核心思想是什么?
  3. HSV色彩空间相比RGB有什么优势?
👉 点击查看答案
  1. 因为人眼对绿色最敏感
  2. 最大化类间方差,使前景和背景区分最明显
  3. 更符合人类对颜色的直观认知,便于颜色的选择和调整

🔗 相关算法

  • 图像增强
  • 边缘检测
  • 特征提取

💡 记住:颜色操作是图像处理的基础,掌握好这些操作,就像掌握了调色盘的魔法!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows系统搭建自己的ftp服务器,保姆级教程(用户验证+无验证)

前言 最近在搭建环境时&#xff0c;我发现每次都需要在网上下载依赖包和软件&#xff0c;这不仅耗时&#xff0c;而且有时还会遇到网络不稳定的问题&#xff0c;导致下载速度慢或者中断&#xff0c;实在不太方便。于是&#xff0c;我产生了搭建一个FTP服务器的想法。通过搭建FT…

蓝桥杯 7. 晚会节目单

晚会节目单 原题目链接 题目描述 小明要组织一台晚会&#xff0c;总共准备了 n 个节目。然而晚会时间有限&#xff0c;他只能从中选择 m 个节目。 这 n 个节目是按照小明设想的顺序给定的&#xff0c;顺序不能改变。 小明发现观众对于晚会的喜欢程度与前几个节目的好看程度…

JavaScript如何实现类型判断?

判断一个数据的类型&#xff0c;常用的方法有以下几种&#xff1a; typeofinstanceofObject.prototype.toString.call(xxx) 下面来分别分析一下这三种方法各自的优缺点 typeof typeof的本意是用来判断一个数据的数据类型&#xff0c;所以返回的也是一个数据类型。但是会遇到下…

哈希表笔记(四)Redis对比Java总结

文章目录 一、基础结构对比数据结构定义Java HashMapRedis字典 主要区别与设计思路 二、关键操作API对比初始化Java HashMapRedis字典 添加元素Java HashMapRedis字典 查找元素Java HashMapRedis字典 删除元素Java HashMapRedis字典 扩容/重哈希操作Java HashMapRedis字典 三、…

docker拉取国内镜像

1. 场景 最近整了一个tencent云服务器&#xff0c;想要玩一下docker&#xff0c;结果发现拉不下来&#xff0c;镜像根本拉不下来。 2. 原因 1.云服务器无法访问外网&#xff1b; 2. 国内的很多公有镜像仓库都被封了&#xff1b; 3. 推荐 https://zhuanlan.zhihu.com/p/713…

Codeforces Round 1008 (Div. 2) C

C 构造 题意&#xff1a;a的数据范围大&#xff0c;b的数据范围小&#xff0c;要求所有的a不同&#xff0c;考虑让丢失的那个a最大即可。问题变成&#xff1a;构造一个最大的a[i] 思路&#xff1a;令a2是最大的,将a1,a3,a5....a2*n1&#xff0c;置为最大的b&#xff0c;将a4,a…

STM32 HAL库实现USB虚拟串口

1. 引言 在嵌入式系统开发中&#xff0c;USB 虚拟串口是一种非常实用的功能。它允许 STM32 微控制器通过 USB 接口与计算机进行通信&#xff0c;就像使用传统的串口一样。这种方式不仅简化了硬件设计&#xff0c;还提高了通信的灵活性和稳定性。STM32F407 系列微控制器具有强大…

JAVA EE_网络原理_UDP与TCP

人海中未遇见时&#xff0c;我将独自前行... ----------陳長生. 1.UDP协议 1.1.UDP协议端格式 UDP&#xff08;用户数据报协议&#xff09;是由 源端口&#xff0c;目标端口&#xff0c;长度&#xff0c;校验和&#xff0c;数据 5种结构组成。16位是UDP报文中字段的长度&#…

【免费】1992-2021年各省GDP数据/各省地区生产总值数据

1992-2021年各省GDP数据/各省地区生产总值数据 1、时间&#xff1a;1992-2021年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;GDP/地区生产总值 4、范围&#xff1a;31省 5、指标说明:国内生产总值&#xff08;GDP&#xff09;是一个国家或地区在一定时期…

C++11新特性_范围-based for 循环

based for 循环介绍 范围 - based for 循环&#xff08;Range-based for loop&#xff09;是 C11 引入的一种新的 for 循环语法&#xff0c;它可以更简洁地遍历容器和数组。 遍历数组&#xff1a;定义了一个整数数组 arr&#xff0c;使用范围 - based for 循环 for (int num :…

【Bootstrap V4系列】学习入门教程之 页面内容排版

Bootstrap V4 学习入门教程之 页面内容排版 按钮上的指针排版一、Global settings 全局设置二、Headings 标题2.1 Customizing headings 自定义标题2.2 Display headings 显示标题2.3 Lead 引导 三、Blockquotes 块引用3.1 Naming a source 命名源3.2 Alignment 对齐 四、Lists…

Flowable7.x学习笔记(十六)分页查询我的待办

前言 我的待办具体区分为3种情况&#xff0c;第一个就是办理人指定就是我&#xff0c;我可以直接审批&#xff1b;第二种就是我是候选人&#xff0c;我需要先拾取任务然后再办理&#xff1b;第三种是我是候选组&#xff0c;我需要切换到指定的角色去拾取任务再办理。如果任务已…

EBO的使用

EBO 其实就是个索引&#xff0c;绑定在相应的VAO中&#xff0c;用来描述绘制顺序。比如在OpenGL绘制三角形的时候&#xff0c;假设有四个顶点&#xff0c;我称他们分别为1&#xff0c;2&#xff0c;3&#xff0c;4号顶点&#xff0c;常规绘制三角形函数是按三个点为一组&#x…

界面控件DevExpress WPF v25.1预览 - AI功能增强(语义搜索)

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

零基础做自动驾驶集成测试(仿真)

图 1&#xff1a;使用 GPUDrive 进行极快的多代理模拟。上图&#xff1a;GPUDrive 中 Waymo Open Motion Dataset 场景的鸟瞰图&#xff0c;方框表示受控智能体&#xff0c;圆圈表示其目标。底部&#xff1a;相应的代理视图&#xff0c;以一个代理为中心。可以根据用户的目标轻…

EasyRTC嵌入式音视频实时通话SDK技术,打造低延迟、高安全的远程技术支持

一、背景 在当今数字化时代&#xff0c;远程技术支持已成为解决各类技术问题的关键手段。随着企业业务的拓展和技术的日益复杂&#xff0c;快速、高效地解决远程设备与系统的技术难题变得至关重要。EasyRTC作为一款高性能的实时通信解决方案&#xff0c;为远程技术支持提供了创…

【C语言常用字符串解析】

总结一下在 C 语言中用于字符串解析&#xff08;特别是从文件中读取行并提取数据&#xff09;的常用函数、 核心任务&#xff1a; 通常是从文件中读取一行文本&#xff08;一个字符串&#xff09;&#xff0c;然后从这个字符串中提取出需要的数据&#xff08;比如数字、单词等…

SpringTas定时任务使用详解

文章目录 Spring Task概述1、环境配置2.注解实现定时任务2.注解实现定时任务4. cron表达式详解&#xff1a; Spring Task概述 在开发中&#xff0c;我们经常会用到定时任务&#xff0c;而Spring Task 则是Spring提供的定时任务框架。 其它定时任务实现框架又jdk自带Timer和Qua…

数字智慧方案6172丨智慧医院扩建信息化整体规划方案(60页PPT)(文末有下载方式)

资料解读&#xff1a;智慧医院扩建信息化整体规划方案 详细资料请看本解读文章的最后内容。 在信息技术飞速发展的当下&#xff0c;医疗行业的信息化建设成为提升医疗服务水平、优化医院管理的关键路径。这份智慧医院扩建信息化整体规划方案&#xff0c;针对医院扩建过程中的信…

ts全局导入接口

为了在项目中全局导入 ITableColumn 接口&#xff0c;避免每次使用时手动导入&#xff0c;可以通过以下步骤实现&#xff1a; 1. 全局导入的实现方式 在 Vue 项目中&#xff0c;可以通过在 src 目录下创建一个 global.d.ts 文件&#xff0c;将 ITableColumn 接口声明为全局类型…