Bayer、global shutter、OV9281
OV9281 / OV5640 都是標準 Bayer 排列,由 ISP demosaic 重建全彩。
| 型態 | 特性 | OV9281 |
|---|---|---|
| Rolling | 逐列曝光 | — |
| Global | 全像素同時曝光 | ✅ |
| 項目 | 規格 |
|---|---|
| 解析度 | 1 MP(1280×800) |
| 像素 | 3.0 µm |
| 快門 | Global shutter |
| 輸出 | MIPI CSI-2 |
| I2C 位址 | 0x36 |
| ID register | 0x300A=0x92 / 0x300B=0x81 |
感測器像素是一個光電二極體 + 浮動節點。光子擊中半導體產生電子(QE,量子效率),電子累積在電容(full well),再經 讀出放大(conversion gain)與 ADC 轉成數位碼。關鍵位元級概念:
| 名詞 | 意義 | 對影像的影響 |
|---|---|---|
| QE | 光子 → 電子轉換率 | 低光靈敏度 |
| Full well | 像素能存的最大電子數 | 飽和(過曝)門檻 |
| Conversion gain | 電子 → 電壓放大 | 讀出雜訊/位元深 |
| Bit depth | ADC 解析度(如 10-bit) | 階調與條帶 |
假設該像素接收 4000 光子,QE=60%: 電子數 = 4000 × 0.6 = 2400 e⁻ 飽和比例 = 2400 / 10000 = 24% 輸出 code = 24% × 1023(10-bit 上限)≈ 245 假設曝光時間加倍(光子→8000): 電子數 = 4800 e⁻ → code ≈ 491(線性) 若超過 10000 e⁻ → code 卡在 1023 = 過曝
OV9281 是 1MP 感測器,最常以 2×2(RGGB)輸出。問題常出在裁切/讀出區域:若讀出視窗的起始像素錯位,Bayer order 就會變成 GRBG 等變體,顏色全錯。
1. 拍白色卡片,取 RAW(unit-08) 2. 把 2×2 的四個位置各取平均 3. 兩個綠色通道平均應接近(Gr≈Gb) 4. 若 Gr≠Gb → 不是 RGGB 就是讀出視窗錯位
Global shutter 讓所有像素「同時開始、同時結束」曝光;相較 rolling 逐列曝光。這讓 global 天生對 LED 調光、閃光燈免疫——因為取樣窗是整幀同步。
| 現象 | Rolling | Global |
|---|---|---|
| LED 閃爍(banding) | 易產生水平亮暗帶 | 整幀明暗、無帶狀 |
| 快速移動物 | 果凍效應(傾斜) | 不扭曲 |
| 像素內存電荷 | 不需 | 需儲存節點(影響 QE/面積) |
場景:Thor T5000 搭載在鋼鐵廠 24 小時連續運作的瑕疵偵測站。感測器為 OV9281 global shutter,環境溫度 55°C,感測器表面溫度可達 70°C。目標:穩定 SNR ≥ 30 dB。
室溫(25°C)full well = 10000 e⁻,dark current = 10 e⁻/s 高溫(70°C)dark current 乘以 ~10 倍 → 100 e⁻/s 曝光 8.3 ms(120 fps)→ dark current 貢獻 = 0.8 e⁻(可忽略) 但 70°C 時 full well 衰減至 ~8500 e⁻(約 85%) QE = 60%,平均像素接收 5000 光子: 電子數 = 5000 × 0.6 = 3000 e⁻ 飽和比例 = 3000 / 8500 = 35.3%(比室溫 30% 稍高) SNR = 20·log10(3000 / √3000) ≈ 34.8 dB ✓ # 設計決策: # 1. 高溫讓 full well 下降 → 飽和門檻提前 → 必須降低曝光避免 clip # 2. dark current 增加但在短曝光下可忽略 → 主要瓶頸是 full well 不是 dark current # 3. 加散熱片把感測器降回 55°C → full well 恢復至 ~9200 e⁻ → SNR 提升 1.5 dB
OV9281 支援 dual-gain readout:同一幀中以兩種增益分別讀出,再由後端合成高動態範圍。低增益通道保留高光細節、高增益通道保留暗部。這在 global shutter 感測器中是珍貴的能力,因為 rolling shutter HDR 通常需要多次曝光(運動場景不適用)。
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| 暗部有明顯紫色/綠色斑點 | bit depth 不足導致暗部量化斷階 | 切換至更高 bit depth sensor mode(10-bit → 12-bit);或提高 analog gain 使暗部落入有效範圍 |
| 白卡 RAW 四通道比例正常但輸出偏色 | Bayer order 正確但 CCM 矩陣未套用 | 確認 ISP 管線中 CCM 區塊是否啟用(unit-07);用手動 AWB + 灰卡驗證感測器本身色彩 |
| 高溫環境下偶發過曝 | full well 隨溫度下降,原本安全的曝光量變成飽和 | 加入溫度感測回饋,在 AE 中設定溫度補償表;或限制最大曝光為 high-temp 值 |
| Rolling shutter 感測器拍移動物體有果凍效應 | 逐列曝光時間差造成幾何扭曲 | 改用 global shutter 感測器(如 OV9281);或縮短曝光時間、提高補光 |
| dual-gain HDR 輸出有規律彩紋 | ISP 未設定 dual-gain 模式,Bayer 解析錯位 | 在 DTB 標記 sensor mode 為 dual-gain;確認 ISP demosaic 支援交錯 Bayer |
場景:你拿到一顆規格不明的感測器,要驗證 datasheet 聲稱的 full well、QE、global shutter 與 Bayer order。這個專案建立「感測器驗收」的可重複流程。
Phase 1 ID 與基礎(unit-03) ├─ 讀 ID register,確認型號 └─ 通過:ID 符合 datasheet Phase 2 Bayer order(unit-02/08) ├─ 拍純白卡,取 RAW ├─ 檢查 R/Gr/Gb/B 四通道平均 └─ 通過:Gr≈Gb;輸出 RGGB 或記錄實際順序 Phase 3 黑位與 dark current(unit-13) ├─ 拍黑框(鏡頭蓋)取 RAW ├─ 量 mean(black level)與 std(read noise) └─ 通過:black level 固定、std 在感測器規格內 Phase 4 full well 實測(unit-02) ├─ 固定曝光,逐級增加光量(光源可調) ├─ 找「code 不再上升」的光量點 └─ 通過:飽和 code ≈ 2^bitdepth − 1 Phase 5 global shutter 驗證 ├─ 拍高速轉動物(扇葉) ├─ 逐列是否扭曲(rolling)or 整幀同步(global) └─ 通過:無果凍效應 → 確認 global Phase 6 產出規格表 + 進 repo └─ 通過:文件含實測值 vs datasheet 對照
Step 1 準備 黑框(鏡頭蓋)、白卡、灰卡、可調光源、三腳架 Step 2 黑位 / read noise 固定曝光+gain,暗場取 20 張 RAW mean=black level,std=read noise(unit-13.14) Step 3 Bayer order 白卡 RAW 四通道平均,判別排列 Step 4 full well 逐步加光,找飽和點(unit-02.5 的估算公式反向驗證) Step 5 global shutter 高速轉動物體測試,判斷果凍效應 Step 6 記錄 每一項記錄:mode、曝光、gain、溫度、光量 判讀指標: 黑位:應為固定常數(unit-08) read noise:隨 gain 線性放大 → 正常 full well:飽和 code 對應回電子數 ≈ datasheet ±20%
| 面向 | Thor T5000 | RPi5 | Orange Pi | Orin Nano |
|---|---|---|---|---|
| 感測器生態 | NVIDIA 官方 + 社群模組 | Raspberry Pi 相機(最多) | Allwinner 相容模組 | NVIDIA 官方 + 工業模組 |
| Global shutter 支援 | ✅(OV9281 等) | ✅(IMX296 等) | ⚠️ 少 | ✅(OV9281 等) |
| 感測器內建 ISP | ❌(走 NVIDIA ISP) | ❌(走 libcamera ISP) | ✅(常啟用) | ❌(走 NVIDIA ISP) |
| 多顆同型號 | ✅ 6+ | ✅ 2(需 HAT) | ⚠️ 1–2 | ✅ 4–6 |
| 感測器 ID/register 工具 | i2c-tools | i2c-tools | i2c-tools | i2c-tools |
本單元涉及的關鍵 register,以及「讀→改→寫→驗證」的完整位元級操作序列:
| Register | 位址 | 功能 | Bit Field 說明 |
|---|---|---|---|
SENSOR_GAIN_REG | 0x0104 (OV9281) | Analogue Gain 控制 | bit[7:0] = gain value, 寫入後需等待 1 frame 生效 |
# Step 1: 讀取目前值 $ devmem2 0x0104 (OV9281) w # 記錄 current_value # Step 2: 計算新值 $ new_value=$(current_value | 0x0001) # Step 3: 寫入 $ devmem2 0x0104 (OV9281) w $new_value # Step 4: 驗證讀回值與預期一致 $ devmem2 0x0104 (OV9281) w $ [ "$(devmem2 0x0104 (OV9281) w | grep Read)" = "expected" ] && echo "PASS" || echo "FAIL"
1. 感測器輸出全黑(code=0)? ├─ 暴露時間 = 0?→ 檢查 AE 設定或手動 exposure register ├─ Gain = 0 + 極暗環境?→ 調高 analog gain 0x0104 └─ 輸出不是 0 但極低 → 檢查黑位 black level offset register 2. 影像偏暗但仍可見? ├─ AE convergence 正常?→ `v4l2-ctl --list-ctrls` 看 exposure/gain 值 └─ AE 正常但偏暗 → ISP pipeline 的亮度目標值(bright_target)太低
1. 紅綠反覆、藍黃反覆?
├─ 是 → Bayer order 錯(RGGB vs BGGR)
│ └─ 修改 device tree 的 `bayer-order` 或 ISP CCM matrix
└─ 否 → 色彩偏移
├─ 單色偏 → CCM 校正不準,重跑白卡校正
└─ 全面偏 → AWB 未收斂,檢查光源色溫感測器基本參數量測 SOP:
| 步驟 | 動作 | 指令/方法 | 預期輸出 |
|---|---|---|---|
| Step 1 | 設定已知光源 | 6500K 日光燈或 D65 light box | 光源穩定無 flicker |
| Step 2 | 拍攝白卡 | 18% grey card, 全畫面覆蓋 | ISO 12233 或白卡中心 ROI |
| Step 3 | 量測黑位 | 蓋住鏡頭,取 10 幀平均 | code 應在 60–80 之間(10-bit) |
| Step 4 | 量測 Read Noise | 暗場 100 幀,算 std dev | 期望 < 2 LSB RMS |
| Step 5 | 量測 Full Well | 白卡逐級增加曝光,找 saturation 點 | 期望 > 4000 DN(10-bit) |
| Step 6 | 動態範圍計算 | DR = 20×log10(FW/RN) | 期望 > 60 dB |
| 面向 | Thor T5000 | RPi5 | Orange Pi | Orin Nano |
|---|---|---|---|---|
| 感測器格式支援 | RAW8–16, YUV, PDAF | RAW10, YUV | RAW10, YUV | RAW10–14, HDR |
| Shutter 類型 | Global + Rolling | Global(OV5647 除外) | Rolling only | Global + Rolling |
| Analogue Gain 範圍 | 1×–64× | 1×–16×(OV5647) | 1×–8× | 1×–32× |
| HDR 模式 | 硬體 Stagger + LED HDR | 軟體 HDR(single-exposure) | 無 | 硬體 Stagger HDR |
| PDAF 支援 | ✅ | ❌ | ❌ | ✅ |
| 感測器 ID 讀取 | I2C: `i2cget -y 1 0x60 0x300A` | 同左 | 同左 | 同左 |
| 開箱即用相容數 | 10+ (NVIDIA partner list) | 50+ | 30+ | 20+ (NVIDIA partner list) |
針對「影像感測器基礎」主題的完整 bring-up 步驟清單: