我们知道计算机处理的是数字,而不是像人类那样直接处理视觉场景。那么,计算机是如何“看”到图像的呢?答案在于数字图像的结构和存储方式。基于图像由像素构成的想法,我们来查看这些像素是如何以数字形式表示的。可以把数字图像想象成一个大的网格,很像电子表格或棋盘。这个网格中的每个方格都对应一个像素。计算机在每个方格中存储一个数值(有时是多个数值),表示该特定像素位置的颜色和强度。灰度图像表示我们从最简单的类型开始:灰度图像,它只包含不同深浅的灰色,从纯黑到纯白。在灰度图像中,每个像素都由一个数字表示。这个数字表示像素的强度或亮度。一种广泛采用的约定是8位灰度。在这种格式中,每个像素的强度存储为一个介于 $0$ 到 $255$ 之间的整数。数值 $0$ 通常表示纯黑,而 $255$ 表示纯白。介于两者之间的数值对应着不同深浅的灰色。因此,整个灰度图像可以被看作是一个二维矩阵(一个网格),它的每个元素都包含这些强度值之一。graph G { layout=neato; node [shape=square, style=filled, fillcolor="#e9ecef", label="", fontname="sans-serif"]; edge [style=invis]; subgraph cluster_grid { label = "灰度图像(像素值)"; fontname="sans-serif"; bgcolor="#f8f9fa"; node [fixedsize=true, width=0.5, height=0.5]; p00 [pos="0,1!", label="10"]; // 深灰色 p01 [pos="0.6,1!", label="50"]; p02 [pos="1.2,1!", label="90"]; p10 [pos="0,0.4!", label="120"]; // 中灰色 p11 [pos="0.6,0.4!", label="150"]; p12 [pos="1.2,0.4!", label="180"]; p20 [pos="0,-0.2!", label="200"]; // 浅灰色 p21 [pos="0.6,-0.2!", label="220"]; p22 [pos="1.2,-0.2!", label="255"]; // 白色 // 网格结构线(可选,保持简单) p00 -- p01 -- p02; p10 -- p11 -- p12; p20 -- p21 -- p22; p00 -- p10 -- p20; p01 -- p11 -- p21; p02 -- p12 -- p22; } }灰度图像的一个小片段,表示为强度值网格(例如,0=黑色,255=白色)。彩色图像表示 (RGB)彩色图像每个像素需要更多的信息。表示颜色最常见的方式是RGB模型,它代表红、绿、蓝。其理念是,通过混合这三种光的原色以不同比例,可以近似表示任何颜色。对于RGB图像,每个像素位置存储三个数值:红色分量的强度。绿色分量的强度。蓝色分量的强度。这三个值通常被称为颜色通道。与灰度类似,每个通道通常使用8位表示,这意味着红、绿、蓝的强度范围从 $0$ (该颜色无强度)到 $255$ (该颜色最大强度)。单个像素的颜色由这三个值的组合决定。例如:$(255, 0, 0)$ 表示纯亮红色。$(0, 255, 0)$ 表示纯亮绿色。$(0, 0, 255)$ 表示纯亮蓝色。$(0, 0, 0)$ 表示黑色(无光)。$(255, 255, 255)$ 表示白色(所有三种颜色最大强度)。$(128, 128, 128)$ 表示中等灰色。$(255, 255, 0)$ 表示黄色(红色和绿色混合)。digraph G { rankdir=LR; node [shape=square, style=filled, fontname="sans-serif"]; edge [fontname="sans-serif"]; splines=false; subgraph cluster_pixel { label="彩色像素"; fontname="sans-serif"; bgcolor="#f8f9fa"; pixel [label="像素\n(x, y)", fillcolor="#ced4da"]; } subgraph cluster_channels { label="RGB通道"; fontname="sans-serif"; bgcolor="#f8f9fa"; node [shape=circle, fixedsize=true, width=0.6]; R [label="R", fillcolor="#ff8787"]; // 红色 G [label="G", fillcolor="#69db7c"]; // 绿色 B [label="B", fillcolor="#748ffc"]; // 蓝色 } pixel -> R [label=" 值 (0-255)"]; pixel -> G [label=" 值 (0-255)"]; pixel -> B [label=" 值 (0-255)"]; }单个彩色像素位置存储红、绿、蓝通道的三个独立强度值。实际中的数据结构在编程中,特别是在Python中使用OpenCV、NumPy或PIL(Pillow)等库时,这些表示直接转换为类似数组的数据结构:一个高为 $H$ 宽为 $W$ 的灰度图像通常存储为一个二维数组(或矩阵),其尺寸为 $H \times W$。每个元素 image[row][column] 存储像素的强度值。相同大小的RGB彩色图像存储为三维数组,尺寸为 $H \times W \times 3$。此处,image[row][column] 本身将是一个小数组或元组,包含该像素的三个值 (R, G, B)。第三个维度(大小为3)表示颜色通道。例如,一个相对较小的 $640 \times 480$ 像素的彩色图像将由一个包含 $640 \times 480 \times 3 = 921,600$ 个独立数字的数据结构表示!位深度我们提到了0-255的范围,这来自于每个通道使用8位($2^8 = 256$ 个可能值)。这被称为位深度。虽然8位对于标准图像(JPEG、PNG)非常常见,但某些应用(如医学成像或科学摄影)使用更高的位深度(例如,10位、12位或16位)来获取更细微的强度变化。更高的位深度意味着每个像素或通道有更多可能的值,从而产生更平滑的渐变和更多细节,但文件大小也会更大。了解图像本质上是数字网格这一点很重要。正是这种数字表示使得我们能够应用数学运算和算法,用计算机处理、分析和解释视觉信息。在接下来的部分中,我们将查看表示颜色的不同方式(色彩空间)以及用于高效存储这些数字网格的常见文件格式。