單元 10 · 曝光與自動曝光(AE)

Argus 曝光控制

曝光三要素

要素控制注意
快門時間感測器曝光 register太長模糊/banding
類比增益感測器 AGC太高雜訊
數位增益NVIDIA ISP最後手段

透過 Argus 控制

Argus 曝光(示意)
SensorMode ... exp_time = 20000
SensorMode ... gain = 2.0
自動收斂:NVIDIA AE 依統計自動調整。除錯「過暗」→ 確認 AE 是否卡在快門/增益上限。

10.6 深入:曝光 register 與 Worked Example

讀目前曝光
v4l2-ctl -d /dev/v4l-subdev0 -C exposure

曝光值依感測器位元布局組合(單元 3 的 16-bit 位址規則)。正式流程用驅動/平台控制,這裡只是理解。

控制曝光
argus_camera SensorMode exp_time=20000
順序鐵則:先快門 → 類比增益 → 數位增益。用增益補曝光犧牲畫質。

10.7 練習

  1. 讀目前曝光/增益值。
  2. 手動設定並確認生效。
  3. 日光燈下檢查 banding。

10.8 深入原理:曝光 register 的位元級與單位換算

OV9281 的曝光時間以「(line)」為單位:每行時間 = line_length_pclk / pclk。這是 register 與真實時間換算的關鍵。

Register內容範例值
0x3501/0x3502曝光行數(高/低 8-bit)1000 = 0x03E8
0x350A/0x350B類比增益(整數 + 0.5 步進)2.0 = 0x04 / 0x00
曝光行數 → 真實時間
假設 pclk=96 MHz,line_length=1688 pclk
每行時間 = 1688 / 96M ≈ 17.6 µs
曝光 1000 行 = 17.6 ms

假設目標曝光 20 ms:
行數 = 20000 µs / 17.6 µs ≈ 1136 行 → 寫 0x3501=0x04, 0x3502=0x70
陷阱:不要把 Argus 的「exp_time(µs)」直接寫進 register。Argus 會幫你換算;但手動控制(或感測器內建 ISP 平台)必須自己算行數。單位搞錯是曝光問題第一名。

10.9 Worked Example:AE 被「上限卡住」的診斷

畫面過暗,判斷卡在哪
1. 讀目前曝光與增益:
   v4l2-ctl -d /dev/v4l-subdev0 -C exposure
   v4l2-ctl -d /dev/v4l-subdev0 -C gain
2. 若 exposure 已達上限(如最大行數):
   → 光線不足,靠曝光救不回 → 補光 / 換鏡頭光圈
3. 若 gain 已達上限(如 8×)且雜訊明顯:
   → 增益撐到極限,品質崩壞 → 補光優先
4. 若兩者都沒到上限但畫面仍暗:
   → AE 統計/目標設定問題(不是光學問題)
工程原則:曝光優先序永遠是「快門 → 類比增益 → 數位增益」。數位增益是最後的不得已,因為它放大「訊號 + 雜訊」而不是只加訊號。

10.10 疑難排解決策樹:過暗/過亮/banding

曝光三症狀
過暗:
 ├─ AE 卡上限 → 補光/光圈
 ├─ AE 統計錯誤 → 場景過暗或有遮罩
 └─ 黑位錯 → 回 unit-08
過亮:
 ├─ AE 目標太高 → 調目標亮度
 ├─ 曝光行數爆掉 → 查 max
 └─ 感測器飽和 → 縮光圈/曝光
banding(條紋):
 ├─ 日光燈 50/60Hz → 曝光時間為市電週期的整數倍
 └─ 感測器讀出問題 → 查 clock

10.11 常見錯誤與陷阱

陷阱 1:把數位增益當萬能——數位增益放大雜訊。低光品質要看「類比增益極限 + 補光」而非拉數位。
陷阱 2:忽略曝光對 motion blur 的影響——global shutter 只是「整幀同步」,不是「曝光變短」。機器人高速運動仍要短曝光,否則 blur。
陷阱 3:banding 只想到電源——市電閃爍(50/60Hz)造成的是時間性 banding,與電源 ripple 不同。分別處理。

10.12 練習

  1. 讀出你感測器目前曝光行數,換算成 ms。
  2. 設定 20 ms 曝光並回讀驗證。
  3. 在日光燈下調整曝光為 50Hz 整數倍,觀察 banding 消失。

10.13 深入原理:曝光、幀時間與運動模糊

曝光不是孤立的 register。對每一個 sensor mode,都有 line length、frame length、pixel clock 與最大曝光行數。幀時間由 frame length × line time 決定;曝光越長,留給讀出與下一幀的餘裕越少。global shutter 解決的是逐列不同步,不會消除長曝光造成的 motion blur。

