(一)緒論
鑒於今年的特殊情況,相較於其他組別,視覺組算是比較幸運的。一是前期改進算法的過程無需依賴任何硬件平台的資源,線上即可完成;二是比賽時間的推遲留給我們大量的時間做前期的准備工作和仿真測試工作。所以今年視覺組的工作進展較為順利,能夠做到隨叫隨到,隨到隨調,隨調隨用。但就從線上答辯的效果來看,今年的准備工作做得還不夠到位,接下來我將從以上幾點來做詳細說明。
(二)自瞄算法思路和成果
較之於去年的代碼,今年的算法主要做了一下幾點改進:
1.預處理部分
算法的預處理部分參考了2019賽季深大自瞄算法的思路,即膨脹、與運算、膨脹。第一次膨脹針對目標顏色區域,目的是填充亮圈。與運算保證始終提取發光區域。第二次膨脹也是填充非閉合區域。這樣經預處理后的二值圖可用來做進一步的處理。
2.追蹤器部分
相較於去年的算法,今年增加了KCF追蹤器部分,具體思路是,上一幀識別目標后,將包圍目標裝甲的最小ROI送入KCF進行初始化,並在下一幀圖像的二倍於裝甲板大小的ROI中進行追蹤,進而得到目標裝甲。但在實際運行過程中發現,KCF的初始化和追蹤操作耗時較長,在有的情況下不僅不能起到提高運行時間的作用,反而還大大延長了處理時間。所以在之后的算法中,拋棄了之前的KCF追蹤器,即得到上一幀目標裝甲后,在下一幀圖像的二倍於當前當前裝甲坐標范圍內進行識別。事實證明,相對於追蹤器,這種縮小目標區域的方法更有利於提升代碼的執行效率。注意在這個過程中的坐標轉換關系。

追蹤效果圖
3.子彈下墜補償
今年代碼的子彈下墜補償直接在平移矩陣中進行,具體思路如下。

(選自北理珠視覺開源群討論圖)
其中射速由下位機通過串口發送。
4.卡爾曼濾波器
第一次有手寫卡爾曼濾波器的想法是在DJI攻城獅的逼乎上看到的這篇文章,介紹了卡爾曼濾波器在雲台控制中的應用。然后通過這篇文章了解到了手寫卡爾曼濾波器的可操作性。
為了從發送端平滑相關參數,也是便於下位機進行預測,參考opencv的官方庫自寫了卡爾曼濾波器。在將瞬時運動視作勻速運動的條件下,卡爾曼濾波器的狀態協方差不必做太多改動。代碼中利用卡爾曼濾波器只進行了yaw軸角度的濾波,經過理論仿真來看,濾波器在識別到目標的情況下可以穩定向下位機發送平滑的差值。但由於聯調時間太短,故實際效果還需進一步驗證。
下圖中藍色為當前實際值,橙色為卡爾曼濾波值,綠色為融合值。

5.solvePNP姿態解算
solvePNP算法進行姿態解算時,通常至少需要目標的三個頂點(這里是四個),為了更加精確的求出相關參數,代碼通過單獨求每個燈柱的頂點(底邊中心點)來作為裝甲板的頂點,大大提高了所得距離及pitch,yaw軸角度的精度。(以往總是以包圍裝甲區域的最小旋轉矩形的頂點作為裝甲區域的頂點。)測距精度3m內誤差<2cm

