🐸 青蛙编程网
首页 / AI / 图像识别 / 1. 计算机如何"看"图

计算机如何"看"图:像素、通道与张量

这是什么:计算机视觉(CV) = 让机器"看图"并认出货物的本事;图片在人眼里是画面,在机器眼里是一张巨大的数字表格。

为什么用:恭喜从 机器学习 毕业!你已经知道"模型从数据里学规律"。从这一章起进入图像识别——不懂像素和通道,后面的 CNN 和预训练模型全都无从下手。

如何用:本章先手算一遍灰度,再用 Pillow 造一张 2×2 的迷你图,把像素和通道一个个读出来。

图片 = 数字矩阵

把一张图片放大到极限,会看到一格一格的小方块,这就是像素(pixel)。每个像素本质是一个数字:0 是纯黑,255 是纯白。一张 1920×1080 的照片,就是 1920 行 × 1080 列的数字表格,约 200 万个数。计算机"看图",就是在读这张表。

RGB:三个通道叠出彩色

彩色照片的每个像素不是一个数,而是三个数:红(R)、绿(G)、蓝(B)各一个 0~255 的值。三种光按不同比例混合,能叠出人眼可见的几乎所有颜色:

  • (255, 0, 0) → 纯红
  • (0, 255, 0) → 纯绿
  • (0, 0, 255) → 纯蓝
  • (255, 255, 0) → 红 + 绿 → 黄色
  • (255, 0, 255) → 红 + 蓝 → 品红
  • (0, 255, 255) → 绿 + 蓝 → 青色
  • (255, 255, 255) → 白
  • (0, 0, 0) → 黑

每个数各占一路,就叫通道(channel):彩色图有 3 通道,黑白照片只有 1 通道。

灰度图:从三层压成一层

灰度图把 RGB 按人眼敏感度压成一个亮度值:

灰度 = 0.299×R + 0.587×G + 0.114×B

人眼对绿色最敏感,所以绿权重最大。很多识别任务第一步就是转灰度,先去掉颜色干扰。

手算一遍灰度

像素 (255, 0, 0) 纯红:

  • 灰度 = 0.299 × 255 + 0.587 × 0 + 0.114 × 0 = 76.245 ≈ 76

像素 (0, 255, 0) 纯绿:

  • 灰度 = 0.299 × 0 + 0.587 × 255 + 0.114 × 0 = 149.685 ≈ 150

纯绿看起来比纯红更亮,符合人眼直觉。

亲手读一读像素

光说不练假把式。先安装 Pillow(Python 最常用的图像库):

pip install pillow

然后造一张 2×2 像素的迷你图,再把它的数值读出来:

from PIL import Image

# 造一张 2x2 的图:左上红、右上绿、左下蓝、右下白
img = Image.new("RGB", (2, 2))
img.putpixel((0, 0), (255, 0, 0))
img.putpixel((1, 0), (0, 255, 0))
img.putpixel((0, 1), (0, 0, 255))
img.putpixel((1, 1), (255, 255, 255))

print(img.size)               # 尺寸:宽 2、高 2
print(img.getpixel((0, 0)))   # 读左上角像素
print(img.getpixel((1, 1)))   # 读右下角像素

gray = img.convert("L")       # 转灰度(L 即亮度)
print(gray.getpixel((0, 0)))  # 红色像素的灰度值
print(gray.getpixel((1, 1)))  # 白色像素的灰度值

你会看到(输出为示意):

(2, 2)
(255, 0, 0)
(255, 255, 255)
76
255

红色 (255, 0, 0) 按公式算灰度:0.299 × 255 ≈ 76,对上了!

分辨率与归一化

真实任务里还会做两件事:

  1. 统一分辨率:模型要求输入尺寸一致(常见 224×224),图片先被缩放。分辨率越大细节越多,但计算量也成倍上涨
  2. 归一化:把 0~255 除以 255 压到 0~1。数值变小、范围统一,模型学得更快更稳

最后把"一批图片"摞在一起——张数 × 通道 × 高 × 宽——就得到 AI 里天天出现的高维数组:张量(tensor)。ML 章节里数据是表格,到了 CV,数据变成了张量。

概念 含义 例子
像素 图片最小单元,本质是数字 (255, 0, 0) 是纯红
通道 颜色分量数:灰度 1 个、彩色 3 个 RGB 三通道
分辨率 像素格数,决定清晰度 1920×1080
归一化 把像素压到统一小范围 255 ÷ 255 = 1.0
张量 多维数组,AI 的标准数据格式 [批次, 通道, 高, 宽]

记忆口诀:图是数字表,彩色三通道;灰度压一层,缩放归一进张量。

❓ 常见问题

Q1:为什么像素值是 0~255?

因为一个像素每个通道用 1 个字节(8 位)存储,2^8 = 256 个取值,即 0~255。

Q2:灰度图和黑白图是一样的吗?

基本一样,但严格说灰度图有 256 级亮度,黑白图(二值化)只有 0 和 1 两个值。CV 里常说的"灰度"就是 0~255 的亮度图。

Q3:为什么要归一化到 0~1?

神经网络对数值范围敏感。0~255 和 0~1 只是缩放关系,但 0~1 梯度更稳,模型收敛更快。

⚠️ 新手翻车现场

翻车一:读错像素坐标顺序

# 错误:以为 (x, y) = (列, 行),实际 PIL 的 getpixel 是 (x, y) 但 x=列,y=行
print(img.getpixel((1, 0)))  # 这是第 2 列、第 1 行(右上角)
print(img.getpixel((0, 1)))  # 这是第 1 列、第 2 行(左下角)

修正:PIL 的 getpixel((x, y)),x 是横坐标(列),y 是纵坐标(行)。和数学坐标系一致,但和图像处理里常见的 (行, 列) 顺序相反,注意别搞反。

翻车二:灰度转换后以为还是 3 通道

gray = img.convert("L")
print(gray.mode)  # 输出 'L',表示单通道灰度
print(gray.getpixel((0, 0)))  # 返回一个数,不是 (R, G, B) 元组

修正:灰度图每个像素只有一个数值(亮度),读出来是单个整数,不是元组。

🎯 什么时候用这些概念

  • 像素/通道:理解图像底层数据结构,做图像预处理
  • 灰度:去除颜色干扰,降低计算量,做边缘检测等任务
  • 分辨率与归一化:给深度学习模型喂图之前的标准操作
  • 张量:理解深度学习框架(PyTorch/TensorFlow)的数据格式

📝 本章小结

  • 图片在计算机眼里是数字矩阵,每个像素是一个或三个数(灰度/RGB)
  • RGB 三通道叠出彩色,灰度按加权公式压成一层亮度值
  • 真实任务要统一分辨率、做归一化,最后组成张量喂给模型
  • 记忆口诀:图是数字表,彩色三通道;灰度压一层,缩放归一进张量。

动手改

  1. 把右下角像素改成 (0, 0, 0),先猜灰度值是多少,再运行验证
  2. 用 img.resize((4, 4)) 把图放大一倍,打印新尺寸,体会"分辨率"的变化
  3. 用 Image.open("你的照片.jpg") 读一张自己的照片,打印它的尺寸和某个像素值

下一章:卷积神经网络入门,看看模型怎么从数字表里认出猫和狗 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。