libnvivp、ISP 區塊
ISP 提供統計(亮度、色彩)給 AE/AWB 演算法自動收斂。
NVIDIA 的 ISP(由 libnvivp + RTCPU firmware 驅動)是硬體管線,每個區塊吃前一個區塊的輸出:
| 區塊 | 做什麼 | 調校意義 |
|---|---|---|
| 黑位減除(black level) | 扣掉無光時的偏壓 | 設錯暗部變色/偏黑 |
| LSC(lens shading) | 補邊緣光量衰減 | 回顧單元 12 |
| Demosaic | Bayer → RGB | Bayer order 錯全錯 |
| NR(denoise) | 空間+時間降噪 | 回顧單元 13 |
| CCM | 色彩矩陣校正 | 回顧單元 11 |
| Gamma / tone map | 亮度曲線 | 對比與動態範圍 |
| Sharpen | 細節強化 | 回顧單元 14 |
每一幀產出統計,演算法在數幀內把目標亮度收斂到設定值。調校者能控制的,主要是「統計的 ROI/權重」與「感測器範圍」,而非逐參數手動——這是 NVIDIA 與 RPi5 libcamera 最大的哲學差異。
# 用 Argus 預覽(建議有螢幕) argus_camera --preview 1 --mode 0 --duration 20 # 期間:暗→亮場景切換,觀察 # - 亮度是否在 ~1s 內穩定(收斂快) # - 是否來回振盪(震盪 = 統計/範圍問題) # 同時抓曝光值變化 watch -n 1 v4l2-ctl -d /dev/v4l-subdev0 -C exposure
正常收斂是「漸進逼近」;若你看到週期性閃爍,通常是 AE 與 AWB 交互或增益範圍卡邊界。
AE/AWB 不必看整張畫面——NVIDIA 通常允許設定統計區域(ROI)與權重。例如車牌辨識只在意中央區域,就把 ROI 收窄,避免窗外過亮影響曝光。
# 全畫面統計:大片天空 → AE 過暗 AE: 全畫面 ──→ 天空亮 → 主體黑 # 中央 ROI:主體為主 → 曝光正確 AE: 中央 ROI ──→ 主體亮 → 天空爆(可接受)
| 想改什麼 | 對應區塊 | 本課單元 |
|---|---|---|
| 暗部/亮度 | 黑位、gamma、tone | 8 / 14 |
| 四角暗 | LSC | 12 |
| 色彩偏 | AWB / CCM | 11 |
| 顆粒 | NR / DPC | 13 |
| 不清晰 | Sharpen | 14 |
1. 暗部浮灰/偏色 → 黑位級(回 RAW 檢查) 2. 四角暗/偏 → LSC 級(單元 12) 3. 色偏 → AWB/CCM 級(單元 11) 4. 顆粒 → NR/增益級(單元 13) 5. 不銳利/光暈 → Sharpen 級(單元 14) 6. 亮暗爆 → tone/HDR 級(單元 14) 7. 全錯/花屏 → 格式/管線級(單元 5/8)
場景:你需要用 NVIDIA ISP 同時處理 OV9281(灰階 RAW)和 OV5640(彩色 RAW),最終輸出兩路 NV12 流。
# 初始化 Argus import argus # Sensor 0: OV9281 → ISP pipeline 0 → NV12 output 0 # Sensor 1: OV5640 → ISP pipeline 1 → NV12 output 1 session = argus.createSession() pipeline0 = argus.createPipeline(session, sensor=0, outputFormat='NV12') pipeline1 = argus.createPipeline(session, sensor=1, outputFormat='NV12') # 關鍵:兩個 pipeline 共用同一個 session,但 ISP instance 各自獨立 # 注意:Orin Nano ISP bandwidth 有限,兩路同時高解析度可能降速
設計決策:OV9281 走灰階 pipeline(跳過 CCM/AWB),OV5640 走全 ISP pipeline。分開處理可節省 ISP 資源,且各感測器的調校參數互不干擾。
Orin Nano 有兩種硬體加速器常被混淆:
| 加速器 | 功能 | 在 ISP pipeline 中的角色 |
|---|---|---|
| NVDEC | 硬體影片解碼(H.264/H.265/AV1) | 解碼壓縮影片後送 ISP 處理(例如:從 NAS 讀影片做分析) |
| NVINF(NVINfer) | 張量推論引擎 | 不直接處理影像像素,但可在 ISP 後做 AI 推論 |
| NVJPEG | 硬體 JPEG 編解碼 | JPEG 擷取/壓縮(不經過 ISP pipeline) |
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| ISP pipeline 出圖但色彩偏暗 | LSC/AWB/CCM 參數未載入(使用預設值) | 用 NVIDIA tuning tool 載入校正檔;確認 ISP pipeline 的 setControls 已呼叫 |
| 多路 ISP pipeline 同時跑時其中一路掉幀 | ISP bandwidth 超限(Orin Nano 有上限) | 降低單路解析度或幀率;或讓其中一路 bypass ISP |
| ISP 出圖有殘影(ghosting) | temporal NR(時域降噪)設定過強 | 降低 TNR 強度;或關閉 TNR 測試是否為 TNR 導致 |
| Argus pipeline 回傳 "ISP processing error" | ISP firmware crash(可能因為 invalid register setting) | reset RTCPU(echo 1 > /sys/kernel/debug/rtpu/reset);重新開機 |
| ISP 出圖尺寸與設定不符 | scaler/crop 設定錯誤(DTB 或 Argus 參數) | 用 media-ctl -p 確認 scaler 的輸入/輸出尺寸 |
場景:影像品質問題常常「人人有看法、沒人有證據」。專案目標:建立一套ISP 分級診斷系統,任何「畫面怪」都能用固定流程歸因到「感測器 / 黑位 / LSC / 色彩 / NR / 美化」某一級,並輸出診斷報告。
# Step 1 · 取 RAW 排除感測器 / 格式問題(回顧單元 8) argus_camera --mode 0 --raw-file diag.raw --duration 1 python3 - <<'EOF' import numpy as np raw = np.fromfile('diag.raw', dtype=np.uint16).reshape(800, 1280) print('黑位', raw.min(), '峰值', raw.max(), '均值', round(raw.mean(),1)) # 黑位異常 → 感測器 / 黑位級;峰值爆 → 曝光級;全花 → 格式級 EOF # Step 2 · 依症狀向上分級(回顧 7.12 反向表) # 角落暗 → LSC(單元 12) # 色偏 → AWB / CCM(單元 11) # 顆粒 → NR / 增益(單元 13) # 不銳利 → Sharpen(單元 14) # Step 3 · 每級用標準樣本驗證(灰卡 / 色卡 / 解析度板) # Step 4 · 輸出診斷報告:症狀 → 證據 → 歸因 → 建議
專案輸出:診斷 SOP 文件 + 標準樣本集(灰卡 / 色卡 / 解析度板 / 黑框)+ 診斷腳本。團隊從此不再「憑感覺修影像」。
| 面向 | Orin Nano | RPi5 | Orange Pi | Thor |
|---|---|---|---|---|
| ISP 提供者 | NVIDIA ISP(libnvivp) | libcamera(開源) | 感測器內建 | Blackwell ISP |
| 管線深度 | 完整(BLC→LSC→demosaic→NR→CCM→gamma) | 完整 | 陽春 | 完整 + AI 加速 |
| 統計回饋 | AE/AWB 自動閉迴路 | 可讀可改 | 有限 | 自動 + Holoscan |
| 參數可視性 | 低(封閉) | 高(tuning file) | 中 | 低 |
| 診斷方法 | 看結果 + 統計行為 | 看數值 | 看結果 | 看結果 + 統計 |
| 步驟 | Command | sensor ISP 路徑 | NVIDIA ISP 路徑 |
|---|---|---|---|
| 1. 確認模式 | argus_camera --mode <N> | mode 1(YUV 輸出) | mode 0(RAW 輸出) |
| 2. 輸出格式 | v4l2-ctl --list-formats-ext | NV16 / YUV422 | SRGGB10 RAW |
| 3. 直方圖 | argus_camera --stats | 感測器 ISP 內部直方圖 | NVIDIA ISP 直方圖 |
| 4. 3A 輸出 | argus_camera --3a-output | 感測器 ISP 自動調整 | NVIDIA ISP 自動調整 |
| 5. 延遲比較 | time argus … | 較低(無 ISP 延遲) | 較高(ISP 管線延遲) |
#!/bin/bash # isp_compare.sh — 比較兩種 ISP 路徑 echo "=== Sensor ISP(mode 1, YUV)===" time argus_camera --camera-id 0 --mode 1 \ --exposure-value 0.016 --gain-value 4.0 \ --capture-auto 1 --duration 1 --file-type raw \ --output-dir /tmp/sensor_isp ls -l /tmp/sensor_isp/*.raw echo "" echo "=== NVIDIA ISP(mode 0, RAW + ISP pipeline)===" time argus_camera --camera-id 0 --mode 0 \ --exposure-value 0.016 --gain-value 4.0 \ --capture-auto 1 --duration 1 --file-type raw \ --output-dir /tmp/nvidia_isp ls -l /tmp/nvidia_isp/*.raw echo "" echo "=== 檔案大小比較 ===" S=$(stat -f%z /tmp/sensor_isp/*.raw) N=$(stat -f%z /tmp/nvidia_isp/*.raw) echo "Sensor ISP: $S bytes" echo "NVIDIA ISP: $N bytes" echo "(Sensor ISP 輸出 YUV 較小;NVIDIA ISP 輸出 RAW 較大)" echo "" echo "=== 亮度比較 ===" python3 -c " import numpy as np s = np.fromfile('/tmp/sensor_isp/*.raw', dtype=np.uint8).mean() n = np.fromfile('/tmp/nvidia_isp/*.raw', dtype=np.uint16).mean() print(f'Sensor ISP mean={s:.1f} (8-bit YUV)') print(f'NVIDIA ISP mean={n:.1f} (16-bit RAW)') "
1. "Session create failed"?
├─ 有其他 argus 在跑?
│ ├─ 是 → kill 舊程序
│ └─ 否 → ISP bandwidth 超限
│ → 降 mode 或減少同時開路數
├─ 輸出路徑不存在?
│ └─ mkdir -p 輸出路徑
└─ ISP patch 版本?
└─ 更新 libnvscf.so(重新安裝 jetson-multipackage)1. 想要 RAW 數據? ├─ 是 → 用 mode 0(sensor RAW 輸出) │ → NVIDIA ISP 在 argus pipeline 內做 │ → 需要 libnvivp tuning └─ 否 ┐ 2. 想要已處理的 YUV? ├─ 是 → 用 mode 1(sensor ISP YUV 輸出) │ → NVIDIA ISP 不再處理 └─ 否 ┐ 3. 想要最大控制權? ├─ 是 → mode 0 + custom tuning file └─ 否 → mode 1(sensor ISP 內建處理最省事)
v4l2-ctl -d /dev/video0 --list-formats-ext → 記錄 SRGGB10(mode 0)與 YUV(mode 1)。argus_camera --mode 1 --capture-auto 1 --duration 1 -o /tmp/sensor_isp。argus_camera --mode 0 --capture-auto 1 --duration 1 -o /tmp/nvidia_isp。| 面向 | Orin Nano | RPi5 | Orange Pi | Thor | 推薦 |
|---|---|---|---|---|---|
| ISP 管線 | NVIDIA ISP(複雜) | libcamera 簡化管線 | 感測器內建 | NVIDIA + Holoscan | 學習 → Orin |
| 可用調校模組 | tegracam 精細控制 | tuning file (JSON) | 基本 brightness | 更強 ISP + AI | 量產 → Orin/Thor |
| GPU 加速後處理 | ✅(TensorRT) | 有限 | 有限 | ✅(更強 GPU) | AI 推論 → Orin |
| 感測器 ISP 輸出 | ✅ mode 1 | ✅ libcamera | ✅ 無 ISP | ✅ mode 1 | 省事 → mode 1 |
| NVIDIA ISP 輸出 | ✅ mode 0 | ❌ | ❌ | ✅ mode 0 | 控制 → mode 0 |
| tegracam tuning | ✅ 精細 | JSON tuning file | 無 | ✅ + Holoscan | 各有格式 |
| ISP 延遲 | 中 | 低 | 最低 | 中 | 低延遲 → RPi5 |