(三)算法理論仿真過程
在進行卡爾曼濾波器仿真的時候,采用了log4cplus日志庫,其可以方便的將代碼運行時的變量值實時的打印在終端或者輸出至文件,借助python的matplotlib工具可以將變量值繪制出來,進而可以更加直觀的觀察出濾波器的效果。唯一的不足是無法實時顯示,但具體實現算法也較為簡單,也可借助以上方法實現。也可模仿北理珠視覺組采用QT工具自制的上位機 :)
(四)算法存在的不足
即使今年算法在提高精度和運行速度方面做了很多改進,但最終的結果在某些地方還是差強人意。
1.SVM
就速度和訓練樣本及識別精度而言,SVM是性價比較高的算法之一。但隨着機器學習算法的不斷改進,有許多簡單的神經網絡也可甚至更好的完成不同特征的分類任務。並且SVM在實際運行過程中的的確確出現了很多誤識別問題,建議以后可根據實際效果更改相應分類算法。
2.自適應閾值
自適應閾值是一個老生長談的話題,自從去年賽季結束后,許多戰隊也都提出了這個問題,但具體的解決方法尚未有學校給出。自適應閾值分為兩個部分,一是相機的自適應曝光。海康相機的軟件曝光可以根據需要實時調節,但官方並沒有相應的算法對曝光效果進行評估,故要想完成相機曝光的閉環,需要自己根據識別效果進行考慮。其次是二值化的自適應閾值。二值化后的圖像才能作為有效信息進行進一步的處理 ,故挑選合適的閾值進行二值化對識別效果有很大的影響。這里建議參考2019賽季上交開源代碼中的大幅預處理部分。
3.先驗條件
這里的先驗條件是指判定燈柱和裝甲范圍的最終限制條件,先驗條件在代碼中多次出現,有些條件冗余重復,亟需更好的方法代替。有些長寬比的限制模棱兩可甚至相互矛盾,這都是由於在閉門造車時考慮不周,而在聯調是突發奇想產生的結果,希望能找到一個大一統的先驗條件,能夠考慮到所有的情況而不會出現遺漏。
4.多進程讀取海康威視相機問題
在剛開始嘗試多進程讀取海康威視相機時,出現了只能同時讀取一個相機圖像的問題,而且在CLION環境中多進程的DEBUG不易操作,所以直到最后也沒有發現到底時什么原因。而且子進程和父進程究竟是哪個先運行也不可預知。但要是換成普通USB相機則不會出現這個問題,所以這可能是海康相機內部進程與此出現了沖突,所以不建議直接多進程讀取海康相機圖像。
最后的解決方案是開辟了兩塊共享內存,使用兩個進程分別同時從兩塊共享內存中取出圖片,再分別進行處理,通過getppid()加以區分,根據不同的PID值通過串口發送不同的幀頭,使下位機區分是哪個相機的數據。這樣即保證了采集與處理圖像的速度,又保證了兩個進程互不干擾,互不影響。
(五)就線上評審的幾個問題產生的思考
線上評審給視覺組的只有兩個問題,也算是一個問題。即Q:怎樣提高神經網絡的泛化性能?
A:要提高神經網絡的泛化性能,主要從以下幾個方面考慮:
- 采用大數據集。特別是RoboMaster比賽中,如果只考慮整車識別,需要建立較大的數據集才能保證識別率(裝甲識別除外)。
- 適當寬范圍的超參數搜索。將每個參數的搜索范圍擴大,可在一定程度上降低陷入局部最優的概率。
- 選擇合適的dropout rate,使網絡不至於過擬合或者欠擬合
- 批歸一化&正則化
除此之外,利用opencv做適當預處理也可以達到事半功倍的效果。
(六)一些建議
- 目前重點的工作還是要建立實驗室自己的數據集,目前所有的算法還都局限在已有的公開數據集的基礎之上。並且各個高校都在逐漸完善自己的數據集(包括作戰機器人和雷達站),可見其必要性。在建立數據集的過程中應盡量注意周圍光線等環境條件。
- 圖片像素點的操作盡可能避免加減乘除,可使用opencv的查表操作代替。
- 這里提供一個反陀螺思路。可以通過多個裝甲板數據得到整車空間狀態(旋轉周期等),從而控制發彈做到反陀螺。這一過程需注意上下位機時間的同步性。
- 百度的AISTUDIO訓練數據集比實驗室服務器快很多,訓練時盡可能首先考慮能不能使用百度的AISTUDIO。使用方法舉例。
- 視覺算法應該做到自動控制發彈,但優先級不能高於操作手。
- 攝像頭標定使用Matlab Calibration工具箱比較好,具體做法見這篇教程。
- 涉及大量像素迭代操作的運算,能用opencvAPI就盡量避免自己寫,opencv的方法一般都會有加速處理。
(七)其他資料
[2] RM圓桌,如何擊打大風車
[3] RoboMaster視覺教程
[4] Windows下GIT管理工具
[5] log4plus日志工具使用
