1. 從“看見”到“鎖定”一個電賽視覺系統(tǒng)的誕生記又到了一年一度電賽備賽的焦灼期看到不少同學(xué)在搜索“2023年電賽E題運(yùn)動目標(biāo)控制與自動追蹤系統(tǒng)——視覺部分以及總結(jié)”這個標(biāo)題。我猜你大概率是剛接觸電賽視覺題目或者正在為如何構(gòu)建一個穩(wěn)定可靠的追蹤系統(tǒng)而頭疼。這個標(biāo)題背后其實(shí)是一個典型的“感知-決策-控制”閉環(huán)問題而視覺部分就是整個系統(tǒng)的“眼睛”和“大腦”的前半部分。它不僅要能“看見”目標(biāo)更要能“看懂”目標(biāo)的運(yùn)動并把這份“理解”準(zhǔn)確、實(shí)時地傳遞給控制系統(tǒng)。回想起當(dāng)年帶隊(duì)做類似題目的經(jīng)歷從攝像頭選型、算法調(diào)試到與下位機(jī)的“愛恨情仇”每一步都充滿了挑戰(zhàn)。今天我就以2023年E題為引子拋開那些華而不實(shí)的報告模板和你深入聊聊一個能在電賽現(xiàn)場穩(wěn)定跑起來的視覺追蹤系統(tǒng)到底是怎么從零搭建起來的以及那些報告里不會寫的“坑”和“技巧”。2. 需求拆解E題視覺部分到底要我們做什么在動手寫一行代碼之前我們必須徹底吃透題目要求。2023年E題“運(yùn)動目標(biāo)控制與自動追蹤系統(tǒng)”這個名稱已經(jīng)點(diǎn)明了核心運(yùn)動目標(biāo)、控制與自動追蹤。視覺部分的核心任務(wù)就是為“控制”和“追蹤”提供感知輸入。2.1 核心功能定義根據(jù)題目共性我們可以將視覺部分的需求拆解為以下幾個硬性指標(biāo)目標(biāo)檢測與識別系統(tǒng)需要從攝像頭畫面中準(zhǔn)確找出特定的運(yùn)動目標(biāo)。這個目標(biāo)可能是一個特定顏色的球、一個帶有圖案的方塊、一輛小車甚至是題目規(guī)定的特定形狀物體。這里的關(guān)鍵詞是“準(zhǔn)確”和“特定”意味著我們需要過濾掉背景干擾。目標(biāo)定位僅僅找到目標(biāo)不夠還需要知道它在坐標(biāo)系中的精確位置。這通常包括二維像素坐標(biāo)(u, v)。對于追蹤系統(tǒng)我們往往更關(guān)心目標(biāo)在世界坐標(biāo)系或相對于云臺/車體坐標(biāo)系的位置。目標(biāo)測距如果涉及追蹤或攔截只知道方向不知道距離就是“睜眼瞎”。因此視覺系統(tǒng)需要估算目標(biāo)與攝像頭之間的距離d。這就引出了單目測距或雙目視覺的需求。運(yùn)動狀態(tài)估計既然是“運(yùn)動目標(biāo)”我們還需要知道它的速度大小和方向甚至預(yù)測其未來位置。這通常通過對連續(xù)幀間的位置變化進(jìn)行濾波如卡爾曼濾波來實(shí)現(xiàn)。數(shù)據(jù)輸出與通信視覺處理的結(jié)果位置、距離、速度等需要以穩(wěn)定、低延遲的格式發(fā)送給主控單片機(jī)如STM32、ESP32這是控制循環(huán)的起點(diǎn)。2.2 性能指標(biāo)與約束條件電賽環(huán)境是殘酷的你的算法不僅要在實(shí)驗(yàn)室的完美光照下工作更要適應(yīng)比賽現(xiàn)場可能出現(xiàn)的復(fù)雜情況實(shí)時性處理一幀圖像的時間必須遠(yuǎn)小于控制周期。如果控制周期是20ms那么視覺處理最好能在10ms內(nèi)完成留出時間給通信和控制計算。幀率FPS是硬指標(biāo)。魯棒性對光照變化晴天/陰天、開燈/關(guān)燈、目標(biāo)部分遮擋、背景顏色干擾等具備抗性。準(zhǔn)確性定位精度直接影響追蹤精度。像素級的誤差經(jīng)過坐標(biāo)轉(zhuǎn)換和測距模型后可能會被放大成厘米級的實(shí)際誤差。資源消耗視覺處理通常運(yùn)行在算力有限的嵌入式平臺如樹莓派、Jetson Nano甚至高性能MCU上算法必須在有限的計算資源和內(nèi)存下高效運(yùn)行。理解了這些我們才能有的放矢地進(jìn)行技術(shù)選型。3. 技術(shù)棧選型開源視覺庫的實(shí)戰(zhàn)分析與抉擇面對“視覺”二字新手最容易犯的錯就是盲目追求最前沿、最復(fù)雜的算法。在電賽有限的時間和資源下“合適”遠(yuǎn)比“先進(jìn)”重要。我們的核心目標(biāo)是在滿足性能要求的前提下選擇最簡單、最穩(wěn)定、最易調(diào)試的方案。3.1 方案對比OpenCV vs. 其他“輪子”這里有一個常見的誤區(qū)看到“視覺識別”就去搜“YOLO”、“深度學(xué)習(xí)”。對于2023年E題這類目標(biāo)明確、環(huán)境相對可控的賽題傳統(tǒng)計算機(jī)視覺方法基于顏色、形狀配合OpenCV往往是最優(yōu)解。特性O(shè)penCV (傳統(tǒng)方法)深度學(xué)習(xí) (如YOLO, SSD)專用視覺軟件 (如VisionMaster)開發(fā)速度極快。函數(shù)庫豐富樣例多調(diào)試直觀。慢。需要準(zhǔn)備數(shù)據(jù)集、訓(xùn)練模型、優(yōu)化部署周期長。快如果熟悉。圖形化配置但靈活性受限。運(yùn)行效率高。算法復(fù)雜度低易于在嵌入式平臺優(yōu)化。低。模型計算量大需要較強(qiáng)的GPU或NPU支持。取決于軟件和硬件通常針對工控機(jī)優(yōu)化。環(huán)境適應(yīng)性依賴特征設(shè)計。對光照、顏色變化敏感但可通過預(yù)處理增強(qiáng)魯棒性。較好。經(jīng)過充分訓(xùn)練后對復(fù)雜背景和形變有較好抗性。通常較好集成了多種濾波和增強(qiáng)算法。調(diào)試難度低。每一步處理結(jié)果二值化、輪廓都可實(shí)時顯示問題定位快。高。模型是黑盒調(diào)參學(xué)習(xí)率、錨框需要經(jīng)驗(yàn)問題定位困難。中。圖形化調(diào)試方便但底層邏輯不透明定制化難。電賽適用性★★★★★(目標(biāo)簡單、規(guī)則、實(shí)時性要求高)★★☆☆☆(除非題目目標(biāo)極其復(fù)雜如識別特定手勢、人臉)★★★☆☆(可能違反“禁止使用專用視覺軟件”的規(guī)則需仔細(xì)閱讀賽題要求)注意務(wù)必仔細(xì)閱讀當(dāng)年賽題規(guī)則有些賽題會明確禁止使用LabVIEW、VisionMaster等圖形化專用軟件要求必須基于編程實(shí)現(xiàn)。OpenCV是公認(rèn)的安全選擇。為什么我強(qiáng)力推薦OpenCV因?yàn)樗墓ぷ髁鞒滔瘛傲魉€”每一步你都能看見、能控制。顏色過濾不對調(diào)HSV閾值輪廓找不準(zhǔn)加個形態(tài)學(xué)操作位置抖動上個濾波器。這種“白盒”特性在電賽48小時極限調(diào)試中是無價之寶。深度學(xué)習(xí)更像“黑盒”比賽時模型一旦出問題幾乎沒有時間讓你重新訓(xùn)練。3.2 OpenCV核心流程拆解一個典型的基于OpenCV的運(yùn)動目標(biāo)追蹤流程如下這也是我們實(shí)現(xiàn)E題視覺部分的核心框架圖像采集從攝像頭讀取視頻流。預(yù)處理減小噪聲、增強(qiáng)目標(biāo)特征。包括高斯模糊、HSV轉(zhuǎn)換等。目標(biāo)提取通過顏色閾值inRange或背景減除法createBackgroundSubtractorMOG2將目標(biāo)從背景中分離得到二值圖像。形態(tài)學(xué)操作使用腐蝕erode和膨脹dilate消除噪點(diǎn)連接斷裂的目標(biāo)區(qū)域。輪廓查找使用findContours找到二值圖中的所有輪廓。輪廓篩選根據(jù)面積、寬高比、圓形度等幾何特征過濾掉非目標(biāo)輪廓。定位與計算對目標(biāo)輪廓求最小外接矩形或外接圓得到中心像素坐標(biāo)結(jié)合測距模型計算實(shí)際位置。運(yùn)動估計與濾波結(jié)合時間戳計算幀間位移得到速度使用卡爾曼濾波KalmanFilter平滑軌跡預(yù)測下一幀位置。數(shù)據(jù)輸出將計算得到的目標(biāo)狀態(tài)x, y, z, vx, vy通過串口/UDP發(fā)送給下位機(jī)。這個流程中的每一步都有大量可調(diào)參數(shù)和技巧直接決定了最終系統(tǒng)的性能。4. 核心環(huán)節(jié)實(shí)現(xiàn)從像素到真實(shí)世界的映射掌握了流程我們來深入最關(guān)鍵的兩個環(huán)節(jié)如何穩(wěn)定地找到目標(biāo)以及如何將像素坐標(biāo)轉(zhuǎn)換成對控制有意義的真實(shí)世界坐標(biāo)。4.1 目標(biāo)提取的穩(wěn)定性超越簡單的顏色閾值很多新手卡在第一步顏色閾值怎么調(diào)白天調(diào)好了晚上燈一開又識別不到了。實(shí)戰(zhàn)技巧一動態(tài)閾值或HSV通道分離不要只用固定閾值。對于光照變化可以采集一部分背景區(qū)域計算其HSV中V明度通道的平均值根據(jù)此動態(tài)調(diào)整目標(biāo)顏色的S飽和度和V的閾值范圍。更魯棒的做法是在HSV空間下H色調(diào)通道對光照相對穩(wěn)定。重點(diǎn)校準(zhǔn)H通道的范圍適當(dāng)放寬S和V的范圍。例如識別紅色球H范圍可能是[0, 10]和[160, 180]因?yàn)镠SV色調(diào)環(huán)是0-180S和V可以是[50, 255]和[50, 255]。實(shí)戰(zhàn)技巧二背景減除法應(yīng)對復(fù)雜背景如果背景顏色與目標(biāo)相近顏色閾值就會失效。這時可以考慮背景減除Background Subtraction。OpenCV的MOG2或KNN背景減除器可以學(xué)習(xí)背景模型將運(yùn)動的前景提取出來。這對于追蹤移動的小車或球非常有效但它對攝像頭抖動和光照突變敏感需要穩(wěn)定攝像頭。實(shí)戰(zhàn)技巧三多特征融合篩選找到輪廓后別只用一個面積過濾。結(jié)合多個特征像漏斗一樣層層篩選輪廓面積 某個最小值過濾噪點(diǎn)。輪廓面積 某個最大值過濾過大物體。輪廓的寬高比接近1如果是圓形或方形目標(biāo)。輪廓的圓形度4*pi*面積/周長^2接近1如果是球體。可選輪廓的凸性檢測。用代碼實(shí)現(xiàn)一個多條件篩選能極大提升抗干擾能力。import cv2 import numpy as np def find_target_contour(binary_image): contours, _ cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) target_contour None for cnt in contours: area cv2.contourArea(cnt) # 條件1: 面積過濾 if area 100 or area 5000: continue # 條件2: 外接矩形寬高比 x, y, w, h cv2.boundingRect(cnt) aspect_ratio w / float(h) if aspect_ratio 0.8 or aspect_ratio 1.2: # 假設(shè)目標(biāo)接近正方形 continue # 條件3: 圓形度 perimeter cv2.arcLength(cnt, True) if perimeter 0: continue circularity 4 * np.pi * area / (perimeter * perimeter) if circularity 0.7: # 圓形度閾值 continue # 通過所有篩選認(rèn)為是目標(biāo) target_contour cnt break return target_contour4.2 單目視覺測距原理與標(biāo)定實(shí)踐知道目標(biāo)在畫面的u, v坐標(biāo)后如何得到距離z這是實(shí)現(xiàn)追蹤的關(guān)鍵。雙目視覺精度高但復(fù)雜單目測足矣應(yīng)付多數(shù)電賽場景。其核心原理是相似三角形。原理簡述 假設(shè)我們有一個已知實(shí)際寬度為W(單位米) 的目標(biāo)比如一個邊長為15cm的方塊在圖像中檢測到的像素寬度為w(單位像素)。攝像頭的焦距f(單位像素) 可以通過標(biāo)定得到。那么根據(jù)相似三角形目標(biāo)到相機(jī)的距離d為d (W * f) / w實(shí)操步驟攝像頭標(biāo)定與測距實(shí)現(xiàn)攝像頭標(biāo)定獲取焦距 f打印一張棋盤格標(biāo)定板OpenCV自帶。用你的攝像頭從不同角度拍攝10-20張標(biāo)定板圖片。使用OpenCV的cv2.calibrateCamera函數(shù)進(jìn)行標(biāo)定可以得到相機(jī)的內(nèi)參矩陣K。其中K[0,0]和K[1,1]就是焦距fx和fy通常兩者接近取平均值即可。你還會得到畸變系數(shù)用于校正圖像。重要標(biāo)定時的圖像分辨率必須和實(shí)際使用時一致實(shí)際測距代碼示例import cv2 import numpy as np # 假設(shè)通過標(biāo)定得到焦距 f像素 focal_length 800 # 像素 # 已知目標(biāo)的實(shí)際寬度米 known_width 0.15 # 例如15cm的方塊 def calculate_distance(pixel_width): 根據(jù)檢測到的像素寬度計算距離 if pixel_width 0: return 0 distance (known_width * focal_length) / pixel_width return distance # 在主循環(huán)中找到目標(biāo)輪廓后計算其像素寬度 target_contour find_target_contour(binary_img) if target_contour is not None: x, y, w_pixel, h_pixel cv2.boundingRect(target_contour) distance calculate_distance(w_pixel) # 使用寬度或高度 print(f目標(biāo)距離: {distance:.2f} 米)避坑指南標(biāo)定板要平整拍攝時標(biāo)定板盡量平整角度多樣。焦距的單位標(biāo)定得到的焦距單位是像素不是毫米。這是因?yàn)槲覀冊趫D像平面像素坐標(biāo)系測量。目標(biāo)寬度需精確known_width的測量誤差會直接導(dǎo)致測距誤差。俯仰角影響上述公式假設(shè)攝像頭光軸與目標(biāo)平面垂直。如果存在俯仰角測距公式會更復(fù)雜需要考慮透視投影。對于電賽小車追蹤地面目標(biāo)如果攝像頭水平安裝這個假設(shè)基本成立。5. 提升追蹤性能濾波、預(yù)測與通信優(yōu)化得到每一幀的目標(biāo)位置和距離后原始數(shù)據(jù)往往是充滿噪聲和抖動的。直接把這些數(shù)據(jù)發(fā)給控制系統(tǒng)云臺或小車會瘋狂抖動。因此濾波和預(yù)測至關(guān)重要。5.1 卡爾曼濾波讓運(yùn)動“平滑”且“可預(yù)測”卡爾曼濾波Kalman Filter是運(yùn)動狀態(tài)估計的利器。它不僅僅是一個濾波器更是一個預(yù)測器。它根據(jù)系統(tǒng)模型目標(biāo)如何運(yùn)動和觀測值視覺檢測到的位置給出一個最優(yōu)估計。在追蹤中的簡單應(yīng)用 我們可以建立一個勻速運(yùn)動模型。狀態(tài)量包括位置(x, y)和速度(vx, vy)。即使我們的視覺只能觀測到位置卡爾曼濾波也能估計出速度并預(yù)測下一時刻的位置。這對于處理視覺檢測偶爾丟失遮擋、誤識別的情況非常有幫助。OpenCV中的簡易使用# 初始化卡爾曼濾波器 (狀態(tài)維度4: x, y, vx, vy; 觀測維度2: x, y) kalman cv2.KalmanFilter(4, 2) kalman.transitionMatrix np.array([[1,0,1,0], [0,1,0,1], [0,0,1,0], [0,0,0,1]], np.float32) # 勻速模型 kalman.measurementMatrix np.array([[1,0,0,0], [0,1,0,0]], np.float32) # 只能觀測位置 # 初始化狀態(tài)和協(xié)方差矩陣... kalman.statePost np.array([initial_x, initial_y, 0, 0], dtypenp.float32) # 在主循環(huán)中 if target_found: # 1. 預(yù)測 prediction kalman.predict() predicted_x, predicted_y prediction[0], prediction[1] # 2. 用當(dāng)前觀測值更新 measurement np.array([[current_x], [current_y]], dtypenp.float32) kalman.correct(measurement) # 使用 kalman.statePost 作為平滑后的最優(yōu)估計狀態(tài) else: # 目標(biāo)丟失只進(jìn)行預(yù)測使用預(yù)測值作為輸出 prediction kalman.predict() # 使用預(yù)測值直到目標(biāo)重新出現(xiàn)5.2 串口通信穩(wěn)定與效率的平衡視覺處理單元樹莓派等與主控MCU的通信串口UART是最常見、最可靠的方式。這里的關(guān)鍵是協(xié)議設(shè)計。不要發(fā)送字符串像“x:123,y:456\n”這樣的字符串解析慢、占用帶寬、容易出錯。應(yīng)該使用二進(jìn)制協(xié)議。一個簡單的二進(jìn)制幀結(jié)構(gòu)示例幀頭 (2字節(jié))數(shù)據(jù)長度 (1字節(jié))數(shù)據(jù)區(qū) (N字節(jié))校驗(yàn)和 (1字節(jié))幀尾 (2字節(jié))0xAA, 0x55Nx(4字節(jié)float), y, z, vx, vy...sum0x0D, 0x0APython端發(fā)送示例 (使用pyserial)import struct import serial ser serial.Serial(/dev/ttyUSB0, 115200, timeout1) def send_data(x, y, z, vx, vy): # 打包數(shù)據(jù)f表示4字節(jié)float data struct.pack(fffff, x, y, z, vx, vy) data_len len(data) checksum sum(data) 0xFF # 簡單求和校驗(yàn) frame b\xAA\x55 bytes([data_len]) data bytes([checksum]) b\x0D\x0A ser.write(frame)STM32端接收解析示例 (HAL庫)uint8_t rx_buffer[256]; uint8_t rx_index 0; enum {STATE_HEAD1, STATE_HEAD2, STATE_LEN, STATE_DATA, STATE_CHECKSUM, STATE_TAIL1} state STATE_HEAD1; void USART_IRQHandler() { uint8_t byte USART_ReceiveData(USART1); switch(state) { case STATE_HEAD1: if(byte 0xAA) state STATE_HEAD2; break; case STATE_HEAD2: if(byte 0x55) state STATE_LEN; else state STATE_HEAD1; break; case STATE_LEN: data_length byte; if(data_length sizeof(data)) { state STATE_HEAD1; break; } data_index 0; state STATE_DATA; break; case STATE_DATA: data[data_index] byte; if(data_index data_length) state STATE_CHECKSUM; break; case STATE_CHECKSUM: // 計算校驗(yàn)和并比較 if(checksum byte) state STATE_TAIL1; else state STATE_HEAD1; break; case STATE_TAIL1: if(byte 0x0D) state STATE_TAIL2; else state STATE_HEAD1; break; case STATE_TAIL2: if(byte 0x0A) { // 一幀完整接收解析data數(shù)組 parse_data(data); } state STATE_HEAD1; break; } }通信避坑點(diǎn)波特率匹配兩端波特率必須嚴(yán)格一致。流控制如果數(shù)據(jù)量大考慮啟用硬件流控RTS/CTS或軟件流控XON/XOFF防止緩沖區(qū)溢出。超時機(jī)制在STM32端如果一段時間沒收到完整幀應(yīng)重置狀態(tài)機(jī)防止錯幀。數(shù)據(jù)對齊確保發(fā)送和接收端對數(shù)據(jù)類型的解釋一致如float的字節(jié)序。6. 系統(tǒng)聯(lián)調(diào)與現(xiàn)場避坑指南當(dāng)視覺模塊單獨(dú)測試良好與下位機(jī)通信也正常后真正的挑戰(zhàn)——系統(tǒng)聯(lián)調(diào)才剛剛開始。以下是我從多次比賽中總結(jié)出的“血淚”經(jīng)驗(yàn)。6.1 延遲延遲延遲視覺追蹤系統(tǒng)的最大敵人是延遲。延遲由三部分構(gòu)成圖像采集延遲、處理延遲、通信延遲。診斷方法在視覺程序開頭和結(jié)尾打時間戳計算處理一幀的時間。同時讓下位機(jī)收到數(shù)據(jù)后立刻返回一個信號計算往返總延遲。優(yōu)化手段降低分辨率這是提升FPS最有效的方法。從1080p降到640x480處理速度可能提升數(shù)倍而精度損失在可控范圍內(nèi)。優(yōu)化算法避免在循環(huán)里進(jìn)行不必要的圖像復(fù)制、縮放。使用cv2.UMatOpenCL加速如果硬件支持。選擇高效攝像頭USB攝像頭有MJPEG、YUYV等格式MJPEG壓縮率高傳輸快但需要解碼。測試不同格式和驅(qū)動如V4L2下的性能。非阻塞式通信視覺程序發(fā)送數(shù)據(jù)不要等待ACK采用“發(fā)完即走”的方式避免通信阻塞處理循環(huán)。6.2 光照光照光照比賽現(xiàn)場的光照條件是不可控的。你可能在窗戶邊也可能在日光燈下。賽前準(zhǔn)備采集多種光照樣本在實(shí)驗(yàn)室模擬強(qiáng)光、弱光、頂光、側(cè)光、日光燈、自然光等條件錄制視頻。測試算法魯棒性用這些視頻離線測試你的視覺程序調(diào)整HSV閾值、預(yù)處理參數(shù)找到一個在各種光照下都能工作的“折中”參數(shù)集。準(zhǔn)備應(yīng)急方案寫一個簡單的自動曝光/白平衡調(diào)整函數(shù)或者在現(xiàn)場準(zhǔn)備一個可調(diào)亮度的補(bǔ)光燈如果規(guī)則允許。現(xiàn)場調(diào)試如果現(xiàn)場光照導(dǎo)致識別失敗不要慌。優(yōu)先調(diào)整HSV中的V明度通道閾值或者啟用直方圖均衡化cv2.equalizeHist來增強(qiáng)對比度。6.3 當(dāng)目標(biāo)丟失時邏輯恢復(fù)策略追蹤過程中目標(biāo)被短暫遮擋或識別失敗是常態(tài)。你的程序必須有健壯的恢復(fù)邏輯。預(yù)測引導(dǎo)如上文所述使用卡爾曼濾波的預(yù)測值作為臨時目標(biāo)位置繼續(xù)發(fā)送給下位機(jī)同時擴(kuò)大圖像搜索區(qū)域ROI。搜索模式如果連續(xù)多幀如10幀丟失視覺系統(tǒng)應(yīng)通知下位機(jī)進(jìn)入“搜索模式”例如云臺緩慢掃描同時視覺程序?qū)OI擴(kuò)大到全圖重新進(jìn)行全局搜索。狀態(tài)機(jī)管理在程序中實(shí)現(xiàn)一個簡單的狀態(tài)機(jī)如SEARCHING,TRACKING,LOST根據(jù)連續(xù)成功/失敗的幀數(shù)切換狀態(tài)不同狀態(tài)對應(yīng)不同的處理策略和參數(shù)。6.4 硬件與供電的“玄學(xué)”問題攝像頭供電不足USB攝像頭從樹莓派取電可能因供電不穩(wěn)導(dǎo)致畫面卡頓、掉幀。使用帶電源的USB HUB為攝像頭獨(dú)立供電。電磁干擾電機(jī)尤其是直流有刷電機(jī)驅(qū)動時會產(chǎn)生強(qiáng)烈電磁干擾可能影響攝像頭數(shù)據(jù)線或串口通信。做好屏蔽使用帶屏蔽層的USB線串口線使用雙絞線電源走線與信號走線分開。散熱樹莓派等開發(fā)板長時間高負(fù)荷運(yùn)行會發(fā)熱降頻導(dǎo)致處理速度變慢。加裝散熱片甚至小風(fēng)扇。7. 從視覺到控制閉環(huán)系統(tǒng)的協(xié)同設(shè)計視覺部分不是孤立的它的設(shè)計必須與控制系統(tǒng)緊密協(xié)同。坐標(biāo)系統(tǒng)一視覺輸出的坐標(biāo)必須是以云臺旋轉(zhuǎn)中心或車體中心為原點(diǎn)的坐標(biāo)系。這需要在安裝攝像頭時進(jìn)行測量和標(biāo)定手眼標(biāo)定。例如攝像頭在云臺上方10cm前方5cm那么視覺檢測到的目標(biāo)像素坐標(biāo)需要經(jīng)過平移轉(zhuǎn)換才能得到相對于云臺旋轉(zhuǎn)中心的坐標(biāo)。控制頻率匹配視覺的數(shù)據(jù)更新頻率如30Hz應(yīng)高于或等于控制器的頻率如50Hz。如果視覺頻率低控制器需要進(jìn)行插值。更常見的做法是控制器以固定頻率運(yùn)行每次控制周期讀取視覺的最新數(shù)據(jù)如果數(shù)據(jù)未更新則使用上一次的數(shù)據(jù)或預(yù)測值。數(shù)據(jù)有效性判斷控制器在收到視覺數(shù)據(jù)后應(yīng)先判斷其有效性例如通過校驗(yàn)和、數(shù)據(jù)范圍、置信度等。無效數(shù)據(jù)應(yīng)被丟棄控制器維持上一時刻的控制輸出或進(jìn)入安全模式。構(gòu)建一個運(yùn)動目標(biāo)追蹤系統(tǒng)視覺是起點(diǎn)也是難點(diǎn)。它要求你不僅懂圖像處理還要懂幾何、懂濾波、懂通信、懂硬件。這個過程沒有捷徑就是不斷地調(diào)試、測試、失敗、再調(diào)試。當(dāng)你看到云臺穩(wěn)穩(wěn)地鎖住運(yùn)動的小球或者小車精準(zhǔn)地駛向目標(biāo)時那種成就感是無與倫比的。希望這篇基于實(shí)戰(zhàn)經(jīng)驗(yàn)的梳理能幫你理清思路避開我們曾經(jīng)踩過的坑在電賽的戰(zhàn)場上搭建出一雙穩(wěn)定而銳利的“眼睛”。記住把復(fù)雜的問題分解把簡單的步驟做扎實(shí)勝利往往就在堅持調(diào)試的下一分鐘里。