图像处理入门003:数字图像的本质:从像素到矩阵

在这里插入图片描述

系列:图像处理算法入门
期数:第003期 / 共144期
日期:2026-08-12
关键词:数字图像、像素、矩阵、采样、量化、分辨率、位深、颜色通道
难度:⭐⭐☆☆☆(需少量NumPy基础)


一、前言

上期我们搭建好了开发环境,从今天开始进入图像处理的核心理论。理解"图像在计算机中到底是什么",是后续所有算法的地基。本文将从物理图像出发,拆解数字化的三步骤——采样、量化、编码,最终落到一个关键认知:数字图像就是 NumPy 数组(矩阵)。文末提供 4 个完整可运行的代码实验,帮助你在代码层面建立直觉。


二、从物理世界到数字图像:三步走

我们肉眼看到的照片是连续的,但计算机只能处理离散数据。将连续图像转化为数字图像需要三个步骤:

连续图像  ──采样──▶  离散空间  ──量化──▶  离散灰度  ──编码──▶  数字图像
(模拟)    (Sampling) (像素网格) (Quantization)(整数值)   (Encoding) (二进制矩阵)

2.1 采样(Sampling)—— 空间离散化

定义:将连续的二维空间划分为有限的网格点,每个网格点取一个值作为该位置的代表。

  • 采样密度越高(网格越密),空间分辨率越高,图像越清晰。
  • 采样不足会导致锯齿/摩尔纹,称为混叠(Aliasing)

直观理解:把一幅画用棋盘格覆盖,每个格子取一个颜色值。格子越小,还原越精确。

2.2 量化(Quantization)—— 幅值离散化

定义:将每个采样点的连续灰度值映射到有限个离散等级。

  • 量化等级越多,灰度分辨率越高,过渡越平滑。
  • 量化不足会导致伪轮廓(False Contouring)——本应平滑的渐变出现明显台阶。

常见量化等级

位深量化等级取值范围典型场景
1 bit2 级0-1二值图、OCR
8 bit256 级0-255普通照片(最常见)
16 bit65536 级0-65535医学影像、RAW
32 bit浮点0.0-1.0HDR、科学计算

2.3 编码(Encoding)—— 二进制表示

将量化后的整数值用二进制存储。8 位图每个像素占 1 字节,RGB 三通道彩色图每像素占 3 字节。

计算公式

图像大小(字节) = 宽 × 高 × 通道数 × (位深 / 8)

示例:一张 1920×1080 的 24 位 RGB 图像:

1920 × 1080 × 3 × 1 = 6,220,800 字节 ≈ 5.93 MB(未压缩)

三、像素与分辨率

3.1 像素(Pixel)

像素是数字图像的最小组成单元,名称来自 Picture Element 的缩写。每个像素包含:

  • 空间坐标 (x, y) —— 在矩阵中的行列位置
  • 灰度值/颜色值 —— 一个或多个数值

在 NumPy 中,像素就是矩阵的一个元素:image[row, col]

坐标约定:图像坐标系以左上角为原点,行向下、列向右增加。这与数学中的笛卡尔坐标系(Y 向上)不同,初学者容易混淆。

3.2 分辨率(Resolution)

概念含义典型值
空间分辨率单位长度内的像素数(PPI/DPI)屏幕显示 72 PPI,印刷 300 DPI
灰度分辨率可辨别的灰度等级数8bit = 256 级
图像尺寸像素总数(宽×高)1920×1080 ≈ 207万像素

PPI vs DPI:PPI(Pixels Per Inch)用于屏幕显示,DPI(Dots Per Inch)用于打印输出。日常语境常混用。


四、位深与颜色通道

4.1 位深(Bit Depth)

位深决定了每个通道能表示的色彩精度:

图像类型通道数位深/通道总位深可表示颜色数
二值图11 bit1 bit2
灰度图18 bit8 bit256
RGB 彩色38 bit24 bit16,777,216
RGBA(带透明度)48 bit32 bit16M + 256级透明

4.2 颜色通道(Color Channel)

RGB 图像由三个独立矩阵叠加而成,分别对应红、绿、蓝三个通道:

