【camera】分散点学习
目录方向一Sensor 上电时序IMX989 的完整启动流程为什么顺序这么重要Sensor 硬件层面你看不到的部分IMX989 的 Standby/Restart方向二、ADDR_BYTE 和 DATA_BYTE 的含义方向三、噪声特性为什么 sensor 驱动工程师要懂噪声三种主要噪声1. 光子散粒噪声Photon Shot Noise2. 读出噪声Read Noise3. 暗电流噪声Dark Current Noise噪声和增益的关系噪声特性曲线ISP 降噪如何利用噪声特性噪声标定怎么做你可以做的验证实验噪声知识总结一句话总结方向一Sensor 上电时序IMX989 的完整启动流程从代码中提取的完整时序时间线 →→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→ Step 1: SOC 端 MIPI 时钟使能 OT_MIPI_ENABLE_MIPI_CLOCK ↓ Step 2: SOC 端 MIPI RX 复位 OT_MIPI_RESET_MIPI ↓ Step 3: SOC 端配置 combo_dev_attr ext_data_type ↓ Step 4: SOC 端 MIPI RX 解复位准备接收数据 OT_MIPI_UNRESET_MIPI ↓ Step 5: Sensor 端上电sample_comm_vi_start_sensor │ ├── 5a: 使能 Sensor 时钟MCLK │ OT_MIPI_ENABLE_SENSOR_CLOCK │ ├── 5b: 复位 Sensor拉低 RESET 引脚 │ OT_MIPI_RESET_SENSOR │ └── 5c: 解复位 Sensor拉高 RESET 引脚 OT_MIPI_UNRESET_SENSOR ↓ Step 6: ISP 框架调用 modules989_init() │ ├── 6a: 初始化 I2Copen /dev/i2c-X │ ├── 6b: 写初始化序列imx989_common_init 模式特定序列 │ → 几百个寄存器写入 │ ├── 6c: 写运行时寄存器CIT/GAIN/DGAIN/VMAX │ modules989_default_reg_init() │ ├── 6d: 等待 10ms │ delay_ms(10) │ └── 6e: 启动 Sensor 出流 modules989_restart() → 写 0x0100 0x01 ↓ Step 7: MIPI 开始传输数据 → ISP 开始处理 → 画面出现为什么顺序这么重要如果先启动 Sensor 再配置 SOC 端 → Sensor 已经开始发 MIPI 数据了 → SOC 端 MIPI RX 还没准备好 → 数据丢失前几帧花屏 如果 MCLK 还没稳定就复位解复位 → Sensor 内部 PLL 没锁上 → 寄存器写入可能失败 → Sensor 不响应 I2C 如果 0x0100 0x01 写太早寄存器还没配完 → Sensor 用默认参数出流 → 帧率/分辨率可能不对Sensor 硬件层面你看不到的部分PCB 上电时硬件工程师负责 │ ├── VDD_IOI/O 供电 1.8V ← 最先上 ├── VDD_CORE核心供电 1.1V ├── VDD_ANALOG模拟供电 2.8V ├── AVDDMIPI 供电 1.2V │ └── 所有电源稳定后 → 等待 MCLK 软件接管后上面的 Step 5 开始 │ ├── 给 MCLK通常 24MHz 或 37.125MHz ├── Sensor 内部 PLL 锁定 → 产生内部时钟 │ 内部时钟 MCLK × PLL 倍频 │ 比如 24MHz × 62.5 1500MHzMIPI 速率 │ ├── RESET 拉高 → Sensor 开始执行内部初始化 │ └── I2C 可用通常 MCLK 稳定后 1~10msIMX989 的 Standby/Restart// 暂停出流不关闭电源 modules989_standby() → 写 0x0100 0x00 // STANDBY 模式 // 恢复出流 modules989_restart() → 写 0x0100 0x01 // 恢复出流这是最轻量的开关方式不需要重新写整个初始化序列。方向二、ADDR_BYTE 和 DATA_BYTE 的含义不同的 sensor 有不同的地址/数据宽度组合┌──────────┬──────────┬─────────────┬─────────────────────┐ │ Sensor │ADDR_BYTE │ DATA_BYTE │ 一次传输的字节数 │ ├──────────┼──────────┼─────────────┼─────────────────────┤ │ IMX989 │ 2 │ 1 │ [AH][AL][D] │ │ OV 系列 │ 2 │ 1 │ [AH][AL][D] │ │ SC 系列 │ 2 │ 1 │ [AH][AL][D] │ │ 某些老 sensor│ 1 │ 1 │ [A][D] │ │ 某些 16bit │ 2 │ 2 │ [AH][AL][DH][DL] │ └──────────┴──────────┴─────────────┴─────────────────────┘ IMX989 #define MODULES989_ADDR_BYTE 2 ← 寄存器地址是 16bit2 字节 #define MODULES989_DATA_BYTE 1 ← 每个寄存器值是 8bit1 字节如果配错了ADDR_BYTE 写成 1应该是 2 → 只发了低字节地址 → sensor 收到错误的寄存器地址 → 写到了别的地方 → 可能花屏或死机 DATA_BYTE 写成 2应该是 1 → 多发了一个字节 → sensor 把第二个字节当成下一条命令的地址 → 后续通信全部错乱方向三、噪声特性为什么 sensor 驱动工程师要懂噪声你以为的画面理想每个像素值 真实光照强度实际的画面每个像素值 真实光照 各种噪声噪声决定了· 画面干不干净· ISP 降噪模块的参数怎么调· 增益上限设多少合适三种主要噪声1. 光子散粒噪声Photon Shot Noise物理本质光子到达是随机事件泊松分布即使光照完全均匀每个像素收到的光子数也不一样期望收到 100 个光子实际可能收到93, 107, 98, 102, 95, 110...噪声 √信号 √100 10信噪比 SNR 信号/噪声 100/10 10信号越大 → 绝对噪声越大 → 但信噪比越好弱光100 个光子噪声 10SNR 10 → 画面有噪点强光10000 个光子噪声 100SNR 100 → 画面干净这就是为什么暗光下噪点多的根本原因这个噪声无法消除——它是光的物理特性不是 sensor 的问题。2. 读出噪声Read Noise来源sensor 内部的电路噪声像素 → 放大器 → ADC → 输出每一步电路都会引入噪声· 热噪声温度越高越大· 1/f 噪声低频噪声· 量化噪声ADC 精度有限即使完全没有光盖上镜头盖像素值也不是 0→ 而是在某个值附近随机抖动用代码中的数据来看#define MODULES989_BLACK_LEVEL 1032 // OBOptical Black值OB 值的含义 盖上镜头盖完全没有光时像素值 ≈ 1032 但每个像素不是精确的 1032 像素1: 1030 像素2: 1035 像素3: 1028 像素4: 1034 ... 平均值 ≈ 1032这就是 Black Level 标准差 ≈ 2~5这就是读出噪声的大小ISP 的 BLCBlack Level Correction模块就是减去这个值原始像素值 1032 信号 噪声 BLC 后 0 信号 噪声 ← 去掉了直流偏置3. 暗电流噪声Dark Current Noise来源即使没有光像素也会因为热效应产生电子 温度每升高 6~7°C → 暗电流翻倍 室温25°C暗电流很小可忽略 高温60°C暗电流显著增大画面出现热噪点 长时间曝光时更明显 · 曝光 1ms暗电流几乎看不到 · 曝光 1s暗电流积累很多画面有明显的亮点噪声和增益的关系增益放大信号的同时也放大了噪声 原始信号S 100噪声 N 10散粒 3读出 13 SNR 100/13 ≈ 7.7 增益 2x 后 信号 200噪声 26 SNR 200/26 ≈ 7.7 ← SNR 不变 但如果是在暗处原始信号只有 10 原始S 10N 3.16散粒 3读出 6.16 SNR 10/6.16 ≈ 1.6 ← 已经很差了 增益 16x 后 信号 160噪声 98.6 SNR 160/98.6 ≈ 1.6 ← 依然很差 → 画面看起来就是一片噪点这就是为什么高增益 高噪点而且降噪怎么都救不回来。噪声特性曲线每个 sensor 都有一条这样的特性曲线噪声 ↑ │ ╱ │ ╱ │ ╱ │ ╱ │ ╱ │ ╱╱ │ ╱╱ │ ╱╱ │ ╱╱ │ ╱╱ │ ╱╱╱╱ ← 噪声 √(散粒² 读出² 暗电流²) │ ╱╱╱╱ 高增益区域噪声急剧上升 │╱╱╱╱ └──────────────────────────────────→ 增益ISO 1x 2x 4x 8x 16x 32x 64xIMX989 的三个模式在这条曲线上的位置不同线性模式10bit · 增益范围 1x ~ 64x · 高增益时噪声明显但能用 DCG 12bitHCG:LCG 4:1 · HCG 路径天生灵敏度高 4 倍 · 相当于起点就高同样场景需要的增益更小 · 所以暗光下噪点更少 · 有效动态范围 ≈ 线性 12dB DCG 14bitHCG:LCG 16:1 · HCG 灵敏度高 16 倍 · 暗光性能最好 · 但 VMAX 更小2776最大曝光时间更短 · 亮处可能过曝ISP 降噪如何利用噪声特性你的代码里有一个关键参数isp_def-noise_calibration g_cmos_noise_calibration;Noise Calibration噪声标定 告诉 ISP 在不同 ISO增益下噪声有多大 ┌──────────────────────────────────┐ │ ISO 100: 噪声 2.0 │ │ ISO 200: 噪声 2.8 │ │ ISO 400: 噪声 4.0 │ │ ISO 800: 噪声 5.7 │ │ ISO 1600: 噪声 8.0 │ │ ISO 3200: 噪声 11.3 │ └──────────────────────────────────┘ ISP 的 Bayer NR 和 3DNR 模块根据这个表决定 · 降噪力度多大 · 降噪力度太小 → 噪点残留 · 降噪力度太大 → 细节丢失涂抹感如果噪声标定不准标定值偏低实际噪声 8你告诉 ISP 是 4 → ISP 降噪力度不够 → 画面噪点残留 → 用户觉得画面不干净 标定值偏高实际噪声 4你告诉 ISP 是 8 → ISP 降噪过度 → 画面细节被抹掉 → 用户觉得画面像水彩画噪声标定怎么做标准方法需要实验室环境 1. 盖上镜头盖全黑环境 2. 拍 100 帧 RAW 图 3. 对每个像素计算标准差 → 这就是读出噪声 4. 在不同光照下重复 → 得到散粒噪声曲线 5. 在不同增益下重复 → 得到完整的噪声特性 实际操作 · Sony FAE 通常会提供一份噪声标定数据 · 你也可以用 IQ 工具自己标定 · 标定结果写入 g_cmos_noise_calibration你可以做的验证实验# 在设备上 dump 一帧 RAW 图盖上镜头盖 # 然后用工具分析 # 1. 平均值 ≈ Black Level应该接近 1032 # 2. 标准差 ≈ 读出噪声大小 # 3. 最大值 - 最小值 ≈ 噪声峰峰值 # 如果不盖镜头盖对着均匀白墙拍 # 1. 看画面的均匀性 # 2. 四角比中心暗 → 需要 LSC 校正 # 3. 局部有色偏 → 需要 CCM 校正噪声知识总结噪声类型来源能否消除和增益的关系光子散粒噪声光的量子特性❌ 物理限制信号越大绝对噪声越大但 SNR 越好读出噪声sensor 电路⚠️ 可通过降噪减弱被增益等比放大暗电流噪声热效应⚠️ 可通过降温/减法减弱温度越高越大长曝光更明显一句话总结噪声是画面的底线——sensor 的物理噪声决定了画面质量的上限ISP 降噪只能在这个上限之内做优化。理解噪声特性你才能设合理的增益上限、调正确的降噪参数、解释为什么暗光下噪点多。