境光傳感器與前饋LUT優(yōu)化機(jī)器視覺自動曝光收斂)
如果沒見過攝像頭模組上電瞬間那張“從黑到亮一點(diǎn)點(diǎn)爬”的畫面你可能很難理解我為什么為一顆幾十塊錢的環(huán)境光傳感器折騰了這么久。最近我在基于 STM32N6 的機(jī)器視覺產(chǎn)品上做圖像效果調(diào)優(yōu)被自動曝光AE的收斂延遲折磨得不輕。默認(rèn)的 AE 算法一幀一幀地讀取統(tǒng)計(jì)結(jié)果、迭代逼近目標(biāo)亮度在 30fps 下往往要花十幾幀才能讓畫面穩(wěn)定下來。這個時間在規(guī)格書里不會標(biāo)注但在實(shí)際產(chǎn)品上卻非常顯眼。我把外部的 OPT3001 環(huán)境光傳感器加進(jìn)來用一張前饋 LUT查找表把環(huán)境亮度直接翻譯成曝光參數(shù)的初始值效果立竿見影收斂時間從 15 幀以上被壓縮到一兩幀而且沒有犧牲過沖和穩(wěn)定性。這篇文章把整個方案的設(shè)計(jì)思路、標(biāo)定方法和踩坑過程完整記錄下來給同樣在做 ISP AE 相關(guān)項(xiàng)目的朋友一個參考。1. 先從那個讓我失眠的“第一幀”問題說起1.1 攝像頭模組點(diǎn)亮后的畫面為什么像呼吸燈大部分嵌入式平臺的 AE 流程是這樣的圖像傳感器輸出幾幀預(yù)覽圖像給 ISPISP 的 3A 統(tǒng)計(jì)模塊從圖像中提取亮度直方圖、區(qū)域平均亮度等數(shù)據(jù)AEC 算法基于這些統(tǒng)計(jì)結(jié)果計(jì)算新的曝光時間、增益和光圈值然后寫入傳感器或者 ISP 的曝光配置。這套流程從架構(gòu)上就決定了它是一個逐幀迭代的過程。如果上一次保存的參數(shù)正好和當(dāng)前光照環(huán)境差得很遠(yuǎn)——比如設(shè)備在暗光環(huán)境關(guān)機(jī)下次卻在白天陽光下開機(jī)或者相反——AE 只能從那個錯誤的起點(diǎn)開始一幀一幀地追最終形成肉眼可見的亮度爬坡。我之前用邏輯分析儀抓過 AE 的調(diào)整曲線在光照突然變化的時候曝光時間經(jīng)常呈現(xiàn)階梯式上升或下降。每一級臺階代表一幀的統(tǒng)計(jì)延遲。如果 AE 控制律的收斂系數(shù)設(shè)置得比較保守臺階會更多如果設(shè)計(jì)得激進(jìn)臺階又會變成過沖甚至振蕩。用反饋控制的語言來說這就是一個典型的閉環(huán)系統(tǒng)快速性和穩(wěn)定性之間存在天然矛盾而幀率又給整個環(huán)路增加了一個不可忽略的純延遲。在 STM32N6 上ISP 的統(tǒng)計(jì)引擎能力是很強(qiáng)的甚至可以輸出多路窗口統(tǒng)計(jì)但統(tǒng)計(jì)引擎只負(fù)責(zé)給反饋環(huán)路喂數(shù)據(jù)它不能改變反饋環(huán)路本身需要多幀迭代這個事實(shí)。想讓第一幀就接近正確曝光必須從“幀統(tǒng)計(jì)結(jié)果”這條路徑之外引入一條獨(dú)立于幀率、響應(yīng)更直接的前饋路徑。1.2 為什么“幾幀而已”在實(shí)際產(chǎn)品里是不可接受的可能有人覺得反正輸出端通常會做一個黑屏過渡或者 logo 動畫幾幀的收斂過程未必會被用戶感知。這種想法在 demo 演示上不一定錯但在真實(shí)產(chǎn)品場景里AE 收斂延遲帶來的問題往往比視覺上“多等一會兒”嚴(yán)重得多掃碼類和快速抓拍設(shè)備要求從觸發(fā)到出圖在幾百毫秒內(nèi)完成。AE 還在收斂抓到的就是廢圖。光伏巡檢無人機(jī)或移動機(jī)器人云臺轉(zhuǎn)向時光照會突變AE 如果跟不上后續(xù) AI 識別準(zhǔn)確率就會跳水。安防門鎖、可視對講這類設(shè)備開機(jī)首幀往往是最重要的畫面用戶不會給你 0.5 秒的“預(yù)熱”時間。如果是卷簾快門的傳感器在 AE 收斂過程中曝光時間和增益都在變化還會引入 banding 或 motion blur 的假象進(jìn)一步干擾調(diào)試判斷。我也是到了項(xiàng)目驗(yàn)收階段才發(fā)現(xiàn)單靠調(diào) AE 參數(shù)已經(jīng)沒有多少空間了。把收斂系數(shù)調(diào)大確實(shí)能讓收斂快一些但畫面容易在穩(wěn)定值附近來回抖動把步進(jìn)限制加嚴(yán)又會導(dǎo)致收斂變慢。當(dāng)時的對策是把 AE 的“目標(biāo)亮度窗口”放寬讓系統(tǒng)在亮度誤差不太大時提前宣布收斂但這種做法治標(biāo)不治本誤差一直存在。這里有一個關(guān)鍵反思如果外部傳感器能比圖像統(tǒng)計(jì)更早感知環(huán)境光照變化為什么還要讓 AE 算法在“黑暗”中一步步摸索2. 前饋 LUT 為什么能讓 AE“開局即正確”2.1 反饋與前饋的根本差異反饋控制的優(yōu)點(diǎn)是不需要精確建模也能把系統(tǒng)拉到目標(biāo)值代價是環(huán)路增益、延遲、穩(wěn)定性之間要做權(quán)衡。AE 正好是這樣一個系統(tǒng)輸入是環(huán)境光輸出是曝光參數(shù)反饋量是畫面統(tǒng)計(jì)亮度執(zhí)行器是曝光時間和增益。由于每次執(zhí)行都要等下一幀的統(tǒng)計(jì)結(jié)果反饋鏈路上天然存在至少一幀的純延遲再加上統(tǒng)計(jì)窗口本身也是基于上一幀的曝光參數(shù)算出來的這個延遲實(shí)際上不止一幀。在低幀率或者高分辨率場景下來回抖動尤其明顯。前饋控制則不依賴輸出反饋而是直接測量主要擾動。對 AE 來說這個主要擾動就是環(huán)境光照強(qiáng)度。如果在外部放一個環(huán)境光傳感器把光照強(qiáng)度測出來再通過某種映射關(guān)系直接生成對應(yīng)的曝光設(shè)置就能在圖像統(tǒng)計(jì)結(jié)果出來之前就完成大部分曝光調(diào)節(jié)。宏觀上看這相當(dāng)于把 AE 從“被動跟隨”變成了“主動預(yù)判”。當(dāng)然前饋并不完美。外部光傳感器感知的是環(huán)境光不是鏡頭正前方的實(shí)際反射光。一個深色物體和一個淺色物體在相同光照下所需曝光完全不同。所以前饋給出的曝光值只是“大概率正確的起點(diǎn)”精細(xì)的修正還要靠 AE 反饋閉環(huán)來完成。但這個起點(diǎn)極其重要——如果起點(diǎn)離目標(biāo)足夠近AE 只需要一兩幀就能進(jìn)入穩(wěn)定區(qū)收斂延遲自然不再是問題。2.2 OPT3001 這顆傳感器為什么合適OPT3001 是一顆很常見的環(huán)境光傳感器I2C 接口量程 0.01 lux 到 83000 lux典型應(yīng)用是手機(jī)、平板和智能照明。我選它主要看中幾點(diǎn)寬動態(tài)范圍。從月光到正午陽光都在一個量程內(nèi)不需要切換量程檔位。輸出標(biāo)準(zhǔn)化 lux 值。不需要自己做 ADC 到物理亮度的換算拿來就能用特別適合做 LUT 的輸入。功耗極低。連續(xù)測量模式只有不到 1mA如果按比較器模式加中斷觸發(fā)平均電流可以做到微安級別對電池類設(shè)備非常友好。可配置積分時間和比較器中斷模式。可以作為“光照等級變化事件”來觸發(fā) MCU 讀取避免盲目輪詢。也有朋友會問使用攝像頭傳感器自帶的 AE 統(tǒng)計(jì)不就行了為什么還要外掛一個傳感器答案是攝像頭本身的 AE 統(tǒng)計(jì)是圍繞圖像內(nèi)容的而圖像內(nèi)容在曝光不合適時是不準(zhǔn)確的比如嚴(yán)重欠曝時統(tǒng)計(jì)到的噪聲和暗電流會干擾判斷嚴(yán)重過曝時又可能被高光截?cái)唷M獠凯h(huán)境光傳感器的測量不依賴圖像內(nèi)容它永遠(yuǎn)以一個“旁觀者”的視角提供接近真實(shí)的環(huán)境亮度這正好是前饋需要的特性。2.3 一張 LUT 如何把光照值變成曝光參數(shù)前饋 LUT 從邏輯上就是一個映射關(guān)系輸入是 lux 值輸出是曝光時間和增益。舉個例子標(biāo)定完一張表后針對 1000 lux 的查表結(jié)果可能是“曝光時間 1/500s總增益 6dB”。這個結(jié)果不是拍腦袋定的而是由鏡頭 F 值、傳感器量子效率、ISP 目標(biāo)亮度等多個因素共同決定的。表怎么存也是工程細(xì)節(jié)。最直接的做法是離散化 lux 軸比如按每 1dB 或者每 10% 一個采樣點(diǎn)存一張稀疏表查詢時用線性插值補(bǔ)全。由于人眼和傳感器的亮度感知都接近對數(shù)通常我更喜歡把 lux 軸做對數(shù)化處理在 log 域內(nèi)均勻取點(diǎn)這樣 LUT 在低照度區(qū)域和日照區(qū)域的精度都會更均衡。具體插值方式后面第 4 節(jié)會講。這種前饋加反饋的混合結(jié)構(gòu)最理想的結(jié)果是環(huán)境光一旦變化OPT3001 的中斷觸發(fā)MCU 讀取 lux查表得到一組曝光參數(shù)直接寫成 AE 的起始值隨后 AE 從這個起始值出發(fā)繼續(xù)做閉環(huán)微調(diào)但因?yàn)槠鹗贾狄呀?jīng)很接近目標(biāo)AE 的收斂步長會被限制在很小的范圍內(nèi)畫面上幾乎看不出調(diào)節(jié)過程。3. 構(gòu)建一張能用的 LUT參數(shù)推導(dǎo)與標(biāo)定流程3.1 先從光學(xué)參數(shù)做理論計(jì)算LUT 不是空手建的第一步是理論推導(dǎo)。假設(shè)鏡頭光圈是 F/2.0傳感器響應(yīng)靈敏度為 S單位是 LSB/(lux·s)不同傳感器有差異圖像傳感器曝光時間 t增益 G則圖像亮度與場景亮度大致成正比。圖像目標(biāo)亮度 Y_target 通常設(shè)置為 1288bit Y 分量。根據(jù)典型相機(jī)模型Y ≈ K * L * A * S * t * G / (π * F^2)其中 K 是鏡頭透光率、遮擋等綜合系數(shù)。理論計(jì)算把中心值算出來后我會先在灰卡場景驗(yàn)證一遍再根據(jù)實(shí)測偏差修正系數(shù)。這個公式的意義不在于得到精確數(shù)值而是幫助理解當(dāng) lux 升高一倍時曝光時間或增益大致需要減少一半這個對數(shù)線性關(guān)系決定了 LUT 的基本形狀。在工程實(shí)現(xiàn)上我通常先算三個關(guān)鍵點(diǎn)低照度約 1~10 lux中等照度約 100~1000 lux高照度約 10000~80000 lux。這三個點(diǎn)的理論曝光值確定后中間點(diǎn)用對數(shù)插值生成然后再用實(shí)測樣本去修正。3.2 實(shí)測標(biāo)定的執(zhí)行步驟理論值只能作為初稿實(shí)際的像素響應(yīng)、鏡頭漸暈、IR 濾光片透過率都會讓理論曲線偏移。所以我會進(jìn)入標(biāo)定環(huán)節(jié)流程如下把一個已經(jīng)校準(zhǔn)的照度計(jì)放在 OPT3001 旁邊同時采集 OPT3001 的 lux 讀數(shù)。固定相機(jī)模組正對一個已知反射率的目標(biāo)比如 18% 灰卡保證畫面中央?yún)^(qū)域被目標(biāo)覆蓋。修改曝光時間或增益讓 ISP 統(tǒng)計(jì)引擎輸出的平均 Y 值落在 128 左右。記錄三組數(shù)據(jù)OPT3001 lux 讀數(shù)、曝光時間、總增益。改變環(huán)境光照覆蓋暗光、室內(nèi)、室外陰天、晴天重復(fù)步驟 2 到 4。下面是我在某次標(biāo)定中記錄的真實(shí)樣張參數(shù)標(biāo)定場景OPT3001 lux曝光時間總增益統(tǒng)計(jì)Y夜間暗室2.81/15s24dB126室內(nèi) LED 燈1181/60s9dB130辦公室窗邊8501/250s3dB127室外陰天41001/500s0dB125室外正午320001/2000s0dB128表格里的每一行在 LUT