RGB图像 = [R矩阵] + [G矩阵] + [B矩阵]
        形状: (H, W, 3)

在 OpenCV 中,默认顺序是 BGR 而非 RGB(历史原因),这是新手最常见的坑。

OpenCV 读取: img.shape → (H, W, 3)  通道顺序: B, G, R
Pillow 读取: img.size  → (W, H)     通道顺序: R, G, B

五、核心认知:图像 = 矩阵

这是全文最重要的一句话:

数字图像在计算机中就是一个多维数组(矩阵)。灰度图是二维矩阵,彩色图是三维张量。所有图像处理算法本质上都是矩阵运算。

图像类型NumPy 数组形状dtype取值范围
灰度图 (8bit)(H, W)uint80-255
灰度图 (16bit)(H, W)uint160-65535
RGB 彩色(H, W, 3)uint80-255
浮点图(H, W)float320.0-1.0

理解了这一点,你就能用 NumPy 做几乎所有基础图像操作——无需调用任何图像库。


六、代码实践

6.1 实验一:用 NumPy 从零创建灰度图像

"""
实验一:用 NumPy 创建灰度图像矩阵并可视化
理解:灰度图 = 二维数组,值越大越亮
"""
import numpy as np
import matplotlib.pyplot as plt

# ========== 1. 创建全黑图像(5x5) ==========
img_black = np.zeros((5, 5), dtype=np.uint8)
print("5x5 全黑图像矩阵:")
print(img_black)
# 输出:全是 0 的矩阵

# ========== 2. 创建全白图像(5x5) ==========
img_white = np.ones((5, 5), dtype=np.uint8) * 255
print("\n5x5 全白图像矩阵:")
print(img_white)
# 输出:全是 255 的矩阵

# ========== 3. 创建渐变图像(0→255) ==========
# np.linspace 生成 0-255 的渐变,reshape 成 1x256,再广播为 256x256
gradient_row = np.linspace(0, 255, 256, dtype=np.uint8)
img_gradient = np.tile(gradient_row, (256, 1))  # 沿行方向重复256次

# ========== 4. 创建棋盘格图像 ==========
# 利用模运算生成 8x8 格子的棋盘
size, block = 256, 32
rows = np.arange(size) // block
cols = np.arange(size) // block
checkerboard = ((rows[:, None] + cols[None, :]) % 2 * 255).astype(np.uint8)

# ========== 5. 可视化 ==========
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
titles = ["全黑 5x5", "全白 5x5", "水平渐变 256x256", "棋盘格 256x256"]
images = [img_black, img_white, img_gradient, checkerboard]

for ax, img, title in zip(axes, images, titles):
    ax.imshow(img, cmap="gray", vmin=0, vmax=255)
    ax.set_title(title, fontsize=12)
    ax.axis("off")

plt.suptitle("实验一:NumPy 创建灰度图像", fontsize=14)
plt.tight_layout()
plt.savefig("code/output/003_exp1_grayscale.png", dpi=150, bbox_inches="tight")
plt.show()
print("\n✅ 实验一完成,图像已保存至 code/output/003_exp1_grayscale.png")

6.2 实验二:创建 RGB 彩色图像

"""
实验二:用 NumPy 创建 RGB 彩色图像
理解:彩色图 = (H, W, 3) 三维数组,三个通道分别对应 R/G/B
"""
import numpy as np
import matplotlib.pyplot as plt

# ========== 1. 创建纯色图像(红色、绿色、蓝色) ==========
H, W = 256, 256

img_red   = np.zeros((H, W, 3), dtype=np.uint8)
img_red[:, :, 0] = 255        # R=255, G=0, B=0

img_green = np.zeros((H, W, 3), dtype=np.uint8)
img_green[:, :, 1] = 255      # R=0, G=255, B=0

img_blue  = np.zeros((H, W, 3), dtype=np.uint8)
img_blue[:, :, 2] = 255       # R=0, G=0, B=255

# ========== 2. 创建双色渐变图 ==========
img_gradient = np.zeros((H, W, 3), dtype=np.uint8)
img_gradient[:, :, 0] = np.linspace(0, 255, W, dtype=np.uint8)  # R 左→右渐变
img_gradient[:, :, 2] = np.linspace(255, 0, W, dtype=np.uint8)  # B 右→左渐变

