[opencv]二維碼識別開發流程及問題復盤總結


 

項目復盤總結

開發需求:

在桌面機器人(向下俯視)攝像頭拍攝到的圖像中做條形碼識別與二維碼識別。

條形碼在圖像固定位置,二維碼做成卡片的形式在固定區域內隨意擺放。

開發環境及相關庫:ubuntu 18.04 + Clion + opencv4.1.0 + zxing + zbar

 

開發思路及識別流程:

攝像頭拍攝圖像分辨率為640*480

1. 圖像畫面還原校正

由於攝像頭(俯視)拍攝到的圖像存在線性的透視偏差,類似於車輛行駛的車道線,兩條相交的直線,因為透視效應直線向視距遠處集中。

此處采用透視變換還原圖像為正視圖,這里存在一個傾角計算的問題。

根據圖像分辨率與實際物體大小的比例進行計算,得出透視變換所需的四個基本點。

 

2. 抓取條形碼區域

由於識別條形碼的位置為固定,確定了矯正方式后,因此就有以下幾種方式將條形碼矯正回來。

(1)將截取的固定區域做透視變換區域

(2)將整個圖像畫面做透視變換區域,再做整個畫面的區域截取。

經過驗證,最終采用(2)方式,因為攝像頭出廠設置有相對誤差,不容易計算透視變換的四個基本點。

而針對整個畫面和實際圖像的比例可以基本確定,故通過(2)要優化(1)。缺點是透視變換的矩陣太大,會加長總時間。

 

3.抓取二維碼區域

由於二維碼卡片在整個畫面中的位置是隨機擺放的,同時二維碼卡片與畫面背景之間有嚴格的邊界。

因此考慮從二維碼卡片的輪廓入手,這是抓取卡片區域的大方向。

如何將二維碼輪廓與背景其他輪廓分開,這里涉及到比較針對性的預處理方式。

考慮以下幾種方式

(1)從Canny圖像中查找到的輪廓集合做面積和長寬比例限制上的篩選,調整相關參數,從而得出符合要求的二維碼區域

(2)針對查找的輪廓集合做多邊形擬合,卡片為四邊形區域,因此擬合頂點為4。

(3)在查找的輪廓中,根據二維碼的三個矩形區域做輪廓層級的hierarchy層級篩選

經過驗證,最終采用(2)方式,雖然(1)也能截取到二維碼區域,但卡片區域輪廓的包圍矩形無法修正透視變換后存在的形變拉伸,以及存在無法識別到旋轉傾斜角度過大的問題。

使用(2)方式的好處是,經過擬合后的四邊形輪廓可以直接得到卡片區域的四個角點。

但使用輪廓擬合方式也存在一定的問題,即擬合到的四邊形輪廓數量過多,實際上只需要一個。因此需要將多余的篩選掉。

同時四邊形輪廓的角點在輪廓集合內是無序的,因此需要根據需求,將四個角點進行與透視變換對應的排序。

照貓畫虎,根據排序好的四個角點代入到透視變換,得出校正正視圖。此處透視變換的參數,為了與二維碼的長寬比適應,透視變換的size長寬比設置為1:1

   

4.識別條形碼與二維碼

由於zxing和zbar庫在性能與識別率上各有千秋,總體來說在當前集成的環境中,zbar高於zxing,但zbar識別不到的部分能被zxing識別出來。

因此考慮使用zxing與zbar混合識別的方式,先走zbar后走zxing。

 

 

遇到的問題及相關解決方案:

1.硬件問題:攝像頭角度傾角過大

從而導致透視變換處理之后的圖像仍然達不到識別庫的要求。

解決方案:攝像頭硬件參數調校。

 

2.環境:光照問題

在強光照射下,二維碼的部分黑色區域由黑色轉變成綠色或紅色,造成一定程度上的失真。

解決方案:自適應亮度調節,亮度增強

 

3.圖像矯正本身的缺陷

透視變換的插值方式會在一定程度上造成圖像失真或增強不必要的白噪聲。

默認使用的是 INTER_LINEAR 方式,經測試驗證,INTER_CUBIC方式更加適合條形碼與二維碼在變換中的插值。

/***
* 默認插值方式 INTER_LINEAR = 1 雙線性插值
* INTER_NEAREST = 0最近鄰插值
* INTER_CUBIC = 2 三次樣條插值
* INTER_AREA = 3 區域插值.圖像放大時類似於線性插值,圖像縮小時可以避免波紋出現。
* INTER_LANCZOS4 = 4 使用8×8像素鄰域的Lanczos插值
* INTER_LINEAR_EXACT = 5 位精確雙線性插值
* INTER_MAX = 7 插值碼掩碼
* WARP_FILL_OUTLIERS = 8 標志,填充所有目標圖像像素。如果其中一些與圖像,設置為零
* WARP_INVERSE_MAP = 16 標志,反變換
*/



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM