單元 12 · 鏡頭陰影校正(LSC)

NVIDIA LSC

Lens shading 成因

鏡頭邊緣光量低於中心(cos⁴),造成四周暗角、角落偏色。

NVIDIA 的 LSC

關鍵:LSC 是「鏡頭 + 感測器」組合特有——換鏡頭/感測器板就要重新校正;多感測器每顆獨立。

12.6 LSC 網格結構(本平台)

12.7 手算 LSC 增益圖(無工具時)

從均勻灰 RAW 推算
python3 - <<'EOF'
import numpy as np
# raw = 讀取的 RAW(分通道 R/Gr/Gb/B)
# center = 中央區均值;gain = center / cell(四周>1)
# 需分通道各自計算;對純灰卡才準
EOF
注意:手算只為理解;量產請用工具校正。換鏡頭後暗角比變化 >5% → 重新校正。

12.8 深入原理:cos⁴ 定律與分通道成因

鏡頭邊緣光量低於中心,主因是 cos⁴ 定律:離軸角度 θ 造成 cos⁴θ 的光量衰減。這影響是「幾何的」而非感測器問題。另一個成因是 光線斜射通過濾色片,使邊緣光譜偏移 → R/B 通道 shading 不一致 → 角落偏色。

cos⁴θ 衰減整體暗角(luma shading)光譜偏移角落偏色(color shading)
cos⁴ 手算
視場角 30°(θ=30°):
cos(30°) ≈ 0.866
cos⁴(30°) ≈ 0.866⁴ ≈ 0.562
→ 邊緣光量只有中心的 56% → 需要 gain ≈ 1/0.562 ≈ 1.78

視場角 20°:
cos⁴(20°) ≈ 0.78 → gain ≈ 1.28
直覺:越廣角、增益越大,角落增益過高會放大雜訊。這就是為什麼 LSC 要在 NR 之前做——先補償幾何衰減,再談降噪(unit-13 會講順序)。

12.9 Worked Example:手算一顆網格節點的增益

