戰(zhàn):攝像頭圖像識別與實(shí)時(shí)處理鏈路解析)
第21屆智能車競賽結(jié)束之后我們隊(duì)里最值得單獨(dú)復(fù)盤的就是“走馬觀碑”這個(gè)環(huán)節(jié)。名字聽起來有點(diǎn)文藝實(shí)際比賽里它就是一段需要車在快速行駛過程中完成“看內(nèi)容、做判斷”的賽道挑戰(zhàn)。我們在它身上投入的時(shí)間比預(yù)想多了一倍踩過的坑從硬件安裝到圖像處理都有最終成績不算出彩但整套流程的教訓(xùn)很值得寫下來。如果你正在準(zhǔn)備下一屆智能車競賽或者關(guān)注攝像頭組的圖像處理和實(shí)時(shí)識別方案這篇文章會從我們的視角拆解完整備賽過程規(guī)則怎么讀、硬件怎么選、圖像鏈路怎么搭、參數(shù)怎么調(diào)、現(xiàn)場怎么避免翻車。同時(shí)也會把那些“看起來不起眼、但直接導(dǎo)致失誤”的細(xì)節(jié)單獨(dú)提出來。1. 走馬觀碑不只是“識別一塊牌子”它是一個(gè)完整的時(shí)序任務(wù)1.1 這個(gè)環(huán)節(jié)在賽道上的實(shí)際形態(tài)走馬觀碑這個(gè)環(huán)節(jié)按照字面意思理解就是“車跑過去順便看完碑上的內(nèi)容”。放到賽道里就是賽道旁邊會放置一塊帶有特定標(biāo)記或文字的標(biāo)識牌車從它前面經(jīng)過時(shí)需要通過攝像頭采集畫面在行駛過程中完成識別然后根據(jù)識別結(jié)果決定后續(xù)動作。這個(gè)動作聽起來簡單但放在比賽場景里難度完全不一樣。首先車是運(yùn)動的不是靜止對著牌子拍其次識別結(jié)果必須在有效時(shí)間窗口內(nèi)送達(dá)控制邏輯否則車已經(jīng)沖過去了識別出來也沒有意義。很多隊(duì)伍第一次接觸這個(gè)環(huán)節(jié)時(shí)容易把重點(diǎn)放在“識別準(zhǔn)確率”上。但實(shí)際測下來真正拉開差距的并不是離線識別誰更準(zhǔn)而是整個(gè)鏈路的響應(yīng)速度。圖像采集、目標(biāo)定位、內(nèi)容識別、結(jié)果輸出、控制動作這一整套流程能不能在幾十毫秒內(nèi)完成才是核心。1.2 三種能力是考核重點(diǎn)從我自己的理解來看走馬觀碑至少同時(shí)考核了三層能力。第一層是感知能力。攝像頭能不能在弱光、強(qiáng)光、逆光等環(huán)境下穩(wěn)定看到標(biāo)志牌畫面里有沒有反光、過曝、運(yùn)動模糊。感知層的失誤是后面的識別算法無論如何都彌補(bǔ)不了的。第二層是處理能力。采集到畫面之后能不能在有限的計(jì)算資源里完成目標(biāo)區(qū)域提取和內(nèi)容識別。這對主控芯片的算力、圖像處理的算法效率都是直接考驗(yàn)。第三層是整車協(xié)同能力。識別結(jié)果拿到之后車要不要減速、要不要避讓、要不要切換路徑這些動作要在什么時(shí)候觸發(fā)、以什么優(yōu)先級執(zhí)行同樣需要花時(shí)間設(shè)計(jì)和測試。很多隊(duì)伍在賽前測試時(shí)只驗(yàn)證了“能識別”沒有驗(yàn)證“識別之后車該干嘛”。到了比賽現(xiàn)場才發(fā)現(xiàn)識別出來了但沒有觸發(fā)有效動作或者動作執(zhí)行得太晚直接被判失敗。這是我在賽后總結(jié)里最想強(qiáng)調(diào)的是走馬觀碑本質(zhì)上是一個(gè)完整的時(shí)序任務(wù)不只是圖像識別單點(diǎn)任務(wù)。1.3 這個(gè)環(huán)節(jié)最容易出現(xiàn)的理解偏差備賽期間我們最大的理解偏差是把走馬觀碑當(dāng)作“一個(gè)需要識別的靜態(tài)目標(biāo)”。一開始我們的測試方式是讓車停在標(biāo)志牌前拍照識別確認(rèn)結(jié)果正確就算通過。這個(gè)測試方式給了我們一種虛假的安全感。離線測試環(huán)境下曝光穩(wěn)定、畫面靜止、目標(biāo)居中識別率當(dāng)然高。但真正跑起來之后運(yùn)動模糊、視角變化、光照變化、車體震動每個(gè)因素都會讓識別效果明顯下降。正確的做法應(yīng)該是從一開始就模擬實(shí)際工況讓車以目標(biāo)速度從標(biāo)志牌旁邊經(jīng)過用行車記錄數(shù)據(jù)回放檢查每一幀圖像的質(zhì)量、識別結(jié)果和動作觸發(fā)時(shí)間。先讓測試環(huán)境接近比賽環(huán)境再談?wù){(diào)優(yōu)。2. 賽前硬件方案直接把難度分成了兩個(gè)等級2.1 攝像頭和灰度的分工不能只按慣性選智能車競賽里攝像頭組和灰度組的選擇一直是討論重點(diǎn)?;叶葌鞲衅髟诰€搜索、邊界檢測等方面簡單直接處理速度也快但面對走馬觀碑這種需要看“內(nèi)容”的環(huán)節(jié)純灰度幾乎是做不了的。我們的方案是攝像頭為主灰度陣列為輔。攝像頭負(fù)責(zé)前瞻、目標(biāo)檢測和內(nèi)容識別灰度負(fù)責(zé)近距離的賽道線跟蹤和位置修正。這樣一個(gè)組合的好處是冗余度高高速行駛時(shí)攝像頭畫面可能出現(xiàn)短暫異?;叶葦?shù)據(jù)還能兜底保證車不沖出賽道。如果你決定做攝像頭為主要感知手段建議優(yōu)先關(guān)注這幾個(gè)參數(shù)全局快門比卷簾快門更適合運(yùn)動場景畫面變形更小。動態(tài)范圍要夠大否則順光和逆光切換時(shí)畫面容易全黑或全白。幀率至少 60 幀以上否則高速行駛時(shí)目標(biāo)很容易漏檢。我們一開始用的是卷簾快門攝像頭靜止拍攝沒問題車一跑起來畫面就出現(xiàn)明顯的果凍效應(yīng)標(biāo)志牌上的內(nèi)容被拉變形識別率直接掉了一截。換到全局快門之后這個(gè)問題才基本解決。2.2 主控算力是識別方案的硬約束走馬觀碑對主控的要求比普通搜線任務(wù)高不少。如果只做賽道線檢測很多單片機(jī)能勝任但要在圖像里做目標(biāo)定位和內(nèi)容匹配算力不夠的話幀率會掉得非常明顯。我們隊(duì)伍當(dāng)時(shí)在兩種平臺之間猶豫一種是傳統(tǒng) MCU 加簡單的模板匹配另一種是上輕量級處理器跑小型分類網(wǎng)絡(luò)。最后考慮到調(diào)試周期和穩(wěn)定性選擇了 MCU 平臺識別方案用模板匹配加簡單特征判斷。比賽圈子里也有隊(duì)伍用了 RISC-V 平臺比如熱詞里出現(xiàn)的 CH32V307VCT6它在主頻和外設(shè)配置上確實(shí)有性價(jià)比優(yōu)勢但最終表現(xiàn)還是取決于具體任務(wù)的開銷。這里給一個(gè)很實(shí)在的建議選平臺之前先估算你的識別算法在目標(biāo)幀率下的計(jì)算量。如果你預(yù)期識別一幀畫面需要 30ms而圖像采集幀率是 60fps每幀只有約 16ms 時(shí)間那就算力不夠。這個(gè)矛盾不是靠優(yōu)化一兩處代碼能解決的很可能需要換方案或者降幀率。2.3 攝像頭安裝位置決定“能看到的距離”硬件方案里最容易被低估的是攝像頭安裝參數(shù)。我們第一版方案把攝像頭裝得太低導(dǎo)致標(biāo)志牌進(jìn)入畫面的時(shí)間很短扣除識別耗時(shí)之后留給控制動作的余量幾乎沒有。后來把安裝高度提高、鏡頭傾角調(diào)大標(biāo)志牌在畫面里出現(xiàn)的時(shí)間提前了將近一倍整個(gè)鏈路才有了足夠的緩沖。安裝參數(shù)不是一個(gè)固定值它取決于標(biāo)志牌距離賽道邊緣多遠(yuǎn)標(biāo)志牌的高度和尺寸車的最高行駛速度識別算法需要多少有效像素我們的做法是先在實(shí)驗(yàn)室模擬賽道的擺放位置然后以不同速度跑車截取行車畫面觀察標(biāo)志牌在每一幀里的位置和大小再反推安裝高度和視角。這個(gè)流程比較笨但是有效。不要憑感覺定安裝參數(shù)一定要拿實(shí)際畫面驗(yàn)證。3. 圖像識別鏈路怎么搭從采集到動作每一步都有取舍3.1 曝光設(shè)置固定曝光還是自動曝光在運(yùn)動場景里自動曝光不一定是好選擇。因?yàn)檐囋谛旭傔^程中畫面內(nèi)容不斷變化自動曝光會根據(jù)整體亮度頻繁調(diào)整參數(shù)導(dǎo)致標(biāo)志牌區(qū)域的亮度不穩(wěn)定。我們最終用了固定曝光。做法是在不同光照條件下采集多組樣本選一個(gè)能讓賽道線和標(biāo)志牌都清晰可見的曝光值。這樣做的缺點(diǎn)是對環(huán)境變化的適應(yīng)能力差但優(yōu)點(diǎn)是非常穩(wěn)定圖像亮度不會突然跳變后續(xù)處理算法的輸入不會劇烈變化。這個(gè)取舍需要根據(jù)比賽場地情況判斷。如果場地光照穩(wěn)定固定曝光是首選如果場地有頂光、側(cè)光、強(qiáng)光源等多種情況可以設(shè)置兩三套曝光參數(shù)根據(jù)畫面整體亮度動態(tài)切換而不是每幀都自動調(diào)整。3.2 ROI 區(qū)域提取別在整幅圖上做識別識別標(biāo)志牌內(nèi)容時(shí)最常見的錯(cuò)誤是先對整幅圖做處理再做內(nèi)容識別。這樣不僅浪費(fèi)算力還會引入大量無關(guān)信息降低識別穩(wěn)定性。正確的流程是先做目標(biāo)檢測在畫面中定位標(biāo)志牌所在的區(qū)域也就是 ROIRegion of Interest然后只對 ROI 內(nèi)的圖像做識別內(nèi)容處理。ROI 提取可以基于幾種線索標(biāo)志牌通常有明顯邊框或底色和賽道背景差異較大標(biāo)志牌的位置相對賽道是固定的可以根據(jù)賽道線位置推測ROI的大致范圍用簡單的顏色閾值或灰度閾值先粗篩再做連通域判斷確定 ROI 之后需要在里面找到標(biāo)志牌的具體位置、大小和旋轉(zhuǎn)角度再做矯正。這樣識別內(nèi)容時(shí)目標(biāo)是正對鏡頭的不會因?yàn)檐嚇?biāo)牌夾角過大導(dǎo)致字符變形。3.3 識別算法模板匹配在小樣本場景里夠用我們最后用的是模板匹配加簡單特征比較。這個(gè)方案在離線測試中識別率大概在 95% 左右但實(shí)際跑起來會低一些原因是運(yùn)動模糊和角度偏差。如果你要識別的標(biāo)志牌內(nèi)容是固定的幾種模板匹配確實(shí)夠用。做法是提前在實(shí)驗(yàn)室采集好每類標(biāo)志牌的標(biāo)準(zhǔn)圖像提取特征信息比賽時(shí)拿 ROI 內(nèi)圖像做歸一化比對選擇相似度最高的作為識別結(jié)果。如果標(biāo)志牌內(nèi)容不固定比如包含數(shù)字、字母、漢字的組合模板匹配就不夠靈活了。這時(shí)需要考慮小型分類網(wǎng)絡(luò)或者特征識別方案。但這里要注意引入模型之后對主控算力的要求會顯著上升調(diào)試難度也會增加。先評估你需要的識別規(guī)模再決定要不要上模型。3.4 識別結(jié)果怎么影響控制邏輯識別完成之后最關(guān)鍵的事情是“拿結(jié)果去干嘛”。我們在前期設(shè)計(jì)了一個(gè)簡單的狀態(tài)機(jī)狀態(tài)一正常行駛持續(xù)搜索標(biāo)志牌狀態(tài)二檢測到標(biāo)志牌進(jìn)入識別流程狀態(tài)三識別完成根據(jù)結(jié)果決定減速、停車或變道狀態(tài)四動作執(zhí)行完成恢復(fù)正常行駛這個(gè)狀態(tài)機(jī)的核心是觸發(fā)時(shí)機(jī)。狀態(tài)二必須在標(biāo)志牌進(jìn)入可識別范圍的最早時(shí)刻觸發(fā)給狀態(tài)三和狀態(tài)四留出足夠的執(zhí)行時(shí)間。我們的經(jīng)驗(yàn)是寧可提前誤觸發(fā)也不要延后正確觸發(fā)。提前誤觸發(fā)可以靠后續(xù)幀修正延后觸發(fā)則直接錯(cuò)過有效窗口。4. 實(shí)測調(diào)參速度、穩(wěn)定性和識別率怎么平衡4.1 從 0.5m/s 開始逐步提速整個(gè)備賽期間我們調(diào)參的順序是先把速度降到 0.5m/s 左右保證每次經(jīng)過都能穩(wěn)定識別。然后以 0.2m/s 的間隔逐步提速每提高一檔都跑至少 10 次統(tǒng)計(jì)識別率和動作觸發(fā)率。這個(gè)過程很枯燥但非常重要。因?yàn)椴煌俣认逻\(yùn)動模糊和視角變化對識別結(jié)果的影響差別很大。高速時(shí)能識別的方案低速時(shí)不一定會失敗反過來低速時(shí)穩(wěn)定的方案高速后很可能出現(xiàn)識別延遲。關(guān)鍵是記錄每一檔速度下的數(shù)據(jù)識別率、平均耗時(shí)、動作觸發(fā)延遲、失敗時(shí)的畫面特征。這樣即使后面改了參數(shù)也能快速判斷是變好了還是變差了。4.2 曝光、閾值、ROI 要聯(lián)動調(diào)整走馬觀碑的調(diào)參過程中最容易出問題的是“只調(diào)一個(gè)參數(shù)”。比如發(fā)現(xiàn)畫面對比度不夠就調(diào)二值化閾值調(diào)完之后發(fā)現(xiàn)賽道線檢測出了問題又去改灰度閾值改完閾值標(biāo)志牌的 ROI 定位又偏了。這類問題本質(zhì)上是圖像處理鏈路里各環(huán)節(jié)相互耦合。曝光變了灰度分布變了二值化閾值需要跟著變閾值變了目標(biāo)區(qū)域分割結(jié)果變了ROI 定位也會受影響。我們的做法是把參數(shù)分為兩組第一組曝光、增益、伽馬這類參數(shù)影響圖像整體質(zhì)量第二組二值化閾值、ROI 上下邊界、模板匹配相似度閾值這類參數(shù)影響識別結(jié)果調(diào)整時(shí)先穩(wěn)定第一組再調(diào)第二組。第一組參數(shù)不穩(wěn)定的情況下盲目調(diào)第二組只會越調(diào)越亂。4.3 連續(xù)測試 30 次才算真正驗(yàn)證過很多隊(duì)伍在賽前測試時(shí)只跑三五次看到識別成功就覺得方案沒問題。但走馬觀碑這種場景單次成功的參考價(jià)值非常有限。建議至少連續(xù)跑 30 次統(tǒng)計(jì)以下數(shù)據(jù)成功識別次數(shù)和失敗次數(shù)失敗時(shí)是檢測不到、識別錯(cuò)誤還是動作執(zhí)行失敗每次識別耗時(shí)是否有明顯波動第 10 次、第 20 次、第 30 次的識別表現(xiàn)是否一致連續(xù)測試的真正價(jià)值在于暴露間歇性問題。有些問題不是每幀都發(fā)生而是每隔十幾次出現(xiàn)一次比如某幀畫面輕微過曝、某次車體震動導(dǎo)致目標(biāo)偏移。單次測試基本看不到這些問題。4.4 一個(gè)具體翻車案例順光變逆光我們在一次模擬比賽中遇到過一個(gè)典型問題。上午測試時(shí)場地是順光標(biāo)志牌區(qū)域亮度充足ROI 提取非常穩(wěn)定。下午換到另一個(gè)場地測試光線變成逆光標(biāo)志牌區(qū)域被背景光壓暗灰度閾值又沒來得及調(diào)整識別直接失敗。這個(gè)問題的根源是曝光和閾值都依賴具體環(huán)境而比賽場地往往是未知的。我們的補(bǔ)救辦法是在正式比賽前預(yù)留至少半天時(shí)間針對比賽場地的光照條件重新標(biāo)定曝光和閾值。同時(shí)在代碼里加入一鍵校準(zhǔn)功能讓車在發(fā)車區(qū)自動采集幾幀背景亮度動態(tài)調(diào)整曝光參數(shù)減少人工介入。這個(gè)功能雖然不能完全解決光線變化問題但至少能把“完全依賴現(xiàn)場手動調(diào)參”的風(fēng)險(xiǎn)降低不少。5. 比賽現(xiàn)場容易忽略的四個(gè)細(xì)節(jié)5.1 場地光線和背景比想象中復(fù)雜比賽場地的燈光結(jié)構(gòu)、地面材質(zhì)、周圍環(huán)境都會影響圖像質(zhì)量。有些場地是深色地毯有些是淺色地面有些會反光。這些因素在賽前測試時(shí)無法完全預(yù)知。建議進(jìn)場后第一時(shí)間用手持?jǐn)z像頭或者車上的攝像頭采集一段視頻在調(diào)參軟件里回放先看畫面整體亮度和對比度再決定是否需要調(diào)整曝光和閾值。不要等到發(fā)車前一分鐘才改參數(shù)。5.2 電池電壓變化會影響車速一致性電池從滿電到低電量輸出電壓會逐步下降電機(jī)驅(qū)動能力隨之減弱。如果賽前用滿電狀態(tài)調(diào)好車速而正式比賽時(shí)電量只剩一半車速和加速特性都會發(fā)生變化識別結(jié)果也可能因此出現(xiàn)差異。解決辦法是在正式發(fā)車前做一次快速測試確認(rèn)當(dāng)前電量下車的實(shí)際速度與調(diào)參時(shí)一致。如果速度偏差明顯需要在策略里預(yù)留速度補(bǔ)償或者提前慢一點(diǎn)優(yōu)先保證識別穩(wěn)定。5.3 現(xiàn)場調(diào)試時(shí)的干擾問題比賽現(xiàn)場通常有大量無線設(shè)備、對講機(jī)、調(diào)試工具這些可能對車載控制電路造成干擾。我們遇到過一接近其他隊(duì)伍的調(diào)試區(qū)域車上攝像頭畫面就出現(xiàn)條紋的情況。提前準(zhǔn)備措施電源線盡量短而粗、傳感器信號線使用屏蔽線、在主控和電機(jī)驅(qū)動之間做好隔離。如果現(xiàn)場出現(xiàn)畫面干擾先檢查是否是共地或電源紋波問題而不是馬上懷疑算法。5.4 規(guī)則判罰的實(shí)際執(zhí)行標(biāo)準(zhǔn)每個(gè)賽區(qū)的執(zhí)行標(biāo)準(zhǔn)可能不完全一致比如標(biāo)志牌區(qū)域是否允許壓線、識別失敗是否可以重試。這些細(xì)節(jié)直接影響比賽策略。我們的經(jīng)驗(yàn)是賽前把規(guī)則文件里關(guān)于走馬觀碑的描述抄出來逐條讀標(biāo)注出所有“必須”“不得”“允許”的詞然后針對每一條準(zhǔn)備對應(yīng)的技術(shù)方案。不要只看別人轉(zhuǎn)述的規(guī)則解讀一定要回到原始規(guī)則文件。6. 賽后復(fù)盤成績之外真正值得留下的經(jīng)驗(yàn)6.1 能跑通和能拿成績是兩回事這次比賽讓我們深刻體會到能跑通走馬觀碑只是及格線。真正決定名次的是整個(gè)識別鏈路的穩(wěn)定性連續(xù)跑 30 次不失敗對未知場地的適應(yīng)能力換場地后不用大改參數(shù)現(xiàn)場調(diào)試效率五分鐘內(nèi)完成參數(shù)校準(zhǔn)這三項(xiàng)能力都需要在備賽階段刻意訓(xùn)練不是靠賽前突擊就能解決的。我們這次在穩(wěn)定性上花的時(shí)間不夠現(xiàn)場調(diào)試時(shí)明顯手忙腳亂。如果再來一次我會把至少一半的備賽時(shí)間放在連續(xù)測試和場地適應(yīng)性測試上。6.2 測試記錄比代碼本身更重要比賽結(jié)束后翻看我們的測試記錄才發(fā)現(xiàn)很多問題其實(shí)早就出現(xiàn)過只是當(dāng)時(shí)沒有記錄下來。比如某次測試中識別成功率只有 60%我們當(dāng)時(shí)以為只是臨時(shí)干擾沒有深究。后來問題反復(fù)出現(xiàn)才發(fā)現(xiàn)是攝像頭某個(gè)固定參數(shù)設(shè)置不合理。如果從一開始就記錄每次測試的環(huán)境、參數(shù)、成功率和失敗畫面很多問題可以提前兩周解決而不是拖到賽前連夜查原因。建議從備賽第一天就建立測試記錄文檔內(nèi)容包括日期、場地條件、燈光情況、電池電量、參數(shù)版本、測試次數(shù)、成功率、失敗截圖、備注。這個(gè)文檔不僅是排查工具也是賽后總結(jié)的重要素材。6.3 給下一屆隊(duì)伍的三條具體建議如果只能留三句話給下一屆隊(duì)伍我會說第一走馬觀碑不是單點(diǎn)識別任務(wù)而是一個(gè)由感知、處理、控制組成的時(shí)序鏈路。從第一天開始就按完整鏈路設(shè)計(jì)測試不要拆開來單測。第二硬件安裝參數(shù)直接影響整個(gè)鏈路的上限。攝像頭高度、角度、鏡頭選擇、主控算力這些在項(xiàng)目初期就要認(rèn)真驗(yàn)證不要等到中后期再推倒重來。第三穩(wěn)定性的優(yōu)先級高于極限速度。在高速下能穩(wěn)定識別 30 次比在極限速度下偶爾成功一次有價(jià)值得多。比賽比的不是誰的單圈極限最快而是誰在多變環(huán)境中失誤更少。這次走馬觀碑的參賽經(jīng)歷拋開最終成績不談?wù)麄€(gè)過程讓我們把圖像處理、實(shí)時(shí)識別、整車系統(tǒng)集成這些知識點(diǎn)真正串了起來。備賽過程中積累的調(diào)試方法、參數(shù)調(diào)整思路、現(xiàn)場應(yīng)變流程才是這次比賽最值得留下的東西。