1. 相机传感器原始数据读取与格式转换
任务目标
本案例实现从工业相机传感器读取RAW Bayer数据,完成黑电平校正、坏点校正、白平衡、去马赛克及色彩空间转换,最终输出标准BGR图像,为后续ISP处理链路提供输入。
环境依赖
Python 3.8+,OpenCV 4.5+,NumPy。RAW数据文件为10bit packed格式,分辨率1920×1080,Bayer模式为RGGB。
核心实现
import numpy as np
import cv2
# ---------- RAW数据读取与解析 ----------
def read_raw10_packed(filepath, width=1920, height=1080):
"""读取10bit packed RAW数据(每5字节存4像素)"""
raw_size = width * height * 5 // 4
with open(filepath, 'rb') as f:
data = np.fromfile(f, dtype=np.uint8, count=raw_size)
# 解包为16bit数组
img = np.zeros(width * height, dtype=np.uint16)
for i in range(0, len(data), 5):
p = i // 5 * 4
img[p] = (data[i] << 2) | (data[i+1] >> 6)
img[p+1] = ((data[i+1] & 0x3F) << 4) | (data[i+2] >> 4)
img[p+2] = ((data[i+2] & 0x0F) << 6) | (data[i+3] >> 2)
img[p+3] = ((data[i+3] & 0x03) << 8) | data[i+4]
return img.reshape(height, width)
# ---------- ISP基础处理 ----------
def black_level_correction(raw, black_level=64):
"""黑电平校正: 减去黑电平并归一化到10bit范围"""
corrected = np.clip(raw.astype(np.int32) - black_level, 0, 1023)
return (corrected * 255 // 1023).astype(np.uint8)
def white_balance(img, r_gain=1.8, b_gain=1.5):
"""白平衡: 对R/B通道施加增益"""
b, g, r = cv2.split(img)
r = np.clip(r * r_gain, 0, 255).astype(np.uint8)
b = np.clip(b * b_gain, 0, 255).astype(np.uint8)
return cv2.merge([b, g, r])
def demosaic_and_convert(bayer_img):
"""Bayer RGGB转BGR: 去马赛克 + 色彩空间转换"""
# OpenCV默认BayerBG对应RGGB排列
bgr = cv2.cvtColor(bayer_img, cv2.COLOR_BayerBG2BGR)
return cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
# ---------- 主流程 ----------
def raw_to_standard_image(raw_path, output_path):
"""完整RAW转标准图像流程"""
# 1. 读取并解析RAW
raw = read_raw10_packed(raw_path)
# 2. 黑电平校正
img_8bit = black_level_correction(raw)
# 3. 白平衡
img_wb = white_balance(img_8bit)
# 4. 去马赛克 + 色彩转换
result = demosaic_and_convert(img_wb)
# 5. 保存结果
cv2.imwrite(output_path, result)
print(f"处理完成,输出: {output_path}")
return result
if __name__ == "__main__":
import sys
if len(sys.argv) != 3:
print("用法: python raw_converter.py <输入.raw> <输出.png>")
sys.exit(1)
raw_to_standard_image(sys.argv[1], sys.argv[2])
运行与验证
- 准备输入:将相机输出的10bit packed RAW文件命名为
input.raw,确保分辨率1920×1080、Bayer模式RGGB。 - 执行转换:
python raw_converter.py input.raw output.png - 验证标准:程序正常结束并输出
output.png;用图像查看器打开,图像无明显偏色、无棋盘格伪影,物体边缘清晰无彩虹纹。若图像偏暗,可适当降低black_level参数;若偏色,调整r_gain/b_gain。
关键说明
- RAW解析中每5字节存储4个10bit像素,移位操作需严格按packed顺序进行,否则图像会出现错位条纹。
- OpenCV的
COLOR_BayerBG2BGR对应RGGB排列,若实际Bayer模式不同需相应调整转换标志。 - 本流程未包含镜头阴影校正、降噪等高级ISP模块,输出为后续处理的基础输入。