mode timingline timeexposure linesframe intervalmotion blur / banding
限制結果調整方向
曝光超過 frame marginFPS 降低或 driver clamp查 frame length/max exposure
曝光接近 10/20 ms 的非整數LED/市電 banding鎖定 anti-flicker 時間
運動速度高模糊,即使 global shutter縮短 exposure、補光、提高 gain

10.14 Worked Example:由目標 FPS 反推曝光上限

60 fps mode 的 timing budget
目標 FPS = 60 → frame interval = 16.67 ms
假設 line time = 17.6 µs
最大曝光行數(保留 8 行 margin)
  = floor(16,670 / 17.6) - 8
  ≈ 939 lines
最大曝光時間 ≈ 939 × 17.6 µs = 16.53 ms

若 AE 要 20 ms:
  → 不能同時維持 60 fps,必須降 fps、提高補光或接受 gain
驗證:比較設定值、回讀值、metadata 中的實際 exposure。
工程判讀:Argus 顯示的目標值不等於感測器最後接受的值。每次調 AE 都要同時記錄 requested、applied、frame rate 三個數字。

10.15 疑難排解決策樹:AE 不穩或曝光不正確

把控制問題與光學問題分開
1. requested 與 applied exposure 不同?
   ├─ 是 → 查 mode 上限、frame margin、單位換算
   └─ 否 ─┐
2. RAW histogram 是否隨曝光改變?
   ├─ 否 → 查 register latch、stream 狀態、sensor reset
   └─ 是 ─┐
3. 亮度仍上下跳動?
   ├─ 是 → 查 AE target、ROI、統計延遲與 anti-flicker
   └─ 否 ─┐
4. 亮度正常但影像糊/有條紋?
   └─ 查運動速度、光源頻率與曝光時間,不要先拉數位增益

10.16 常見錯誤與陷阱

陷阱 1:把曝光單位當微秒直接寫 register。Argus 的時間通常是 API 單位,sensor register 常是行數;中間必須用 mode timing 換算。
陷阱 2:只看顯示器亮度。顯示器可能套 gamma、tone mapping 或自動亮度;AE 驗證要看 RAW histogram 與 metadata。
陷阱 3:用提高 FPS 解決延遲卻忘了光量。FPS 提高會縮小曝光 budget,低光時可能導致 gain 爆升與 SNR 惡化。

10.17 練習

  1. 從一個實際 mode 的 pclk、line length、frame length 算出 line time 與最大曝光。
  2. 建立 30/50/60 fps 的 anti-flicker 測試,記錄 banding 與實際 applied exposure。
  3. 固定亮度,分別改曝光與類比增益,量測 motion blur、SNR、FPS 的取捨。
看完這單元你應該能說出:
  • 曝光三要素。
  • Argus 控制曝光。
  • NVIDIA AE 自動收斂。
  • 「上限受限」除錯方向。

延伸閱讀

10.18 進階真實情境 Worked Example:60 fps 機器人高速取像的曝光預算

場景:Thor T5000 搭載在 AGV(自動引導車)上,OV9281 @ 60 fps 做 SLAM。AGV 速度 2 m/s,目標清晰 SLAM 特徵點(motion blur < 1 pixel)。

Motion blur 反推曝光上限
# SLAM 要求:motion blur < 1 pixel
# OV9281 像素尺寸 3.0 µm,鏡頭焦距 2.8 mm
# 1 pixel 在物方的寬度 = 3.0 µm × (物距/焦距)
# 物距 1 m → 1 pixel ≈ 1.07 mm
# AGV 速度 2 m/s → 最大曝光 = 1.07 mm / 2 m/s = 0.535 ms

# 60 fps → frame interval = 16.67 ms
# 最大曝光 0.535 ms << 16.67 ms → 有充足時間
# 但曝光太短 → SNR 可能不足

# SNR 驗證( OV9281:full well 10000 e⁻, QE 60%)
# 曝光 0.5 ms、場景 500 lux:
# 光子數 ≈ 500 × 0.5 ms × 像素面積 × 120 lm/W ≈ 假設 800 光子
# 電子數 = 800 × 0.6 = 480 e⁻
# SNR = 20·log10(480/√480) ≈ 26.6 dB(偏低)

# 解決方案:
# 1. 提高增益 → 雜訊增加 → SNR 更差
# 2. 補光 → 光子數增加 → SNR 提升 → 推薦
# 3. 加大光圈 → 更多光子 → 同時景深縮小(SLAM 可能需要)
設計決策:高速 SLAM 的曝光上限由 motion blur 決定,不是由 FPS 決定。先用「blur < 1 pixel」算出最大曝光,再用「SNR ≥ 30 dB」驗證。兩者矛盾時,補光是唯一不犧牲品質的解法。

10.19 深入原理擴充:Thor 的 AE ROI 與區域統計