從灰卡 RAW 估角落增益
python3 - <<'EOF'
import numpy as np
raw = np.load('grey_raw.npy')   # 分好通道的 R/Gr/Gb/B
h, w = raw.shape
center = raw[h//2-50:h//2+50, w//2-50:w//2+50].mean()
corner = raw[50:150, 50:150].mean()
print('center', center, 'corner', corner)
print('gain   ', center/corner)   # 角落要乘的增益
EOF
注意:這是最簡化的一點估法。真正 LSC 網格是每節點各自分通道的增益,節點間雙線性插值。量產務必用 NVIDIA 工具(拍多張、自動產生網格),手算只為理解原理。

12.10 疑難排解決策樹:暗角/偏色

「角落偏暗或偏色」
1. 是「整體暗」還是「角落特別暗」?
   ├─ 角落特別暗 → LSC 未校正 / 未更新
   └─ 整體暗 → 曝光(unit-10)
2. LSC 已開仍暗角?
   ├─ 換過鏡頭/感測器?→ 重新校正(組合特有)
   └─ 網格解析度不足?→ 提高網格密度
3. 角落偏色(非暗)?
   └─ color shading 校正(分通道網格)

12.11 常見錯誤與陷阱

陷阱 1:用彩色場景校正 LSC——場景本身有明暗就會被誤當成 shading。要用均勻灰卡 + 均勻光源。
陷阱 2:換鏡頭不重校——LSC 是「鏡頭+感測器」組合的特有結果。換鏡頭後若暗角變化 >5%,一定要重校。
陷阱 3:只校正亮度不分通道——color shading 需要 R/Gr/Gb/B 各自的網格,單一亮度網格解不了偏色。

12.12 練習

  1. 拍灰卡,量測中心與四角亮度比。
  2. 用 12.9 的方法估一個角落節點增益。
  3. 比較「換鏡頭前後」的 shading,驗證重校需求。

12.13 深入原理:LSC 網格、插值與雜訊

LSC 不是把四角任意拉亮,而是為每個 Bayer 通道建立空間增益場。實際像素落在網格節點之間時,ISP 以雙線性插值取得增益;因此網格太粗會留下波紋,太細則對校正圖雜訊與灰卡不均勻更敏感。

均勻灰 RAW四通道 cell mean中心/局部比平滑/限制 gain雙線性插值
校正項代表問題驗證
luma shading角落暗灰卡亮度徑向曲線
color shading角落偏色R/Gr/Gb/B 四通道曲線
高增益限制角落雜訊被放大LSC 前後 SNR
重要:LSC 應使用與產品實際相同的 focus、光圈、曝光、色溫與 sensor mode。裁切或 binning 改變光線映射時,舊網格不一定能沿用。

12.14 Worked Example:由灰卡量測產生四通道節點

一個 4×4 網格節點的計算
中心基準:R=800, Gr=820, Gb=815, B=780
左上 cell:R=600, Gr=650, Gb=640, B=560

gain_R  = 800 / 600 = 1.333
gain_Gr = 820 / 650 = 1.262
gain_Gb = 815 / 640 = 1.273
gain_B  = 780 / 560 = 1.393

限制最大 gain(例如 1.5)後,與鄰近節點平滑,
再由 ISP 在 cell 內插值。若單一節點跳變,輸出可能出現棋盤或光暈。

實驗時要拍多張取平均,排除灰卡反光與 temporal noise;比較 LSC 前後時要固定 AE,否則亮度變化會掩蓋校正效果。

12.15 疑難排解決策樹:LSC 開了仍不均勻

先判斷資料與網格是否對應
1. 校正圖與產品 mode/解析度相同?
   ├─ 否 → 重新拍該 mode 的灰卡
   └─ 是 ─┐
2. 是亮度暗角還是色彩暗角?
   ├─ 亮度 → 查 luma gain、曝光一致性、鏡頭光圈
   └─ 色彩 → 查 R/Gr/Gb/B 分通道網格
3. LSC 前後角落變亮但雜訊爆?
   ├─ 是 → 限制最大 gain、改善光源或重新選鏡頭
   └─ 否 ─┐
4. 出現棋盤/波紋?→ 查網格密度、節點平滑與 stride

12.16 常見錯誤與陷阱

陷阱 1:用畫面中心當絕對真值。中心也可能受曝光、反光與 shading 影響;應使用多區域、分通道、重複拍攝。
陷阱 2:LSC 與 AWB 同時自動變動。AWB 會改變通道比例,使你無法知道偏色修正來自哪一層;校正時先固定 AWB。
陷阱 3:直接沿用另一顆鏡頭的網格。焦距、光圈、法蘭距與感測器 cover glass 都會改變 shading。

12.17 練習

  1. 以同一 mode 拍三張灰卡,計算中心與四角四通道平均及標準差。
  2. 產生兩種網格密度,觀察暗角殘留、波紋與噪聲放大的差異。
  3. 換鏡頭或改光圈重做驗證,建立「哪些條件需要重新校正」清單。
看完這單元你應該能說出:
  • lens shading 成因。
  • NVIDIA LSC 網格。
  • LSC 需隨組合重新校正。
  • 多感測器獨立 LSC。

延伸閱讀

12.18 進階真實情境 Worked Example:多感測器 LSC 獨立校正

場景:Thor T5000 接 3 顆 OV9281(前視 + 左右側視),每顆搭配不同鏡頭(前視 2.8mm 廣角、側視 6mm 標準)。三顆的 lens shading 特性完全不同。

三顆感測器的 LSC 校正流程
# 前視(2.8mm 廣角):
# 視場角 120°,θ_max = 60°,cos⁴(60°) = 0.0625
# → 角落 gain 最高可達 16x(非常大)
# → 雜訊在角落被嚴重放大
# → 限制最大 gain ≤ 4x,接受角落 slight 暗角

# 左/右側視(6mm 標準):
# 視場角 50°,θ_max = 25°,cos⁴(25°) = 0.67
# → 角落 gain ≈ 1.49x(合理範圍)
# → LSC 全補償,無雜訊放大問題

# 校正流程:
1. 三顆各自拍灰卡(同一光源、同一亮度)
2. 各自產生 LSC 網格(格式相同、參數不同)
3. 前視 LSC 限制最大 gain(防角落雜訊爆)
4. 側視 LSC 正常全補償
5. 驗證:拍均勻灰卡,三顆的四角亮度差 < 5%

# 設計決策:
# 1. 每顆感測器 + 鏡頭組合必須獨立校正——不能共用
# 2. 廣角鏡頭的 LSC gain 要設上限——否則角落 SNR 崩壞
# 3. LSC 網格密度要夠高——廣角鏡頭的 shading 變化更快
設計決策:多感測器系統的 LSC 是「每顆獨立」的。廣角鏡頭的 LSC gain 過高是品質隱患——限制最大 gain 並接受 slight 暗角,比讓角落雜訊爆炸更明智。

12.19 深入原理擴充:LSC 與 NR 的交互作用

LSC 在 ISP 管線中位於 NR 之前(unit-07 管線順序)。這代表:LSC 增益會先放大角落的雜訊,然後 NR 再嘗試壓制。若 LSC 增益過高(> 4x),NR 可能把放大後的雜訊當成「正常」訊號而保留,造成角落「有雜訊但 NR 沒完全壓制」的尷尬狀態。

容易忽略的邊界案例:若 LSC 網格過粗(例如 4×4),網格節點間的插值誤差會在影像上產生「棋盤格」或「光暈」效應。這在低光場景特別明顯(因為 LSC 增益高、插值誤差也被放大)。提高網格密度(16×16 或 32×32)可改善,但要與校正圖品質取捨。

12.20 診斷式疑難排解表

症狀可能原因解決方案
LSC 開啟後角落反而更暗LSC 網格的增益方向搞反(衰減變放大)檢查網格增益值:角落應 > 1.0(補償衰減);若 < 1.0 → 方向反了
換鏡頭後 LSC 效果變差但網格未更新LSC 是「鏡頭+感測器」組合特有換鏡頭後必須重新拍灰卡校正 LSC 網格
廣角鏡頭的 LSC 開啟後角落雜訊明顯增加LSC gain 過高(> 4x),放大了角落雜訊限制 LSC 最大 gain;或在 LSC 後增強角落 NR 強度
LSC 網格在低光場景產生棋盤格效應網格過粗 + 增益高 → 插值誤差被放大提高網格密度(32×32);或用更平滑的插值方法
只校正亮度不分通道導致角落偏色Color shading 需要 R/Gr/Gb/B 各自網格重新拍灰卡,分四通道各產生獨立 LSC 網格

12.21 進階挑戰題

  1. 設計一個 LSC 與 NR 的聯合調校策略:在不同 LSC max gain 限制下,量測角落的 SNR 與 NR 保留率。找出「LSC gain vs 角落品質」的最佳甜蜜點。
  2. 比較 4×4、16×16 與 32×32 三種 LSC 網格密度在廣角鏡頭(120°)下的效果。量測暗角殘留、棋盤格可見度與雜訊放大,畫出三者的 trade-off 曲線。
  3. 設計一個自動化 LSC 校正腳本:自動拍灰卡(多張取平均)、分通道計算增益網格、限制最大 gain、平滑處理,並輸出 ISP 可直接載入的 LSC 格式。

12.22 專案級端到端 Worked Example:LSC 校正專案 — 灰卡拍攝到網格部署

場景:Thor 多感測器系統(廣角 + 標準鏡頭混用),需要為每顆建立 LSC 網格並部署到 ISP。

里程碑規劃
M1 拍攝條件
   ├─ 均勻光源 + 灰卡 + 固定光圈/焦距/曝光
   ├─ 固定 AWB(避免通道比例干擾)
   └─ 通過:多張灰卡亮度一致

M2 資料收集
   ├─ 每顆感測器拍 10–20 張灰卡
   └─ 通過:取平均排除 temporal noise

M3 網格計算
   ├─ 分四通道算 cell mean → gain = center/cell
   ├─ 限制最大 gain(廣角 ≤ 4x)
   └─ 通過:網格值合理、無跳變

M4 網格驗證
   ├─ 套入 ISP,重拍灰卡
   ├─ 量四角亮度差 + 四通道比例
   └─ 通過:四角亮度差 < 5%、無偏色

M5 雜訊檢查
   ├─ 檢查角落 SNR(高增益區)
   └─ 通過:SNR 可接受(或調整 max gain 限制)

M6 多感測器部署
   └─ 通過:每顆獨立網格 + 驗證表進 repo

驗證:
  四角亮度差 = (邊緣均亮 − 中心均亮) / 中心均亮
專案要點:LSC 是「鏡頭+感測器」組合特有——每顆都要獨立做。廣角鏡頭一定要限制最大增益,否則角落雜訊爆炸。

12.23 量測 / 驗證 SOP:LSC 校正與復驗

LSC SOP(Step 1–6)
Step 1 固定條件
   均勻光源箱 + 灰卡 + 固定光圈/曝光/焦距 + 固定 AWB
Step 2 拍攝
   10–20 張灰卡,取平均
Step 3 計算網格
   分通道 cell mean → gain;限制 max gain
Step 4 套用
   載入 ISP LSC 網格
Step 5 復驗
   重拍灰卡 → 四角亮度差 < 5%、四通道比例一致
Step 6 記錄
   光圈/焦距/模式條件 + 網格 + 結果進 repo

判讀指標:
  四角仍暗 → 網格未生效 / 解析度模式不符
  出現棋盤/波紋 → 網格過粗
  角落雜訊大 → max gain 太高
  角落偏色 → 分通道網格未正確套用

12.24 平台間對照:LSC 支援

面向Thor T5000RPi5Orange PiOrin Nano
LSC 引擎NVIDIA ISP 網格libcamera tuning感測器內建(有限)NVIDIA ISP 網格
校正工具NVIDIA 工具libcamera tuning 工具手動 registerNVIDIA 工具
分通道網格✅ R/Gr/Gb/B⚠️
網格密度可設定可設定固定可設定
多感測器獨立 LSC⚠️(單一 camera)
選擇思考:LSC 的原理(cos⁴ + 分通道)四平台相同。Thor/Orin 支援多感測器獨立網格、可調密度;Orange Pi 幾乎只能靠感測器內建。

12.25 互動式檢核清單

12.18 Register 位元級完整工作流

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

Register位址功能Bit Field 說明
LSC_TABLE_ADDR0x00140300LSC table 載入位址bit[15:0] = table offset, write 0x01 to trigger load
LSC_STRENGTH0x00140304LSC 強度控制bit[7:0] = strength (0=off, 255=full)
讀→改→寫→驗證 完整序列(以 LSC_TABLE_ADDR 為例)
# Step 1: 讀取目前值
$ devmem2 0x00140300 w
# 記錄 current_value

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

# Step 3: 寫入
$ devmem2 0x00140300 w $new_value

# Step 4: 驗證
$ devmem2 0x00140300 w
# 確認 bit[0] = 1,其餘 bit 不變

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

12.19 多層疑難排解決策樹

決策樹 1:暗角修正不足
1. 四角仍暗?
   ├─ LSC table 未載入 → 確認 LSC_TABLE_ADDR trigger bit
   └─ table 與 lens 不匹配 → 重新拍白板生成 table
2. 中心過亮(over-correction)?
   └─ LSC_STRENGTH 太高 → 降到 0x80–0xC0
決策樹 2:LSC table 生成失敗
1. 白板有陰影?
   ├─ 光源不均勻 → 用 diffuser 或 lightbox
   └─ 白板有紋路 → 用專業 white target
2. 四角量測值不合理?
   └─ ROI 選取不對 → 確認選在四角角落、避開邊緣 dark frame

12.20 量測驗證完整 SOP

LSC 完整校正與驗證 SOP:

步驟動作指令/方法預期輸出
Step 1拍攝白板均勻光源(lightbox),全畫面白色曝光不飽和
Step 2量測四角 + 中心ROI 各取 100×100 pixel 平均值記錄 DN 值
Step 3計算暗角比(center - corner) / center × 100%期望 < 20%
Step 4生成 LSC tableISP Visualizer 或腳本自動生成5×5 grid × 4 channels
Step 5載入 table寫入 LSC_TABLE_ADDR + triggertable 載入成功
Step 6驗證修正效果重拍白板,重複 Step 2四角差 < 5%
Step 7強度微調調 LSC_STRENGTH,找最佳值中心不過亮、四角不暗

12.21 四平台終極對照

面向Thor T5000RPi5Orange PiOrin Nano
LSC grid 大小5×5 × 4ch(可調)17×13(固定)N/A16×12(固定)
LSC table 生成ISP Visualizer(GUI)`raspistill` 以 12-bit 抓N/AISP Visualizer
LSC 強度控制N/A
自動 LSC 校正N/A
LSC + lens profilesN/A⚠️
驗證工具ColorChecker + 角落量測白板 DN 比較N/AColorChecker + 角落量測

12.22 完整 Bring-up 小 Checklist

針對「鏡頭陰影校正(LSC)」主題的完整 bring-up 步驟清單: