1. 项目概述:从“我的第一个矩阵”到色彩空间的探索
如果你刚开始接触数字图像处理或者计算机图形学,看到“矩阵”、“RGB”、“YIQ”这些词可能会觉得既熟悉又陌生。熟悉是因为它们无处不在,陌生是因为它们背后的原理和相互转换的关系,常常被包裹在一层神秘的面纱里。这个项目——“My First Matrix, RGB, YIQ, and Color Cubes”——本质上是一个绝佳的入门实践。它不是一个复杂的应用程序,而是一个 系统性的认知实验 ,旨在通过动手操作,帮你亲手揭开色彩表示与变换的数学面纱。
简单来说,这个项目就是让你用代码(通常是MATLAB或Python)去构建和可视化色彩空间。你会从最基础的 颜色立方体 开始,直观理解RGB空间;然后,你会学习如何用 矩阵 这个强大的数学工具,将颜色从RGB空间转换到其他空间(比如YIQ);最后,你会亲眼看到这些变换如何改变了颜色在三维空间中的分布。这不仅仅是学习几个函数调用,而是理解“为什么数字图像中的颜色可以这样被计算和操纵”。无论你是学生、刚入行的开发者,还是对图形学原理感兴趣的爱好者,通过这个项目,你都能获得对像素背后世界的坚实直觉。接下来,我们就一步步拆解,看看如何亲手实现这个“第一次”。
2. 核心概念拆解:矩阵、色彩空间与立方体
在动手写代码之前,我们必须把几个核心概念及其之间的关系彻底理清。很多人卡在第一步,就是因为对这些基础概念的混合感到困惑。
2.1 矩阵:不仅仅是数字的表格
在这里,矩阵扮演着双重角色。首先,它是 数据的容器 。一张RGB图像,在计算机内存中,本质上就是三个巨大的矩阵(或一个三维矩阵),分别存储着每个像素点的红、绿、蓝分量值。例如,一个100x100像素的图片,其R通道就是一个100行、100列的矩阵,每个元素是一个介于0到255(8位)或0到1(归一化)的数值。
其次,也是本项目更关键的一点,矩阵是 线性变换的算子 。色彩空间转换,如RGB到YIQ,在数学上是一个线性变换。这意味着,目标空间的每一个颜色分量(Y, I, Q),都是源空间颜色分量(R, G, B)的线性组合。这个组合关系,恰恰可以用一个矩阵乘法完美地表达出来。
例如,RGB到YIQ的标准转换矩阵(基于NTSC标准)是:
[ Y ] [ 0.299 0.587 0.114 ] [ R ]
[ I ] = [ 0.596 -0.275 -0.321 ] * [ G ]
[ Q ] [ 0.212 -0.523 0.311 ] [ B ]
这个3x3的矩阵就是变换的核心。你输入一个RGB列向量
[R; G; B]
,左乘这个矩阵,就得到了对应的YIQ列向量
[Y; I; Q]
。理解这一点,你就掌握了色彩空间转换的钥匙。
2.2 RGB色彩空间:加色模型的基石
RGB是我们最熟悉的色彩模型,基于 加色法 。想象你有三盏灯:红灯、绿灯、蓝灯。当它们全部关闭时,是黑色(0,0,0);全部以最亮打开时,是白色(255,255,255或1,1,1)。通过调节三盏灯的亮度比例,你可以混合出肉眼可见的绝大部分颜色。
在三维坐标系中,我们可以把RGB空间表示为一个立方体。三个坐标轴分别代表R、G、B分量。这个立方体的原点(0,0,0)是黑色,对角顶点(1,1,1)是白色。所有可能的颜色都“住”在这个单位立方体内。灰度色阶就在从黑到白的对角线上。可视化这个立方体,是理解颜色离散性和连续性的第一步。
2.3 YIQ色彩空间:为兼容性而生的智慧
YIQ色彩空间可能不如RGB或HSV那么常用,但它蕴含着重要的工程智慧。它主要用于旧式的NTSC彩色电视广播系统。其设计目标是将彩色信息(Chrominance)与亮度信息(Luminance)分离,并让彩色信息占据更少的带宽。
- Y分量(亮度) :包含了图像中所有的亮度信息,也就是黑白电视信号需要的内容。这样,黑白电视机可以只接收Y信号来显示画面。
- I和Q分量(色度) :携带颜色信息。I代表从橙色到青色的色调范围,Q代表从紫色到黄绿色的色调范围。人眼对I代表的色调变化更敏感,对Q代表的色调变化较不敏感。因此,在信号传输时,可以对Q分量进行更强的压缩(即用更少的带宽),从而节省总带宽。
从RGB转换到YIQ,正是利用了矩阵变换,将颜色数据重新打包,以适应特定的传输或处理需求。理解YIQ,能让你明白色彩空间设计是如何服务于具体应用场景(如压缩、兼容)的。
2.4 颜色立方体:三维可视化的威力
颜色立方体是本项目的 可视化核心输出 。它的意义在于将抽象的数字(矩阵中的数值)转化为直观的、可旋转审视的三维图形。
-
RGB立方体
:直接绘制。每个点
(r,g,b)对应一个颜色,点的位置就是其坐标,点的颜色就是其(r,g,b)值本身。这个立方体是规整的。 -
YIQ立方体
:需要先进行变换。你将RGB立方体中的所有点(比如均匀采样的一系列点)通过上述转换矩阵计算出对应的
(y,i,q)坐标,然后用这些新坐标绘图。这时,点的颜色仍然用原始的RGB值来渲染(以便观察变换前后颜色的对应关系),但点的位置已经变成了YIQ空间下的坐标。你会看到一个被“拉斜”或“旋转”了的立方体,这直观地展示了线性变换对颜色分布的几何影响。
通过对比变换前后的立方体,你能深刻体会到:色彩空间转换,本质上是对颜色数据集进行了一次“视角旋转”或“坐标系重塑”,颜色本身的内在关系没变,但我们观察和处理的“坐标架”变了。
3. 项目实战:使用MATLAB构建与可视化
理论清晰后,我们进入实战环节。我将以MATLAB为例,因为它内置了强大的矩阵运算和三维绘图功能,非常适合做这种原理性演示。整个过程分为四个清晰的步骤。
3.1 第一步:构建RGB颜色立方体的点集
我们的目标是生成代表RGB立方体内大量颜色的点。一个简单有效的方法是使用
meshgrid
函数。
% 步骤1:生成RGB颜色立方体的点集
% 设定采样分辨率,例如每维度采样11个点(0:0.1:1)
step = 0.1;
[r, g, b] = meshgrid(0:step:1, 0:step:1, 0:step:1);
% 将三维网格数据重塑为Nx3的矩阵,每一行是一个(R,G,B)颜色点
rgb_points = [r(:), g(:), b(:)];
num_points = size(rgb_points, 1);
fprintf('生成了 %d 个颜色采样点。\n', num_points);
这段代码生成了一个在0到1之间均匀采样的点阵。
step=0.1
会在每个维度上采样11个点(0, 0.1, 0.2, ..., 1.0),总共生成11
11
11=1331个点。你可以调整
step
来改变采样密度,更密的采样会让后续的立方体看起来更实心,但计算量和绘图负担也会增加。对于初次演示,0.1或0.2的步长是不错的选择。
注意 :这里我们将颜色值归一化到[0,1]区间,而不是[0,255]。这在图像处理计算中很常见,可以避免整数运算,方便矩阵乘法。绘图时,MATLAB的
scatter3函数能自动识别[0,1]范围的颜色值。
3.2 第二步:定义RGB到YIQ的转换矩阵并应用
接下来,我们引入那个关键的转换矩阵,并对所有采样点进行变换。
% 步骤2:定义RGB到YIQ的转换矩阵(NTSC标准)
% 这个矩阵是固定的,来源于色彩科学标准。
T_rgb2yiq = [0.299, 0.587, 0.114; % Y行
0.596, -0.275, -0.321; % I行
0.212, -0.523, 0.311]; % Q行
% 应用变换:对每一行(一个颜色点)进行矩阵乘法
% 最直接的方式是转置后相乘,再转置回来。更高效的方式是直接右乘矩阵的转置。
yiq_points = rgb_points * T_rgb2yiq'; % 注意是乘以矩阵的转置
% 解释:如果 rgb_points 是 Nx3, T_rgb2yiq 是 3x3,
% 那么 rgb_points * T_rgb2yiq' 实现了对每个点 row_i 计算 row_i * T_rgb2yiq',
% 等价于 (T_rgb2yiq * row_i')'。
这里有一个关键的编程技巧:我们利用矩阵乘法的性质,避免了写循环。
rgb_points
是
N x 3
矩阵,
T_rgb2yiq'
是
3 x 3
矩阵,结果
yiq_points
就是
N x 3
的YIQ点集。这种向量化操作在MATLAB中效率极高。
实操心得 :转换矩阵的数值是标准化的,不要随意修改,除非你在实验特定的色彩空间。不同的标准(如PAL制式用的YUV)矩阵系数不同。确保你使用的矩阵与你想要模拟的色彩空间一致。
3.3 第三步:三维可视化RGB与YIQ颜色立方体
现在是见证奇迹的时刻。我们将并排绘制两个三维散点图。
% 步骤3:创建并排对比的可视化图形
figure('Position', [100, 100, 1200, 500]); % 设置一个宽幅窗口
% 子图1:RGB颜色立方体
subplot(1, 2, 1);
scatter3(rgb_points(:,1), rgb_points(:,2), rgb_points(:,3), ...
40, rgb_points, 'filled'); % 点大小40,颜色用rgb_points值
xlabel('Red (R)'); ylabel('Green (G)'); zlabel('Blue (B)');
title('RGB Color Cube');
axis equal; grid on; view(3); % 等轴、网格、三维视角
% 设置坐标轴范围,确保立方体显示完整
xlim([0, 1]); ylim([0, 1]); zlim([0, 1]);
% 子图2:YIQ颜色立方体(点的颜色仍用原始RGB值显示)
subplot(1, 2, 2);
scatter3(yiq_points(:,1), yiq_points(:,2), yiq_points(:,3), ...
40, rgb_points, 'filled'); % 关键:颜色信息仍用rgb_points
xlabel('Luma (Y)'); ylabel('In-phase (I)'); zlabel('Quadrature (Q)');
title('YIQ Color Cube (Colors from original RGB)');
axis equal; grid on; view(3);
% 注意:YIQ坐标的范围可能与RGB不同,我们让坐标轴自动调整以显示全部点
% 但为了对比,可以手动设置一个合理的范围,例如Y在[0,1],I和Q在[-0.6,0.6]附近
% xlim([0, 1]); ylim([-0.6, 0.6]); zlim([-0.6, 0.6]);
sgtitle('My First Matrix, RGB, YIQ, and Color Cubes'); % 总标题
这段代码的精华在于
scatter3
函数的调用。前三个参数是点的XYZ坐标,第四个参数是点的大小,
第五个参数
rgb_points
决定了每个点的颜色
。这意味着:
-
在RGB立方体图中,点的位置
(R,G,B)和颜色(R,G,B)是一致的。 -
在YIQ立方体图中,点的位置变成了
(Y,I,Q),但颜色仍然使用其原始的(R,G,B)值来渲染。
这种可视化方式极其强大!它让你一眼就能看出:同一个颜色(由点的颜色表示),在两个不同的色彩空间坐标系(由点的位置表示)下,其“坐标”发生了怎样的变化。你会看到YIQ立方体不再是一个规整的立方体,而是被“剪切”和“旋转”成了一个平行六面体,其中亮度Y轴大致对应原RGB空间的对角线(黑白轴)。
3.4 第四步:交互式探索与效果增强
基础的绘图完成了,但我们可以让它更具交互性和启发性。
% 步骤4:添加交互和注释
% 4.1 旋转以观察立方体结构
disp('图形已生成。请手动旋转三维图形(点击旋转图标或直接拖拽)以观察立方体结构。');
disp('重点观察YIQ立方体如何从RGB立方体变换而来。');
% 4.2 标记特殊点(可选,增强理解)
% 例如,标记纯黑、纯白、纯红、纯绿、纯蓝在YIQ空间中的位置
hold on; % 在YIQ子图上继续绘制
special_rgb = [0,0,0; 1,1,1; 1,0,0; 0,1,0; 0,0,1];
special_yiq = special_rgb * T_rgb2yiq';
scatter3(special_yiq(:,1), special_yiq(:,2), special_yiq(:,3), ...
120, 'k', 'LineWidth', 2); % 用大黑圈标记
legend('All Colors', 'Special Colors (B/W/R/G/B)', 'Location', 'best');
% 4.3 绘制从原点到特殊点的向量(可选)
% 这可以显示变换矩阵对基向量的作用
origin = [0,0,0];
for i = 1:size(special_yiq,1)
plot3([origin(1), special_yiq(i,1)], ...
[origin(2), special_yiq(i,2)], ...
[origin(3), special_yiq(i,3)], 'k--', 'LineWidth', 1);
end
hold off;
% 4.4 保存图形
saveas(gcf, 'RGB_YIQ_Color_Cubes.png');
disp('图形已保存为 RGB_YIQ_Color_Cubes.png');
通过标记特殊颜色点并绘制向量,你可以更清晰地看到变换的几何意义。例如,纯白色(1,1,1)在RGB空间位于(1,1,1),在YIQ空间则位于约(1.0, 0.0, 0.0)附近,这说明白色几乎全部由亮度Y分量承载,色度I和Q分量很小。
4. 深度解析:矩阵变换的几何意义与色彩分离
完成了可视化,我们来回过头深入分析一下看到的图形,这比单纯跑通代码更重要。
4.1 YIQ变换矩阵的列向量意义
一个3x3矩阵的每一列,都有明确的几何意义:它代表了原始空间的标准基向量(即
[1,0,0]
,
[0,1,0]
,
[0,0,1]
,对应纯红、纯绿、纯蓝)经过变换后,在新空间(YIQ空间)中的坐标。
让我们计算一下:
-
纯红 [1,0,0] 变换后
:
T * [1;0;0] = [0.299; 0.596; 0.212]。这意味着纯红在YIQ空间中位于(0.299, 0.596, 0.212)。 -
纯绿 [0,1,0] 变换后
:
T * [0;1;0] = [0.587; -0.275; -0.523]。 -
纯蓝 [0,0,1] 变换后
:
T * [0;0;1] = [0.114; -0.321; 0.311]。
在你的YIQ立方体图中,如果你标记了这三个点,你会发现它们构成了那个“歪斜”的平行六面体的三个从原点出发的边。这个平行六面体就是原始RGB单位立方体经过矩阵
T
线性变换后的结果。所有在RGB立方体内的颜色,都被映射到了这个YIQ平行六面体内。
4.2 Y分量的物理意义:灰度图像的产生
Y分量被设计为R、G、B的加权和,权重系数(0.299, 0.587, 0.114)来源于人眼对不同波长光线的敏感度(光度函数)。绿色光对人眼亮度感知贡献最大,红色次之,蓝色最小。因此, Y分量本质上就是一张图像的灰度图 。
你可以轻松验证这一点:
% 读取一张彩色图片
img_rgb = imread('peppers.png'); % 使用MATLAB示例图片或你自己的图片
img_rgb_double = im2double(img_rgb); % 转换为双精度[0,1]
% 提取RGB三个通道
R = img_rgb_double(:,:,1);
G = img_rgb_double(:,:,2);
B = img_rgb_double(:,:,3);
% 按照公式计算Y分量
Y_calculated = 0.299 * R + 0.587 * G + 0.114 * B;
% 使用内置函数进行RGB到YIQ转换(验证)
% 注意:MATLAB的 `rgb2ntsc` 函数转换到的是NTSC YIQ空间
img_yiq = rgb2ntsc(img_rgb_double);
Y_from_func = img_yiq(:,:,1);
% 比较两者(理论上应该几乎完全相同)
difference = abs(Y_calculated - Y_from_func);
max_diff = max(difference(:));
fprintf('手动计算与函数计算的Y分量最大差异为:%e\n', max_diff);
% 并排显示原图、手动计算灰度图、函数提取灰度图
figure;
subplot(1,3,1); imshow(img_rgb); title('Original RGB Image');
subplot(1,3,2); imshow(Y_calculated); title('Grayscale (Manual Y)');
subplot(1,3,3); imshow(Y_from_func); title('Grayscale (from rgb2ntsc)');
这个实验让你直观地理解,为什么将彩色图像转换为灰度图不是简单地对R、G、B取平均值,而是要进行加权平均。这个加权平均,就是变换矩阵第一行所做的事情。
4.3 I与Q分量的设计:带宽压缩的奥秘
I和Q分量携带色度信息。观察变换矩阵的第二、三行,你会发现它们包含正负系数,这意味着I和Q是R、G、B的某种差分组合。这种设计使得I和Q在典型的自然图像中,数值的动态范围(方差)比R、G、B本身要小,且平均值在0附近。
更重要的是, 人眼对I分量(橙-青色调)携带的色度细节更敏感,对Q分量(紫-黄绿色调)的细节较不敏感 。在早期的NTSC电视系统中,工程师利用这一特性,对Q分量信号使用了比I分量更宽的滤波(即更低的带宽)进行传输,从而在保证主观视觉质量不明显下降的前提下,大大压缩了彩色信号所需的带宽。这就是色彩空间设计如何直接影响工程实践的经典案例。
在你的YIQ立方体图中,你可以观察到大部分颜色点聚集在Y轴附近,I和Q的绝对值较小,这印证了色度信息相对于亮度信息其“能量”较低且集中在0附近的特点。
5. 项目扩展与进阶思考
完成基础版本后,你可以从这个项目出发,进行多种有意义的扩展,深化理解。
5.1 扩展一:探索其他色彩空间
RGB到YIQ只是线性变换的一个例子。你可以用同样的框架探索其他空间。
- RGB to HSV/HSL :这些是圆柱坐标或双圆锥坐标表示的颜色空间,变换是非线性的。你需要实现算法(如max/min计算、分段函数),而不是简单的矩阵乘法。可视化时,HSV空间更像一个圆柱体或圆锥体。
-
RGB to YCbCr
:这是JPEG图像压缩和视频编码(如MPEG, H.264)中广泛使用的空间。它也是线性变换,但矩阵系数与YIQ不同。例如,常用的BT.601标准:
注意Cb和Cr有偏移量(+0.5),通常被缩放到[0,1]或[16, 240](YCbCr视频范围)。可视化YCbCr立方体,你会看到颜色点被“平移”并“缩放”到了一个新的区域。Y = 0.299 * R + 0.587 * G + 0.114 * B Cb = -0.168736 * R - 0.331264 * G + 0.5 * B + 0.5 Cr = 0.5 * R - 0.418688 * G - 0.081312 * B + 0.5
实现并对比YIQ和YCbCr的立方体,能让你理解不同标准如何为了不同的应用目标(广播 vs. 数字压缩)而优化色彩表示。
5.2 扩展二:实现逆变换与图像处理
一个完整的色彩空间转换应包括正变换和逆变换。逆变换矩阵是正变换矩阵的逆矩阵。
% 计算YIQ到RGB的逆变换矩阵
T_yiq2rgb = inv(T_rgb2yiq); % 求逆矩阵
% 验证:对一个随机颜色进行往返变换
test_color = rand(1, 3);
yiq_color = test_color * T_rgb2yiq';
reconstructed_color = yiq_color * T_yiq2rgb';
error = norm(test_color - reconstructed_color);
fprintf('往返变换误差(范数): %e\n', error);
% 理论上误差应极小(在浮点精度内)
基于逆变换,你可以实现简单的图像处理滤镜。例如,在YIQ空间降低I和Q分量的幅度(即降低饱和度),然后再转换回RGB空间,就能得到一张低饱和度的图片。
% 简易饱和度调整滤镜
img_rgb = im2double(imread('peppers.png'));
img_yiq = rgb2ntsc(img_rgb); % 转换到YIQ
saturation_factor = 0.5; % 饱和度因子,1为原图,0为灰度
img_yiq_adjusted = img_yiq;
img_yiq_adjusted(:,:,2) = img_yiq_adjusted(:,:,2) * saturation_factor; % 调整I
img_yiq_adjusted(:,:,3) = img_yiq_adjusted(:,:,3) * saturation_factor; % 调整Q
img_rgb_adjusted = ntsc2rgb(img_yiq_adjusted); % 转换回RGB
figure;
subplot(1,2,1); imshow(img_rgb); title('Original');
subplot(1,2,2); imshow(img_rgb_adjusted); title(['Saturation x', num2str(saturation_factor)]);
这个练习将抽象的矩阵变换与直观的图像效果直接联系起来,极大地增强了学习的成就感。
5.3 扩展三:量化与颜色减少
在RGB立方体中,均匀采样是一种方式。但你也可以尝试非均匀采样,例如只在色域边界或感兴趣的区域密集采样。更高级的练习是 颜色量化 :将一张真彩色图片(数百万颜色)减少到有限的调色板(如256色)。一种经典算法(中位切分法)就是在RGB或YIQ颜色立方体中递归地进行空间划分。你可以尝试可视化量化前后的颜色在立方体中的分布,理解量化是如何通过用少数代表色来近似整个颜色集的。
6. 常见问题与调试技巧实录
在实际操作中,你可能会遇到一些典型问题。这里记录了我踩过的坑和解决方法。
6.1 可视化问题:图形显示异常或空白
-
问题描述
:运行
scatter3后图形窗口空白,或点显示得非常奇怪(比如全黑)。 -
排查步骤
:
-
检查数据范围
:首先打印
rgb_points和yiq_points的最小最大值(min(rgb_points),max(rgb_points))。确保RGB点在[0,1]内。YIQ点的范围可能超出[0,1],这是正常的,但如果你用RGB值来着色,而坐标轴范围设置不当,点可能会被画到窗口外。尝试不设置xlim/ylim/zlim,让MATLAB自动调整范围。 -
检查
scatter3颜色参数 :第五个参数(颜色)必须是一个Nx3的矩阵,且值在[0,1]之间。确认你传递的是rgb_points,而不是yiq_points。如果你错误地传递了yiq_points,由于YIQ值可能为负或大于1,MATLAB会将其截断,导致着色异常。 -
图形渲染问题
:对于大量点(如上万个),
scatter3可能会变慢或卡顿。可以尝试减少采样步长(如step=0.2),或使用drawnow命令强制刷新图形。如果收到OpenGL渲染警告,可以尝试在绘图前使用opengl software命令切换到软件渲染,虽然画质可能下降,但兼容性更好。
-
检查数据范围
:首先打印
6.2 矩阵乘法维度错误
-
问题描述
:执行
yiq_points = rgb_points * T_rgb2yiq'时报错“矩阵维度不一致”。 -
原因与解决
:确保
rgb_points是Nx3矩阵,T_rgb2yiq是3x3矩阵。T_rgb2yiq'是3x3。所以乘法是(Nx3) * (3x3) = (Nx3),维度正确。如果rgb_points是3xN(常见于某些图像数据重塑后),你需要先转置它,或者使用T_rgb2yiq * rgb_points(但此时结果维度是3xN,需要再转置)。始终清楚你的数据布局是“每行一个样本”还是“每列一个样本”。
6.3 色彩空间转换结果与预期不符
-
问题描述
:自己计算的YIQ值与MATLAB内置函数
rgb2ntsc的结果有显著差异。 -
可能原因
:
-
输入范围
:
rgb2ntsc函数期望输入是双精度浮点且范围在[0,1]。如果你传入0-255的uint8数据,它会先被缩放到[0,1],但计算过程可能涉及舍入。始终使用im2double进行转换。 -
矩阵系数
:你使用的转换矩阵可能和MATLAB内部使用的略有不同。MATLAB的
rgb2ntsc遵循一个特定的NTSC标准。你可以通过查看其文档或简单测试来验证。差异通常很小,不影响原理理解。 -
输出范围
:
rgb2ntsc输出的Y分量在[0,1],但I和Q分量通常在[-0.5957, 0.5957]和[-0.5226, 0.5226]左右,并非严格的[-1,1]。这是由矩阵系数决定的。你的计算应该得到相同范围。
-
输入范围
:
6.4 性能优化:处理大图像或高密度采样
当需要处理高分辨率图像或进行非常密集的立方体采样时,循环操作会变得很慢。
-
向量化是王道
:就像我们项目中所做的,始终优先使用矩阵运算代替循环。对于图像,
reshape和permute函数是你的好朋友,可以将3维图像数据(高x宽x3)重塑为2维矩阵((高*宽) x 3),进行批量矩阵乘法,然后再重塑回去。 -
减少采样点
:对于颜色立方体可视化,无需极端密集的采样。
step=0.05(21^3=9261个点)已经能产生非常平滑的视觉效果。step=0.1(1331个点)对于理解原理完全足够。 -
使用
scatter3的替代方案 :对于极大量的点,scatter3可能不是最高效的。可以考虑使用plot3并配合'.'标记,但会失去每个点单独着色的能力。或者,可以只绘制立方体的骨架(12条边),这同样能展示空间的形状。
这个项目就像一把钥匙,打开了理解数字色彩和线性代数在图形学中应用的大门。从构建一个简单的RGB立方体开始,到应用矩阵变换,再到可视化抽象的YIQ空间,每一步都在强化“颜色即向量,变换即矩阵乘法”这一核心概念。我个人的体会是,亲手敲下代码并看到那个歪斜的YIQ立方体在屏幕上旋转的那一刻,远比阅读十页理论公式来得深刻。当你后续学习图像压缩、视频编码甚至机器学习中的特征变换时,这次与矩阵、RGB、YIQ和颜色立方体的“第一次亲密接触”,将会成为你知识体系中一个坚实而直观的基石。
680

被折叠的 条评论
为什么被折叠?