NVIDIA ISP 的 AE 支援 多區域統計(multi-zone statistics):把畫面分成 N×M 格子,每格獨立計算亮度。AE 演算法可以針對特定 ROI(Region of Interest)調整曝光,而非只看全畫面平均。這在「前景暗 + 背景亮」的場景中至關重要。

容易忽略的邊界案例:若 AE ROI 設定在畫面中央但主體在邊緣(例如機器人手臂在畫面右下),AE 會被中央背景主導,導致手臂過暗。在多感測器系統中,每顆感測器的 AE ROI 必須獨立設定,且需與 Holoscan 管線中的目標偵測 ROI 對齊。

10.20 診斷式疑難排解表

症狀可能原因解決方案
AE 收斂後畫面仍過暗,gain 已達上限曝光時間被 frame length clamp(上限卡住)讀回 applied exposure 與 max exposure;若已卡上限 → 補光或降 fps
日光燈下畫面有水平亮暗帶曝光時間非市電週期整數倍(50/60 Hz banding)啟用 anti-flicker 模式或手動設定曝光為 10 ms 整數倍
ROI 外的主體過暗AE ROI 未覆蓋主體區域重新設定 AE ROI;或用全畫面平均 AE + 手動微調
動態場景中曝光跳動AE 反應速度過快 / 統計延遲導致 overshoot降低 AE convergence speed;增加 temporal smoothing
60 fps mode 下最大曝光 < 1 ms 但仍過亮場景光線過強,即使最短曝光仍飽和加入 ND filter 或縮小光圈;感測器端限制最大 analog gain

10.21 進階挑戰題

  1. 設計一個 SLAM 專用的 AE 策略:在 60 fps 下動態調整曝光,確保 motion blur < 1 pixel 的同時 SNR ≥ 28 dB。若場景光線不足,自動觸發補光。畫出完整的控制流程圖。
  2. 分析 anti-flicker 在 50 Hz 與 60 Hz 電源下對 FPS 的影響:若曝光必須是 10 ms 整數倍,最大可用 FPS 各是多少?若場景光源同時有 50 Hz 與 60 Hz(混合光源),如何設定 anti-flicker?
  3. 在 Thor 的多感測器系統中,設計一個「AE 優先級」機制:前視感測器的 AE 優先級高於側視。當兩者的曝光需求衝突時,如何在 Holoscan 管線中實現「優先滿足前視」的策略?

10.22 專案級端到端 Worked Example:AE 調校專案 — 從收斂到抗閃爍

場景:Thor 上的 SLAM 機器人,60 fps、會進出不同亮度環境(倉庫 / 戶外)、且常在日光燈下運作。專案目標:AE 在各種場景收斂快、無 banding、曝光不超過 motion blur 上限。

里程碑規劃
M1 曝光計算基礎
   ├─ 算出 line time、最大曝光行數(unit-10.14)
   └─ 通過:requested = applied(回讀一致)

M2 收斂測試
   ├─ 場景快速切換(亮↔暗),觀察 AE 收斂幀數
   └─ 通過:< 15 幀收斂、無 overshoot 跳動

M3 上限診斷
   ├─ 低光:確認曝光/增益誰先到上限
   └─ 通過:知道卡在哪、知道該補光或降 fps

M4 anti-flicker
   ├─ 日光燈下測 50/60Hz banding
   ├─ 設定曝光為市電週期整數倍
   └─ 通過:無水平亮暗帶

M5 ROI 策略
   ├─ SLAM 場景定義 AE ROI
   └─ 通過:主體(前景)曝光優先

M6 回歸
   └─ 通過:亮/暗/混合光源各場景全過

驗證:
  v4l2-ctl -d /dev/v4l-subdev0 -C exposure,gain
  # 比較 requested 與 applied
專案要點:AE 調校不是「調一個目標值」而是「驗證三個閉迴路」:收斂速度、上限行為、抗閃爍。三個都驗過,AE 才算完成。

10.23 量測 / 驗證 SOP:曝光與 AE 驗證

曝光 SOP(Step 1–6)
Step 1 讀目前值
   v4l2-ctl -d /dev/v4l-subdev0 -C exposure,gain
Step 2 手動設定並回讀
   設定曝光 → 回讀確認 applied 一致
Step 3 單位換算驗證
   曝光行數 × line time = 真實時間
Step 4 收斂測試
   切換場景亮度,數 AE 收斂幀數
Step 5 banding 測試
   日光燈下調整曝光為 50/60Hz 整數倍
Step 6 上限測試
   低光下找出「曝光 or 增益先到上限」

判讀指標:
  requested ≠ applied → mode 上限 / 單位換算錯
  收斂 > 30 幀 → 調 reaction speed
  banding 存在 → 曝光非市電週期整數倍

