Blackwell ISP
Thor 沿用 NVIDIA ISP 架構(與 Orin 的 libnvivp 同族),提供統計給 AE/AWB。
⚠️ Thor ISP 完整公開參數集以官方文件為準。
NVIDIA ISP(libnvivp 同族)的管線區塊各自對應一種「影像缺陷」。除錯時反過來用:看到什麼症狀 → 哪個區塊負責。
| 區塊 | 作用 | 症狀若停用 |
|---|---|---|
| 黑位 OB | 扣除感測器暗電流偏移 | 整體偏灰/偏綠 |
| LSC | 補償鏡頭陰影 | 四角偏暗偏色(unit-12) |
| Demosaic | Bayer → RGB 重建 | 彩色假影/雜訊(aliasing) |
| NR | 空間/時間降噪 | 低光雜訊明顯(unit-13) |
| CCM | 色彩矩陣校正 | 色偏不自然(unit-11) |
| Gamma/TM | 亮度對數曲線/色調映射 | 高光爆、暗部死黑 |
| Statistics | 算 AE/AWB 需要的統計值 | AE/AWB 收斂不正常 |
RAW code = 500(10-bit) OB 扣除:500 − 黑位(64) = 436 LSC:中央增益 1.0 → 436 Demosaic:鄰近 R/G/B 內插 → R=430, G=436, B=432 NR:小幅平滑 → 不變(訊號不強) CCM:3×3 矩陣轉換 → R'=0.9R−0.1G+... → 校正後色 Gamma:code 經過非線性 → 128(8-bit 輸出) 輸出:127~129 的灰
1. 整體偏色? ├─ AWB/CCM 關閉?→ 手動設灰卡白平衡 └─ 仍偏 → 黑位 OB 檢查 2. 四角暗? └─ LSC(unit-12) 3. 低光雜訊多? └─ NR 與增益(unit-13) 4. 高光爆、暗部死黑? └─ Gamma/TM 與曝光(unit-10/14) 5. 動態畫面有假影? └─ 幀率/曝光(unit-11 幀率單元、unit-14)
NVIDIA ISP 的 AE/AWB 是「閉迴路」:ISP 計算每幀統計(亮度分布、色平衡),演算法依統計調整參數,下一幀再重算——如此反覆收斂。
| 統計 | 餵給誰 | 異常時症狀 |
|---|---|---|
| 亮度直方圖 | AE | 過暗/過亮 |
| 色平衡統計 | AWB | 色偏 |
| 區域統計(格子) | AE/AWB | 局部曝光錯 |
1. 開機拍暗場景:畫面很暗 2. 幾幀後 AE 逐步調高曝光/增益 → 畫面變亮 3. 檢查收斂:亮度不再大幅跳動 = 已收斂 4. 若一直跳動或過暗: → 統計目標錯 / 上限卡住 / 感測器 RAW 有問題 (回到 unit-10 的「上限卡住」診斷)
場景:Thor T5000 同時處理 3 顆感測器(前視 8MP + 左右側視 2MP),每顆的 ISP 統計獨立計算 AE/AWB。左側視感測器朝向逆光窗戶,AE 統計被強光主導,導致整體曝光策略錯誤。
# 問題:3 顆感測器共享同一 ISP 統計引擎 # 左側視逆光 → AE 計算出「場景很亮」→ 降低曝光 # → 前視感測器跟著變暗 → 前方物件欠曝 # 解決方案:per-sensor AE ROI 設定 # 1. 每顆感測器的 AE 統計範圍獨立設定(不跨 sensor) # 2. 前視感測器的 AE 目標獨立於側視 # 3. 或使用 Holoscan 的統計隔離 operator,每路 ISP 管線各自有獨立 AE 閉迴路 # 驗證: # 固定前視曝光為手動,觀察側視曝光自動調整是否影響前視 # 若不受影響 → 統計隔離成功
Thor 的 Blackwell ISP 支援 multi-pass processing:同一幀資料可以通過 ISP 管線多次,每次套用不同的參數集。例如第一 pass 做基礎色彩校正(CCM + AWB),第二 pass 做局部 tone mapping。這在 HDR 場景中特別有用——第一 pass 計算動態範圍,第二 pass 針對高光/暗部分別映射。
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| 輸出影像整體偏綠但 RAW 四通道正常 | CCM 矩陣未套用或 CCM 色溫分段切換錯誤 | 確認 CCM 輸入色溫是否與實際光源匹配;用手動 AWB 固定色溫後重試 |
| AE 收斂後畫面仍過暗 | AE 目標亮度設定過低 / 統計 ROI 遮蔽主體 | 調整 AE target brightness;確認統計 ROI 覆蓋主要場景區域 |
| 低光場景中 NR 開啟後畫面模糊 | 空間 NR 強度過高,把細節當雜訊抹除 | 降低 spatial NR strength;確認 sharpen 在 NR 之後才啟用 |
| multi-pass ISP 的第二 pass 產生殘影 | 時間性 NR 在 multi-pass 間的幀緩衝未清除 | 確認 temporal NR 的幀緩衝在 multi-pass 切換時正確重置 |
| ISP 輸出的 histogram 與 RAW histogram 不一致 | gamma/tone mapping 在兩者之間改變了亮度分布 | 比較時必須在同一階段(RAW vs RAW,或 sRGB vs sRGB) |
場景:你接手一個 Thor 專案,畫面「怪怪的」。專案目標:用「逐區塊停用實驗」建立對 ISP 管線的實證理解,並定位畫面異常來自哪個區塊。
M1 建立基準 ├─ 固定場景(灰卡 + 光源箱) ├─ 固定曝光、關 AWB └─ 通過:取得 RAW 與 YUV 基準檔 M2 逐區塊停用 ├─ 依序停用:OB / LSC / Demosaic / NR / CCM / Gamma ├─ 每停一個存一張 YUV └─ 通過:每張對應「症狀 vs 區塊」觀察記錄 M3 症狀→區塊對照 ├─ 整理「停用某區塊 → 出現什麼症狀」 └─ 通過:產出自己平台的區塊-症狀表 M4 統計回饋檢查 ├─ 檢查 AE/AWB 統計是否隨區塊停用變化 └─ 通過:理解統計取樣點在哪個區塊之後 M5 異常定位 ├─ 套回原參數,重新診斷初始「怪畫面」 └─ 通過:定位到具體區塊並提出修正 M6 產出調校地圖 └─ 通過:repo 內有「區塊-症狀-調校參數」對照文件
Step 1 固定條件 固定曝光、固定 AWB、固定光源、灰卡/色卡 Step 2 取基準 RAW + YUV 各一組 Step 3 統計檢查 看亮度直方圖、色平衡統計是否落在合理範圍 Step 4 區塊停用掃描 依序停用區塊,各取一幀,記錄視覺變化 Step 5 量化 比較每幀的 histogram(均亮、峰位、通道比例) Step 6 記錄 區塊-症狀-量化表 進 repo 判讀指標: 停 OB → 偏灰/偏綠 = OB 正常運作 停 LSC → 角落變暗 = LSC 正常運作 停 CCM → 色彩偏感測器原生 = CCM 正常運作 停 Gamma → 暗部變灰 = Gamma 正常運作
| 面向 | Thor T5000 | RPi5 | Orange Pi | Orin Nano |
|---|---|---|---|---|
| ISP 位置 | Blackwell 硬體引擎 | libcamera(CPU) | 感測器內建 | NVIDIA 硬體引擎 |
| 管線順序 | OB→LSC→Demosaic→NR→CCM→Gamma | libcamera(可看原始碼) | 感測器固定 | 同 NVIDIA 族 |
| 統計回饋 | ✅ AE/AWB 統計閉迴路 | ✅ IPA | ⚠️ 感測器韌體 | ✅ 同 Thor |
| 區塊可調性 | 受限(自動化為主) | 全可調(開源) | 幾乎不可調 | 受限 |
| Multi-pass | ✅ 支援 | ❌ | ❌ | ⚠️ 部分 |
本單元涉及的關鍵 register,以及「讀→改→寫→驗證」的完整位元級操作序列:
| Register | 位址 | 功能 | Bit Field 說明 |
|---|---|---|---|
ISP_BLC_OFFSET | 0x00140000 | Black Level Correction 偏移 | bit[15:0] = BLC offset per channel (R/Gr/Gb/B) |
ISP_BPC_CTRL | 0x00140040 | Bad Pixel Correction 控制 | bit[0]=enable, bit[1]=method (median/interpolation) |
# Step 1: 讀取目前值 $ devmem2 0x00140000 w # 記錄 current_value # Step 2: 計算新值(設定 bit[0]=1) $ new_value=$((current_value | 0x0001)) # Step 3: 寫入 $ devmem2 0x00140000 w $new_value # Step 4: 驗證 $ devmem2 0x00140000 w # 確認 bit[0] = 1,其餘 bit 不變 # Step 5: 進階 — bitmask 操作 $ read_val=$(devmem2 0x00140000 w | grep "Read" | awk '{print $NF}') $ mask=0x0001 $ expected=0x0001 $ [ $(($read_val & $mask)) -eq $expected ] && echo "PASS" || echo "FAIL: bit[0] not set"
1. 色彩偏移或反色? ├─ CCM matrix 未載入 → 確認 ISP tuning 文件路徑 └─ Gamma curve 設定錯 → 進 visualizer 調 LUT 2. 暗角或亮角? ├─ LSC table 不對 → 重拍白卡生成新 table └─ 鏡頭與 LSC table 不匹配 → 確認 lens 型號
1. pipeline latency > 20ms? ├─ ISP clock 頻率太低 → 檢查 `cat /sys/kernel/debug/bpmp/debug/clk/isp/rate` └─ ISP block 過多 → 關閉不需要的功能(HDR、Nr、LSC 可暫關測試)
ISP 管線完整驗證 SOP:
| 步驟 | 動作 | 指令/方法 | 預期輸出 |
|---|---|---|---|
| Step 1 | raw 輸入確認 | 先確保 sensor raw streaming 正常 | raw 檔非零 |
| Step 2 | BLC 驗證 | 拍暗場,量測四通道 black level | R/Gr/Gb/B 接近(±2 DN) |
| Step 3 | BPC 驗證 | 拍白卡,放大檢視 dead pixel | 無明顯亮/暗點 |
| Step 4 | LSC 驗證 | 拍白板四角,量測亮度均勻度 | 四角差 < 10% |
| Step 5 | Demosaic 驗證 | 拍 ISO 12233 chart | 無 moiré / false color |
| Step 6 | CCM + AWB 驗證 | 拍白卡 + X-Rite ColorChecker | ΔE < 3 |
| Step 7 | Gamma 驗證 | 拍 21 級灰階 chart | tone curve 符合預期 |
| Step 8 | NR + 銳化 | 暗場 + 細節 chart | 雜訊抑制但不糊 |
| 面向 | Thor T5000 | RPi5 | Orange Pi | Orin Nano |
|---|---|---|---|---|
| ISP 處理能力 | Blackwell ISP: 2 GOPS | 博通 BCM2835 ISP | 無獨立 ISP(CPU soft) | NVIDIA ISP: 1.5 GOPS |
| BLC 精度 | 12-bit per channel | 10-bit | N/A(raw only) | 12-bit |
| BPC 方法 | Median + ML inference | Fixed pattern | N/A | Median + Interpolation |
| LSC table 格式 | 5×5 grid × 4 channels | 17×13 grid | N/A | 16×12 grid |
| CCM 矩陣大小 | 3×3 + offset | 3×3 | N/A | 3×3 + offset |
| ISP tuning 工具 | NVIDIA ISP Visualizer | raspistill --settings | N/A | NVIDIA ISP Visualizer |
針對「ISP 管線深入」主題的完整 bring-up 步驟清單: