客製 OV 接入、完整案例
RPi5 兩組 CSI 可同時跑兩顆;libcamera 以多 Camera 呈現,各自獨立控制。
rpicam-hello --list-cameras # 0: ov5647(1) 1: ov5647(0) 等drivers/media/i2c/ 有對應驅動(ov5647/5640/9281)。rpicam-hello --list-cameras 確認偵測。rpicam-still --raw -o t.dng 出圖 + 存 DNG。□ 硬體:CSI lane / I2C / reset / clock 腳位對齊 □ DT overlay:compatible / reg / clocks / reset-gpios □ 驅動:是否有現成 / 是否需改 init table □ dmesg:probe 成功?讀到 ID? □ 出圖:--list-cameras / 預覽有畫面? □ RAW:Bayer order / 黑位 / 缺陷像素 □ 調校:黑位 → LSC → AWB/CCM → NR/Sharpen
場景:你拿到一顆全新的 OV5647,RPi5 的預設 tuning 不理想(偏暗、偏黃)。需要從零開始,按正確順序建立一份完整的 tuning JSON。
#!/bin/bash
# === 階段 1:備份預設 tuning ===
cp /usr/share/libcamera/ipa/rpi/pisp/ov5647.json ./tuning_v0.json
# === 階段 2:黑位校正(遮光拍攝)===
rpicam-still --raw --shutter 33000 --gain 1 \
--awb off --awbgains 1,1 -o black.dng
python3 - <<'EOF'
import rawpy, numpy as np
raw = rawpy.imread('black.dng').raw_image[500:1500,500:1500]
print(f"BlackLevel: R={raw[0::2,0::2].mean():.0f} "
f"Gr={raw[0::2,1::2].mean():.0f} "
f"Gb={raw[1::2,0::2].mean():.0f} "
f"B={raw[1::2,1::2].mean():.0f}")
EOF
# → 將量測值填入 tuning JSON 的 BlackLevel 區塊
# → 另存為 tuning_v1_black.json
# === 階段 3:LSC 校正(均勻灰拍攝)===
rpicam-still --raw --shutter 20000 --gain 1 \
--awb off --awbgains 1,1 -o lsc_gray.dng
# → 用白牆/灰卡推算 LSC 網格 → tuning_v2_lsc.json
# === 階段 4:AWB/CCM 校正(色卡拍攝)===
rpicam-still --raw --shutter 20000 --gain 1 \
--awb off --awbgains 1,1 -o colorchart.dng
# → 用色卡各色塊計算 CCM → tuning_v3_ccm.json
# === 階段 5:NR/Sharpen 微調(實景)===
rpicam-still --tuning-file tuning_v3_ccm.json \
--shutter 20000 --gain 4 -o real_scene.jpg
# → 調整 Denoise strength + Sharpen → tuning_v4_final.json
# === 驗證 ===
rpicam-still --tuning-file tuning_v4_final.json \
--shutter 20000 --gain 1 --raw -o verify.dngRPi5 的 BCM2712 內建 PiSP(Programmable ISP),其硬體管線有以下特點:
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| 從零建立的 tuning 效果比預設更差 | 跳過了校正順序(如先調 CCM 再校黑位) | 嚴格按黑位→LSC→AWB/CCM→NR 順序重做 |
| 色卡校正後室內場景色彩正確但日光場景偏暖 | CCM 只在一個色溫下校正,未涵蓋其他光源 | 在至少 2-3 個色溫下分別校正 CCM,建立分段表 |
| LSC 校正用白牆但效果不如積分球 | 白牆的均勻度不夠(有陰影、反射、污漬) | 用更均勻的光源;或增加曝光範圍取平均 |
| NR 開到最強仍無法消除低光雜訊 | 增益太高(雜訊源頭過強) | 回到源頭:降增益、加曝光、補光 |
| tuning JSON 修改後 libcamera 報錯 | JSON 語法錯誤或缺少必要欄位 | 用 python3 -m json.tool 驗證;對照預設 JSON 的結構 |
場景:建立一套「雙 OV5647 立體視覺」系統:兩顆相機同步曝光、各自調校、輸出校正後的成對圖。整合單元 16(多感測器)、1(雙鏡頭)、4(overlay)、11/12/13(調校)、15(平台對照)知識。
# 1. 確認兩顆相機(Camera 0 + Camera 1) rpicam-hello --list-cameras # 預期:0 : ov5647 1 : ov5647 # 2. picamera2 同步配置(同尺寸/同參數) python3 - <<'EOF' from picamera2 import Picamera2 cam0 = Picamera2(0); cam1 = Picamera2(1) cfg = lambda c: c.create_still_configuration(main={"size":(1296,972),"format":"RGB888"}) cam0.configure(cfg(cam0)); cam1.configure(cfg(cam1)) # 固定相同曝光/增益/AWB,確保兩眼一致 for c in (cam0, cam1): c.set_controls({"AeEnable":False,"ExposureTime":20000, "AnalogueGain":1.0,"AwbEnable":False}) cam0.start(); cam1.start() cam0.capture_file("left.jpg"); cam1.capture_file("right.jpg") cam0.stop(); cam1.stop() print("立體對輸出完成") EOF # 3. 驗證兩眼一致性 python3 - <<'EOF' import cv2, numpy as np l = cv2.imread('left.jpg'); r = cv2.imread('right.jpg') print("亮度差(mean abs):", np.abs(l.astype(float)-r.astype(float)).mean()) # 目標 < 3(同場景兩眼亮度應幾乎一致) EOF
| 面向 | RPi5 | Orange Pi | Orin Nano | Thor |
|---|---|---|---|---|
| 同步相機數 | 2(雙 CSI) | 1-2(依板型) | 多路(GMSL 可到 8+) | 多路(HSB 乙太) |
| 同步機制 | 軟體同步(誤差較大) | — | 硬體同步(GPIO/trigger) | 硬體同步(乙太精準) |
| 調校工具 | 每顆各自 tuning JSON | — | NVIDIA 批次工具 | Holoscan pipeline |
| 坑 | 雙顆同 I2C 位址要分 bus | 能力有限 | 成本高、NDA | 生態新 |
| 步驟 | 操作 | 位元級說明 |
|---|---|---|
| 1. 確認 sensor 0 I2C 地址 | i2cdetect -y 1 | 0x3C (OV5647 default) |
| 2. 確認 sensor 1 I2C 地址 | i2cdetect -y 0 | 0x3C on bus 0(不同 I2C bus) |
| 3. config.txt 設定 | 加入兩個 dtoverlay | dtoverlay=ov5647,cam0 + dtoverlay=ov5647,cam1 |
| 4. 驗證 media topology | media-ctl -d /dev/media0 -p | 確認兩個 sensor 出現在 topology 中 |
決策樹 A:多感測器只有一個能用
只有一個能用 ├─ 檢查 A:兩個 sensor 是否在不同 I2C bus │ ├─ 同 bus 同地址 → 地址衝突 → 調整其中一個的地址(如有 OTP)
└─ 不同 bus → 繼續 ├─ 檢查 B:config.txt overlay 是否正確指定 cam0/cam1 │ ├─ 未指定 → 加,cam0/,cam1參數 │ └─ 已指定 → 繼續 ├─ 檢查 C:CSI lane 分配是否正確 │ ├─ cam0 佔用全部 lane → cam1 無 lane 可用 → 調整 lane 分配 │ └─ 正確分配 → 繼續 └─ 檢查 D:ISP 是否有足夠 bandwidth 處理雙路 ├─ 無 → 降低其中一路解析度 └─ 有 → 檢查驅動程式 multi-camera 支援
| 面向 | RPi5 | Orange Pi | Orin Nano | Thor | 推薦 |
|---|---|---|---|---|---|
| 最大感測器數 | 2(官方) | 1-2 | 4+ (GMSL) | 多路(乙太網路) | Orin 規模最大 |
| 多攝同步 | 有限(GPIO sync) | 困難 | 硬體 sync 支援 | 網路時間協議 | Orin/Thor 最佳 |
| 帶寬 | 2×4-lane MIPI | 2×2-lane | 4× GMSL2 | 乙太網路無限 | Thor 天生分散 |
| 應用場景 | 立體視覺 | 前後鏡頭 | 多角度監控 | 大型部署 | 依需求選擇 |
| 複雜度 | 中等 | 中等 | 高 | 很高 | RPi5 適合入門 |