10.24 平台間對照:曝光控制

面向Thor T5000RPi5Orange PiOrin Nano
控制介面SensorMode exp_time / V4L2ExposureTimeexposure(V4L2 ctrl)SensorMode exp_time
AE 引擎NVIDIA 自動化libcamera IPA感測器內建NVIDIA 自動化
anti-flicker✅ 支援✅ 支援⚠️ 少✅ 支援
AE ROI✅ 多區域統計✅ libcamera⚠️
曝光單位µs(Argus)→ 行數(register)µs行數或 µs(依驅動)µs(Argus)→ 行數
選擇思考:「先快門→類比增益→數位增益」的順序鐵則四平台通用。Thor/Orin 的 AE 最自動化、ROI 最完整;Orange Pi 的 AE 能力最受限。

10.25 互動式檢核清單

10.18 Register 位元級完整工作流

本單元涉及的關鍵 register,以及「讀→改→寫→驗證」的完整位元級操作序列:

Register位址功能Bit Field 說明
SENSOR_EXPOSURE_REG0x3500/0x3501/0x3502 (OV9281)Exposure timebit[19:16]=upper, bit[15:8]=mid, bit[7:0]=lower, 單位 line
AE_CONVERGENCE_STATUS0x00100010AE 收斂狀態bit[0]=converged, bit[1]=over_exposed, bit[2]=under_exposed
讀→改→寫→驗證 完整序列(以 SENSOR_EXPOSURE_REG 為例)
# Step 1: 讀取目前值
$ devmem2 0x3500/0x3501/0x3502 (OV9281) w
# 記錄 current_value

# Step 2: 計算新值(設定 bit[0]=1)
$ new_value=$((current_value | 0x0001))

# Step 3: 寫入
$ devmem2 0x3500/0x3501/0x3502 (OV9281) w $new_value

# Step 4: 驗證
$ devmem2 0x3500/0x3501/0x3502 (OV9281) w
# 確認 bit[0] = 1,其餘 bit 不變

# Step 5: 進階 — bitmask 操作
$ read_val=$(devmem2 0x3500/0x3501/0x3502 (OV9281) w | grep "Read" | awk '{print $NF}')
$ mask=0x0001
$ expected=0x0001
$ [ $(($read_val & $mask)) -eq $expected ] && echo "PASS" || echo "FAIL: bit[0] not set"

10.19 多層疑難排解決策樹

決策樹 1:AE 收斂失敗
1. 曝光值不動?
   ├─ AE 被鎖定 → 檢查 `v4l2-ctl --set-ctrl=exposure_auto=1`(manual)
   └─ AE 正常但收斂慢 → 收斂速度參數太保守,調 AE speed factor
2. 曝光震盪(忽亮忽暗)?
   ├─ AE 步進太大 → 減小 step size
   └─ 目標亮度設定不當 → 調 bright target 值
決策樹 2:曝光時間異常
1. 曝光時間 > frame duration?
   ├─ sensor 降為 partial exposure → 檢查 line_length 與 frame_length
   └─ 設定值超出 sensor range → clamp 到 max exposure
2. 曝光時間 = 0?
   ├─ AE 未啟動 → 確認 AE mode
   └─ 軟體 bug → 檢查 Argus 的 exposure 計算邏輯

10.20 量測驗證完整 SOP

AE 完整量測與調校 SOP:

步驟動作指令/方法預期輸出
Step 1設定 baseline手動 exposure = 10ms, gain = 1×固定光源 D65
Step 2記錄 histogram`v4l2-ctl -d /dev/video0 --list-ctrls` + dump framehistogram 峰值在中間
Step 3啟用 AE`v4l2-ctl --set-ctrl=exposure_auto=3`(aperture priority)AE 開始收斂
Step 4監控收斂每 100ms 記錄 exposure/gain 值2–5 秒內收斂
Step 5驗證穩態靜態場景持續 30 秒exposure 變化 < ±5%
Step 6動態測試突然遮擋 50% 畫面re-converge < 1 秒
Step 7flicker 測試100Hz 日光燈下無 banding

10.21 四平台終極對照

面向Thor T5000RPi5Orange PiOrin Nano
AE 實作Argus 3A (硬體加速)libcamera 3A(軟體)V4L2 auto exposure(有限)Argus 3A
曝光精度1 line(~8.3μs @30fps)1 line1 line1 line
AE 收斂速度< 1 sec(典型)2–5 sec3–8 sec1–2 sec
Flicker 抗制100/120Hz hardware detect軟體(有限)100/120Hz
HDR 曝光控制Stagger 多曝光Single exposureStagger 多曝光
AE ROI 限制

10.22 完整 Bring-up 小 Checklist

針對「曝光與自動曝光(AE)」主題的完整 bring-up 步驟清單: