【视觉基础篇】10 # 图形系统如何表示颜色?

article/2025/10/6 15:51:00

说明

【跟月影学可视化】学习笔记。

RGB 和 RGBA 颜色

RGB 和 RGBA 的颜色表示法

#RRGGBB 是 RGB 颜色的十六进制表示法,其中 RR、GG、BB 分别是两位十六进制数字,表示红、绿、蓝三色通道的色阶

色阶可以表示某个通道的强弱。

每个通道一共有 256 阶,取值是 0 到 255。一共能表示 2^24 种不同的颜色。

在这里插入图片描述

#RRGGBBAA 的表示 RGBA 色值,其中增加了一个 Alpha 通道,也就是透明度。(alpha 是一个从 0 到 1 的数)

WebGL 的 shader 默认支持 RGBA。是使用一个四维向量来表示颜色,并采用归一化的浮点数值。就是分量 r、g、b、a 的数值都是 0 到 1 之间的浮点数。

人眼看到的颜色 vs RGB能表示的颜色

灰色区域是人眼所能见到的全部颜色,中间的三角形是 RGB 能表示的所有颜色。

在这里插入图片描述

RGB(A) 颜色表示法的局限性

局限性:当要选择一组颜色给图表使用时,我们并不知道要以什么样的规则来配置颜色,才能让不同数据对应的图形之间的对比尽可能鲜明。

举个例子:在画布上显示 3 组颜色不同的圆,每组各 5 个,用来表示重要程度不同的信息。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>RGB(A) 颜色表示法的局限性</title><style>canvas {border: 1px dashed salmon;}</style></head><body><canvas width="512" height="512"></canvas><script type="module">import { Vec3 } from "./common/lib/math/vec3.js";const canvas = document.querySelector("canvas");const ctx = canvas.getContext("2d");// 生成随机的三维向量function randomRGB() {return new Vec3(0.5 * Math.random(),0.5 * Math.random(),0.5 * Math.random());}ctx.translate(256, 256);ctx.scale(1, -1);// 转成 RGB 颜色for (let i = 0; i < 3; i++) {const colorVector = randomRGB();for (let j = 0; j < 5; j++) {// 依次用 0.5、0.75、1.0、1.25 和 1.5 的比率乘上随机生成的 RGB 数值,一组圆就能呈现不同的亮度const c = colorVector.clone().scale(0.5 + 0.25 * j);ctx.fillStyle = `rgb(${Math.floor(c[0] * 256)},${Math.floor(c[1] * 256)},${Math.floor(c[2] * 256)})`;ctx.beginPath();ctx.arc((j - 2) * 60, (i - 1) * 60, 20, 0, Math.PI * 2);ctx.fill();}}</script></body>
</html>

总体效果如下:颜色是越左边的越暗,越右边的越亮。

在这里插入图片描述

缺陷:

  1. 无法保证具体的颜色差别大小
  2. 无法控制随机生成的颜色本身的亮度

比如下面这种:后面一行的颜色很暗,区分度太差。

在这里插入图片描述
需要动态构建视觉颜色效果,很少直接选用 RGB(A) 色值,比较常用的就是 HSL 和 HSV 颜色表示形式。

HSL 和 HSV 颜色

各字母的含义:

  • H:色相(Hue),Hue 是角度,取值范围是 0 到 360 度
  • S:饱和度(Saturation),取值范围从 0 到 100%。
  • L:亮度(Lightness),取值范围从 0 到 100%。
  • V:明度(Value),取值范围从 0 到 100%。

HSL和HSV的产生原理

可以把 HSL 和 HSV 颜色理解为,是将 RGB 颜色的立方体从直角坐标系投影到极坐标的圆柱上,所以它的色值和 RGB 色值是一一对应的。
在这里插入图片描述

RGB 和 HSV 的转换代码

vec3 rgb2hsv(vec3 c){vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));float d = q.x - min(q.w, q.y);float e = 1.0e-10;return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}vec3 hsv2rgb(vec3 c){vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0), 6.0)-3.0)-1.0, 0.0, 1.0);rgb = rgb * rgb * (3.0 - 2.0 * rgb);return c.z * mix(vec3(1.0), rgb, c.y);
}

HSL 和 HSV 的颜色表示方法

用 HSL 颜色改写前面绘制三排圆的例子

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>HSL 和 HSV 的颜色表示方法</title><style>canvas {border: 1px dashed salmon;}</style></head><body><canvas width="512" height="512"></canvas><script type="module">import { Vec3 } from "./common/lib/math/vec3.js";const canvas = document.querySelector("canvas");const ctx = canvas.getContext("2d");// 生成随机的三维向量function randomColor() {return new Vec3(0.5 * Math.random(), // 初始色相随机取0~0.5之间的值0.7, // 初始饱和度0.70.45 // 初始亮度0.45);}ctx.translate(256, 256);ctx.scale(1, -1);// 生成随机 hslconst [h, s, l] = randomColor();for (let i = 0; i < 3; i++) {const p = (i * 0.25 + h) % 1;for (let j = 0; j < 5; j++) {const d = j - 2;// 根据 HSL 的规则,亮度越高,颜色越接近白色,只有同时提升饱和度,才能确保圆的颜色不会太浅。ctx.fillStyle = `hsl(${Math.floor(p * 360)}, ${Math.floor((0.15 * d + s) * 100)}%, ${Math.floor((0.12 * d + l) * 100)}%)`;ctx.beginPath();ctx.arc((j - 2) * 60, (i - 1) * 60, 20, 0, Math.PI * 2);ctx.fill();}}</script></body>
</html>

在这里插入图片描述

HSL 和 HSV 的局限性

上面的例子可以看到有的颜色看起来和其他的颜色差距明显,有的颜色还是没那么明显。这是为什么?

例子:绘制两排不同的圆

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>HSL 和 HSV 的局限性</title><style>canvas {border: 1px dashed salmon;}</style></head><body><canvas width="512" height="512"></canvas><script type="module">const canvas = document.querySelector("canvas");const ctx = canvas.getContext("2d");ctx.translate(256, 256);ctx.scale(1, -1);// 第一排每个圆的色相间隔都是 15,饱和度和亮度都是 50%for (let i = 0; i < 20; i++) {ctx.fillStyle = `hsl(${Math.floor(i * 15)}, 50%, 50%)`;ctx.beginPath();ctx.arc((i - 10) * 20, 60, 10, 0, Math.PI * 2);ctx.fill();}// 第二排圆的颜色在色相 60 和 210 附近两两交错,饱和度和亮度都是 50%for (let i = 0; i < 20; i++) {ctx.fillStyle = `hsl(${Math.floor((i % 2 ? 60 : 210) + 3 * i)}, 50%, 50%)`;ctx.beginPath();ctx.arc((i - 10) * 20, -60, 10, 0, Math.PI * 2);ctx.fill();}</script></body>
</html>

效果如下:

  1. 第一排:色相相差都是 15,但是中间几个绿色圆的颜色比较接近。
  2. 第二排:圆的亮度都是 50%,蓝色和紫色的圆不如偏绿偏黄的圆亮。

这是由于人眼对不同频率的光的敏感度不同造成的。

在这里插入图片描述

HSL 依然不是最完美的颜色方法,所以需要建立一套针对人类知觉的标准,它就是 CIE Lab

标准需满足以下 2 个原则

  1. 人眼看到的色差 = 颜色向量间的欧氏距离
  2. 相同的亮度,能让人感觉亮度相同

CIE Lab 和 CIE Lch 颜色

CIELab是CIE的一个颜色系统,表色体系,基于 CIELab 的意思是基于这个颜色系统之上,基本是用于确定某个颜色的数值信息。

Lab 模式是由国际照明委员会(CIE)于 1976 年公布的一种色彩模式。是 CIE 组织确定的一个理论上包括了人眼可见的所有色彩的色彩模式。Lab 模式弥补了 RGB 与 CMYK 两种彩色模式的不足,是 Photoshop 用来从一种色彩模式向另一种色彩模式转换时使用的一种内部色彩模式。Lab模式也是由三个通道组成,第一个通道是明度,即 L。a 通道的颜色是从红色到深绿;b 通道则是从蓝色到黄色。 在表达色彩范围上,最全的是 Lab 模式,其次是 RGB 模式,最窄的是 CMYK 模式。也就是说 Lab 模式所定义的色彩最多,且与光线及设备无关,并且处理速度与 RGB 模式同样快,比 CMYK 模式快数倍。

CSS Color Module Level 4规范给出了 Lab 颜色值的定义

lab() = lab( [<percentage> | <number> | none][ <percentage> | <number> | none][ <percentage> | <number> | none][ / [<alpha-value> | none] ]? )

例子:

在这里插入图片描述

一些 JavaScript 库也可以直接处理 Lab 颜色空间,比如:【d3-color】:https://github.com/d3/d3-color

例子:使用 d3.lab 来定义 Lab 色彩。

<script src="https://d3js.org/d3-color.v1.min.js"></script>

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>CIE Lab 和 CIE Lch 颜色</title><script src="https://d3js.org/d3-color.v1.min.js"></script><style>canvas {border: 1px dashed salmon;}</style></head><body><canvas width="512" height="512"></canvas><script type="module">const canvas = document.querySelector("canvas");const ctx = canvas.getContext("2d");ctx.translate(256, 256);ctx.scale(1, -1);// 使用 d3.lab().rgb() 获取到rgb的值for (let i = 0; i < 20; i++) {const c = d3.lab(30, i * 15 - 150, i * 15 - 150).rgb();ctx.fillStyle = `rgb(${c.r}, ${c.g}, ${c.b})`;ctx.beginPath();ctx.arc((i - 10) * 20, 60, 10, 0, Math.PI * 2);ctx.fill();}for (let i = 0; i < 20; i++) {const c = d3.lab(i * 5, 80, 80).rgb();ctx.fillStyle = `rgb(${c.r}, ${c.g}, ${c.b})`;ctx.beginPath();ctx.arc((i - 10) * 20, -60, 10, 0, Math.PI * 2);ctx.fill();}</script></body>
</html>

在这里插入图片描述

可以看到以 CIELab 方式呈现的色彩变化中,设置的数值和人眼感知的一致性比较强。

Cubehelix 色盘

Cubehelix “立方螺旋” 算法会生成给定数量的颜色列表。此颜色表拥有线性增加的强度曲线,同时也会在色轮周围旋转产生各种颜色的渐变。

优点:生成的色表在转换为灰度或替换色调后,其强度的变化不会有影响。因为红绿蓝三色本身的感知亮度是不一样的,如果更改了基础色,则还需要再修一遍整体平衡。这个算法能够在不破坏亮度平衡的情况下替换起始颜色。

Cubehelix 渐变

在这里插入图片描述

Cubehelix 渐变加亮度渐变

在这里插入图片描述

推荐阅读:Cubehelix颜色表算法

Cubehelix色盘的原理

Cubehelix 色盘(立方螺旋色盘)的原理就是在 RGB 的立方中构建一段螺旋线,让色相随着亮度增加螺旋变换。可以查看Dave Green’s ‘cubehelix’ colour scheme

在这里插入图片描述

Cubehelix 的应用

例子:使用 cubehelix:https://github.com/mperdikeas/js-cubehelix#readme 模块写一个颜色随着长度变化的柱状图

cubehelix:A JavaScript library implementing Dave Green’s `cubehelix’ algorithm to generate a family of mapping functions. I.e., a family of functions that map values in the [0, 1] domain to points in the RGB colorspace employing a wide variety of color and ensuring that the perceived brightness monotonically increases.


可以自己将 cubehelix 的代码弄一份到自己的 lib 库里,方便使用
在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Cubehelix 色盘</title><style>canvas {border: 1px dashed salmon;background: #000;}</style></head><body><canvas width="512" height="512"></canvas><script type="module">import { cubehelix } from "./common/lib/color/cubehelix/index.js";const canvas = document.querySelector("canvas");const ctx = canvas.getContext("2d");ctx.translate(0, 256);ctx.scale(1, -1);// 构造cubehelix色盘颜色映射函数,cubehelix 函数是一个高阶函数,它的返回值是一个色盘映射函数。const color = cubehelix();const T = 2000;function update(t) {// 用正弦函数来模拟数据的周期性变化const p = 0.5 + 0.5 * Math.sin(t / T);ctx.clearRect(0, -256, 512, 512);// 获取当前的颜色值,p 范围是 0 到 1,当它从小到大依次改变的时候,不仅颜色会依次改变,亮度也会依次增强。const { r, g, b } = color(p);ctx.fillStyle = `rgb(${255 * r},${255 * g},${255 * b})`;ctx.beginPath();ctx.rect(20, -20, 480 * p, 40);ctx.fill();window.ctx = ctx;requestAnimationFrame(update);}update(0);</script></body>
</html>

效果如下:
在这里插入图片描述

推荐阅读资料

  • CSS Color Module Level 4
  • 三原色光模式(RGB color model)
  • CIELab表色系
  • 色彩空间中的 HSL、HSV、HSB 有什么区别?
  • JS实现RGB,HSL,HSB相互转换
  • Cubehelix颜色表算法
  • Dave Green’s ‘cubehelix’ colour scheme

http://chatgpt.dhexx.cn/article/Xs1AWXGF.shtml

相关文章

CIELab图像的通道分解与合成

import cv2 import numpy as np lotus cv2.imread(lotus.jpg) showImgByPlot(lotus,10,6) lotus_lab cv2.cvtColor(lotus, cv2.COLOR_BGR2LAB) l, a, b cv2.split(lotus_lab) #! featureMat cv2.merge([l, a, b]) #! merge失败 featureMat np.dstack((l, a, b)).astype(np…

CIELab和LCH的色彩空间图

资料来源&#xff1a;http://www.18show.cn/share_news/599547.html CIE Lab&#xff1a; LAB色空间是基于一种颜色不能同时既是蓝又是黄这个理论而建立。所以CIE Lab&#xff0c;单一数值可用于描述红/绿色及黄/蓝色特徽。当一种颜色用CIE L*a*b*时&#xff0c;L* 表示明度值…

CIELAB色差计算

CIE色差计算就是在之前Lab颜色空间进行的。色差一般指的是由于位置不同或者放大率不同所造成的颜色差异。而在图像处理领域&#xff0c;尤其是针对色彩的处理中&#xff0c;很重要的一点就是消除色差。那么接下来我们就讨论CIE色差公式的改进过程&#xff0c;每次改进的意义&am…

彩色空间-CIELAB和LAB的关系

CIELAB和LAB的关系 CIELab是CIE的一个颜色系统&#xff0c;表色体系&#xff0c;基于CIELab的意思是基于这个颜色系统之上&#xff0c;基本是用于确定某个颜色的数值信息。 Hunter 1948 L, a, b色彩空间的坐标是L, a和b。但是&#xff0c;Lab经常用做CIE 1976 (L*, a*, b*)色彩…

MATLAB GUI设计如何弹出新界面?

本意是想要设计一个图像处理系统&#xff0c;在该系统中点击按钮可以跳转到另一个GUI界面&#xff0c;在该界面设计后将所设置参数引回到原有的GUI界面&#xff0c;并在该界面进行显示处理好的图像。各位如果有好的结果的话麻烦江湖救急&#xff01;或者可以加我QQ&#xff1a;…

Matlab GUI编程

在matlab命令行上输入guide或者从菜单中选择New GUI可以创建matlab的图形用户界面。 创建空白的GUI界面&#xff08;默认&#xff09;&#xff0c;其界面如下&#xff1a; 未命名情况下matlab将会在当前工作目录下&#xff0c;同时将会生成untitled.fig和untitled.m文件。其中…

学习matlab(十四)——GUI

1.编程方法 在本章首先详细的介绍了MATLAB的图形句柄,通过对图形对象的属性进行设置,可以是实现图形的底层控制和设置。然后介绍了用户接口对象,用于建立各种按钮、菜单和工具条等。最后介绍了常用的对话框,这些对话框是GUI编程常用的基本元件。 在MATLAB中,各种句柄图形对象…

matlab制作GUI界面(1)

matlab制作GUI界面 概述创建GUI界面界面设置静态文本最后 概述 图形用户界面&#xff08;Graphical User Interface&#xff0c;简称 GUI&#xff0c;又称图形用户接口&#xff09;是指采用图形方式显示的计算机操作用户界面。 图形用户界面是一种人与计算机通信的界面显示格式…

matlab GUI编程入门

转载请注明来自&#xff1a;黄朝辉的博客 1.前言 这里我们来实现一个加法器&#xff0c;功能比较简单&#xff0c;主要用于了解matlab中的代码是如何与控件进行交互。 2.绘制界面 在命令行窗口中输入&#xff1a; >> guide 直接“确定”即可。 将需要的控件从左边托…

MATLAB GUI学习———简易计算器

暑假快要过完了才想起来学习&#xff0c;最近刚好接触到MATLAB中的GUI&#xff0c;觉得还挺有意思的&#xff0c;今天就用GUI产生了一个简易的计算器&#xff0c;实现了基本的加、减、乘、除运算。由于是新手小白&#xff0c;所以刚刚开始的时候&#xff0c;我是在网上去找了一…

MATLAB的GUI设计——计算器

出于兴趣爱好自学了一段时间的MATLAB&#xff0c;然后学习自制了一个属于自己的一个计算器&#xff0c;现在将我的第一个GUI分享给大家。&#xff08;MATLAB版本为R2019a&#xff09; 一、准备工作 ①首先在MATLAB中的命令行窗口输入guide&#xff0c;之后会出现如下界面&…

MATLAB 编写一个简单的GUI

MATLAB作为一个使用方便、容易上手的工具&#xff0c;也经常用来进行相关项目的结果展示 本次博客讲解一下如何创建一个简单的GUI 首先&#xff0c;启动matlab&#xff0c;在命令窗口输入 guide 在弹出的窗口选择 Blank GUI 在随后弹出的窗口中&#xff0c;左侧是工具栏&#…

Matlab GUI组件详解

1、触控按钮&#xff08;Push Button&#xff09; 在Push Button 上双击调用属性查看器可以查看和设置Push Button 的所有属性Push Button 对象的常用属性见下表。 2、静态文本&#xff08;Static Text&#xff09; Static Text 通常用于显示其他对象的数值状态等Static Text…

MATLAB创建GUI

1.matlab命令行输入guide&#xff0c;新建GUI图形界面&#xff0c;或者新建–应用程序–GUIDE&#xff0c;选择Blank GUI&#xff0c;选择路径。 2.在图形界面点击左侧控件和组件构建图形界面。 主要用到的控件和组件&#xff1a; &#xff08;1&#xff09;按钮&#xff08;选…

MATLAB GUI实现计算器(设计)

文章目录 1.先打开matlab新建GUI文件2.选择路径&#xff08;左边是默认的不用改&#xff09;3.此时界面会弹出一个小框4.建立计算器界面&#xff08;贴上我设计的界面&#xff0c;不许嘲笑我的设计&#xff09;5.细致讲解一下&#xff0c;这里的按键和显示框的是怎么实现的6.把…

MATLAB GUI笔记(一):按钮的使用

笔记一是简单地介绍按钮的使用&#xff0c;通过点击按钮实现传递字符串的功能来简单了解按钮的用法。 目录 笔记一是简单地介绍按钮的使用&#xff0c;通过点击按钮实现传递字符串的功能来简单了解按钮的用法。1. 打开GUI界面2. 选择Blank GUI3. 将按钮拖动出来4. 选择可编辑文…

带你从零开始,快速学会 Matlab GUI

本文来自作者 木木小迷哥 在 GitChat 上分享「Matlab GUI 零基础学员快速入门」&#xff0c;「阅读原文」查看交流实录 「文末高能」 编辑 | 洛肯 Matlab广泛地应用于数学分析、计算、自动控制、系统仿真、数字信号处理、图像处理、数理统计、人工智能、通信工程和金融系统等领…

如何用Matlab设计GUI?

如何用matlab设计gui&#xff1f; | TinTin 什么是GUI&#xff1f;matlab编程可以设计GUI吗&#xff1f; GUI定义:GUI指的是图形用户界面&#xff08;Graphical User Interface&#xff0c;GUI&#xff09;&#xff0c;也称之为图形用户接口&#xff0c;GUI是用图形化方式显示…

Matlab GUI界面使用方法(一):打开GUIGUI常用控件(最基础)

GUI界面能够为我们的matlab代码提供一些有好的交互界面&#xff0c;下面是matlab中gui界面的一些使用方法&#xff08;因为我在使用gui时&#xff0c;常常因为找不到一些控件的使用方法或某些功能的实现方法&#xff0c;所以在此为大家提供一些我遇到过的问题的解决方法&#x…

【MATLAB学习笔记——GUI】

Matlab中GUI 学习笔记 虽然打开matlab后提示说GUI后续版本会取消&#xff08;以后的版本中将会删除 GUIDE。请改用 APPDESIGNER。 &#xff09;&#xff0c;但是老师布置了matlab GUI实验&#xff0c;所以说还得学习学习&#xff0c;所以记录学习过程&#xff0c;学习笔记。 …