# ========== 3. 创建三色拼接图 ==========
img_tri = np.zeros((H, W, 3), dtype=np.uint8)
img_tri[:, :W//3] = [255, 0, 0]       # 左 1/3 红色
img_tri[:, W//3:2*W//3] = [0, 255, 0] # 中 1/3 绿色
img_tri[:, 2*W//3:] = [0, 0, 255]     # 右 1/3 蓝色

# ========== 4. 可视化 ==========
fig, axes = plt.subplots(1, 5, figsize=(20, 4))
titles = ["纯红", "纯绿", "纯蓝", "红蓝渐变", "三色拼接"]
images = [img_red, img_green, img_blue, img_gradient, img_tri]

for ax, img, title in zip(axes, images, titles):
    ax.imshow(img)
    ax.set_title(title, fontsize=12)
    ax.axis("off")

plt.suptitle("实验二:NumPy 创建 RGB 彩色图像", fontsize=14)
plt.tight_layout()
plt.savefig("code/output/003_exp2_rgb.png", dpi=150, bbox_inches="tight")
plt.show()
print("✅ 实验二完成,图像已保存至 code/output/003_exp2_rgb.png")

6.3 实验三:采样——空间分辨率对图像质量的影响

"""
实验三:模拟不同采样率对图像质量的影响
通过下采样+上采样模拟低分辨率效果
"""
import cv2
import numpy as np
import matplotlib.pyplot as plt

# ========== 1. 生成高分辨率测试图(含细节) ==========
H, W = 512, 512
# 创建包含线条和文字的合成图
img = np.zeros((H, W), dtype=np.uint8)

# 绘制同心圆
center = (W // 2, H // 2)
for r in range(20, 240, 20):
    cv2.circle(img, center, r, 255, 1)

# 绘制网格线
for i in range(0, H, 32):
    cv2.line(img, (0, i), (W, i), 128, 1)
    cv2.line(img, (i, 0), (i, W), 128, 1)

# ========== 2. 不同采样率下采样后上采样回原尺寸 ==========
# 下采样因子分别为 2, 4, 8, 16
factors = [1, 2, 4, 8, 16]
fig, axes = plt.subplots(1, len(factors), figsize=(20, 4))

for ax, factor in zip(axes, factors):
    # 下采样:每隔 factor 个像素取一个
    downsampled = img[::factor, ::factor]
    # 上采样:用最近邻插值还原到原始尺寸
    upsampled = cv2.resize(downsampled, (W, H), interpolation=cv2.INTER_NEAREST)

    h_down, w_down = downsampled.shape
    title = f"原始 {H}x{W}" if factor == 1 else f"采样率 1/{factor}\n({w_down}x{h_down}{W}x{H})"
    ax.imshow(upsampled, cmap="gray", vmin=0, vmax=255)
    ax.set_title(title, fontsize=10)
    ax.axis("off")

plt.suptitle("实验三:采样率对图像质量的影响(混叠效应)", fontsize=14)
plt.tight_layout()
plt.savefig("code/output/003_exp3_sampling.png", dpi=150, bbox_inches="tight")
plt.show()
print("✅ 实验三完成,图像已保存至 code/output/003_exp3_sampling.png")

6.4 实验四:量化——位深对图像质量的影响

"""
实验四:模拟不同量化等级对图像质量的影响
将 256 级灰度压缩到更少的灰度等级
"""
import numpy as np
import matplotlib.pyplot as plt

# ========== 1. 创建渐变测试图 ==========
W = 256
gradient = np.linspace(0, 255, W, dtype=np.uint8)
img = np.tile(gradient, (W, 1))  # 256x256 水平渐变

# ========== 2. 不同量化等级 ==========
# 量化方法:img_quantized = (img // step) * step
bits_list = [8, 4, 3, 2, 1]  # 对应 256, 16, 8, 4, 2 级
levels = [2 ** b for b in bits_list]

fig, axes = plt.subplots(1, len(bits_list), figsize=(20, 4))

for ax, bits, level in zip(axes, bits_list, levels):
    if bits < 8:
        step = 256 // level
        img_q = (img // step) * step
        img_q = np.clip(img_q, 0, 255).astype(np.uint8)
    else:
        img_q = img.copy()

    ax.imshow(img_q, cmap="gray", vmin=0, vmax=255)
    ax.set_title(f"{bits} bit / {level} 级", fontsize=12)
    ax.axis("off")

plt.suptitle("实验四:量化等级对图像质量的影响(伪轮廓效应)", fontsize=14)
plt.tight_layout()
plt.savefig("code/output/003_exp4_quantization.png", dpi=150, bbox_inches="tight")
plt.show()
print("✅ 实验四完成,图像已保存至 code/output/003_exp4_quantization.png")

七、常见问题与解决方案

问题原因解决方案
imshow 显示彩色图偏蓝OpenCV 读取的是 BGR,matplotlib 需要 RGB使用 cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 转换
灰度图显示为偏色imshow 默认用彩色 colormap添加 cmap="gray", vmin=0, vmax=255
NumPy 创建图像后保存为黑色dtype 不是 uint8 或值域超出 0-255确保 dtype=np.uint8 且值在 0-255
渐变图有条纹量化等级不足(< 8bit)使用至少 8bit(256级)存储
坐标系混乱图像行列与 xy 坐标方向不同记住 img[row=y, col=x],行向下,列向右

八、相关产品推荐

移动端 App

产品平台与本期内容的关联适合场景
SnapseediOS / Android内置"细节"面板可直观对比像素级放大效果,理解采样概念日常照片编辑、像素级观察
Lightroom MobileiOS / Android支持 RAW(16bit)拍摄,可对比 8bit vs 16bit 动态范围差异移动端专业摄影后期
VSCOiOS / Android胶片滤镜基于 LUT(查找表),本质上是对像素值的量化映射风格化调色

专业级工具

产品平台与本期内容的关联适合场景
Adobe PhotoshopWin / macOS支持切换 8/16/32bit 模式,直方图面板实时显示像素分布专业图像编辑
Affinity PhotoWin / macOS / iPad一次性买断,支持 16bit/32bit HDR 工作流专业级 Photoshop 替代
ImageJWin / macOS / Linux开源科研工具,可逐像素查看矩阵值,支持 16bit/浮点图像科研图像分析、像素级研究

九、扩展练习

  1. 矩阵操作练习:用 NumPy 创建一张 512×512 的灰度图,在中心画一个直径 200 的白色实心圆,四周为黑色。提示:用 np.meshgrid 生成坐标,计算距离判断。
  2. 量化对比:读取一张真实照片,分别量化为 8bit/6bit/4bit/2bit,计算每次量化后的 MSE(均方误差),绘制"量化位数 vs MSE"曲线。
  3. 通道分离:用 NumPy 切片操作分离一张 RGB 图像的三个通道,分别显示为红色、绿色、蓝色的单通道图(其他通道设为0),并拼接为一行展示。

十、知识总结

概念核心要点一句话记忆
采样空间离散化,决定图像尺寸格子越密越清晰
量化灰度离散化,决定色彩精度等级越多越平滑
编码二进制存储,决定文件大小位深×通道×像素 = 文件大小
像素图像最小单元矩阵的一个元素
分辨率空间分辨率(PPI) vs 灰度分辨率(级数)PPI 管清晰,位深管过渡
矩阵图像 = 多维数组灰度(H,W) 彩色(H,W,3)

十一、下节预告

第004期:图像文件格式深度解析:JPEG/PNG/TIFF/BMP,将拆解四种常见格式的压缩原理、适用场景与文件结构,并用代码实测各格式的文件大小与质量差异。


本期核心结论:数字图像在计算机中就是 NumPy 数组。灰度图是 (H, W) 的二维矩阵,彩色图是 (H, W, 3) 的三维张量。所有图像处理算法,本质上都是矩阵运算。建立这个认知,后续学习事半功倍。

觉得有用的话,点赞收藏不迷路,我们下期见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Andrew浮游会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值