1. RAW格式解析:从传感器到数字负片

RAW文件是什么?说白了,它就是相机传感器最原始的“电子底片”。JPEG是厨师做好的菜,RAW则是菜市场买回来的新鲜食材——所有后期处理的决定权都在你手里。我做了十几年影像工程,每次拿到一个新机型的RAW文件,都像拆开一份礼物。

这一节,我们拆开RAW文件的外壳,看看里面到底藏着什么。

1.1 RAW文件结构:TIFF的变种与私有魔改

大多数RAW格式都脱胎于TIFF规范。TIFF是一种标签化文件格式,你可以把它想象成一个带目录的文件夹——每个数据块都有对应的标签(Tag)告诉你“这是什么、在哪里、有多大”。

但相机厂商不会老老实实只用标准TIFF。他们会在文件头里塞私有魔改,比如佳能的.CR2、尼康的.NEF、索尼的.ARW。我当年第一次解析.CR2时,对着十六进制看了三个小时才找到图像数据的偏移量——嗯,那感觉就像在迷宫里找出口。

文件格式 基础规范 厂商私有扩展 典型后缀
CR2 TIFF v6 CR2私有IFD、传感器校准表 .CR2, .CR3
NEF TIFF v6 尼康Makernotes、镜头数据 .NEF, .NRW
ARW TIFF v6 + Sony私有 Sony Makernotes、压缩表 .ARW, .SRF
DNG TIFF v6 + Adobe扩展 公开规范,无私有魔改 .DNG
我的建议:如果你刚开始接触RAW解析,先从DNG入手。Adobe把DNG规范完全公开了,文档写得清清楚楚。等你搞懂了DNG的结构,再去啃CR2和NEF,会轻松很多。

1.2 拜耳阵列原理:为什么每个像素只有一种颜色?

相机传感器是色盲的——它只能感知光的强度,分不清红绿蓝。那彩色照片怎么来的?靠的是拜耳阵列(Bayer Array)。

拜耳阵列在传感器表面覆盖了一层彩色滤光片,每个像素只允许一种颜色的光通过。最常见的模式是RGGB:一个红色、两个绿色、一个蓝色。为什么绿色有两个?因为人眼对绿色最敏感,多给绿色一些采样,视觉上更自然。

拜耳阵列 RGGB 模式 R G B 关键点 • 每个像素只记录一种颜色 • 绿色像素占50%(RGGB) • 红色和蓝色各占25% • 缺失颜色靠插值(去马赛克)

你想想看,一个2400万像素的传感器,实际只记录了600万个红色、1200万个绿色、600万个蓝色信息。剩下的颜色去哪了?靠算法“猜”出来的。这个过程叫去马赛克(Demosaicing),我们后面会专门讲。

核心概念:RAW文件里存储的不是RGB图像,而是拜耳阵列的原始电压值。每个像素只有一种颜色通道的数据。这就是为什么RAW文件看起来“灰蒙蒙”的——它还没经过色彩重建。

1.3 元数据解读:EXIF与Makernotes

RAW文件里除了图像数据,还塞了一大堆元数据。这些数据分成两类:EXIF(可交换图像文件格式)和Makernotes(厂商私有数据)。

EXIF:标准化的相机信息

EXIF是国际标准,所有相机厂商都得遵守。它记录了拍摄时的参数:快门速度、光圈、ISO、焦距、白平衡、时间戳、GPS坐标等等。你可以在任何看图软件里看到这些信息。

但EXIF有个问题——它只记录“用户设置”层面的参数。比如白平衡是“日光”还是“自动”,但不会告诉你传感器具体的色彩校准矩阵。这些更底层的数据,藏在Makernotes里。

Makernotes:厂商的“黑匣子”

Makernotes是相机厂商自己定义的数据区,没有统一标准。每个厂商、甚至每个机型,Makernotes的结构都不一样。这里面藏着什么?

  • 传感器校准数据:黑电平、白电平、色彩矩阵、镜头畸变校正参数
  • 镜头信息:镜头型号、焦距范围、光圈范围、防抖状态
  • 处理参数:降噪强度、锐化设置、色调曲线
  • 私有算法数据:佳能的Picture Style、尼康的Picture Control、索尼的Creative Style
我曾经踩过的坑:有一次我解析索尼ARW文件的Makernotes,按照网上找到的偏移量去读数据,结果读出来的色彩矩阵全是错的。折腾了两天,最后发现索尼在某个固件版本后改了Makernotes的加密方式。嗯,从那以后我养成了一个习惯——先查固件版本,再解析Makernotes。

1.4 实战:用Python读取RAW元数据

光说不练假把式。我们写几行代码,看看RAW文件里到底有什么。

import rawpy
import exifread

# 读取RAW文件
raw = rawpy.imread('sample.CR2')

# 获取图像数据(拜耳阵列原始值)
bayer = raw.raw_image
print(f"传感器尺寸: {bayer.shape}")
print(f"像素位深: {raw.raw_image.dtype}")

# 读取EXIF元数据
with open('sample.CR2', 'rb') as f:
    tags = exifread.process_file(f)

# 打印关键EXIF标签
for tag in ('Image Make', 'Image Model', 
            'EXIF ExposureTime', 'EXIF ISOSpeedRatings',
            'EXIF FocalLength', 'EXIF WhiteBalance'):
    if tag in tags:
        print(f"{tag}: {tags[tag]}")

# 获取相机白平衡乘数(来自Makernotes)
wb = raw.camera_whitebalance
print(f"相机白平衡乘数 (R/G/B/G2): {wb}")

# 获取黑电平
black_level = raw.black_level_per_channel
print(f"黑电平 (R/G1/G2/B): {black_level}")

# 获取白电平(饱和值)
white_level = raw.white_level
print(f"白电平: {white_level}")

raw.close()

这段代码会输出什么?你会看到传感器尺寸、位深、拍摄参数,还有最重要的——黑电平和白电平。这两个值决定了RAW数据的动态范围边界。我建议你拿到一个新机型的RAW文件后,第一件事就是打印黑电平和白电平,看看它的底子到底有多宽。

1.5 知识结构总览

这一节的内容,可以用下面这张图串起来:

RAW格式解析知识结构 RAW文件 文件结构 TIFF v6 基础 厂商私有IFD 压缩与加密 拜耳阵列 RGGB 模式 单像素单色 去马赛克基础 元数据 EXIF 标准信息 Makernotes 私有数据 校准矩阵与黑电平 核心:RAW = 传感器原始数据 + 元数据
个人习惯:我每次拿到一个新机型的RAW文件,都会先跑一遍上面的代码,把黑电平、白电平、色彩矩阵打印出来。这些数据是后续所有处理的基础。如果基础数据错了,后面再怎么调都是白费功夫。