您好,登錄后才能下訂單哦!
基于谷歌街景多位數字識別技術的TensorFlow的車牌號識別系統是怎樣的,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
過去幾周我一直在涉足深度學習領域,尤其是卷積神經網絡模型。最近,谷歌圍繞街景多位數字識別技術發布了一篇不錯的paper。該文章描述了一個用于提取街景門牌號的單個端到端神經網絡系統。然后,作者闡述了基于同樣的網絡結構如何來突破谷歌驗證碼識別系統的準確率。 為了親身體驗神經網絡的實現,我決定嘗試設計一個可以解決類似問題的系統:車牌號自動識別系統。設計這樣一個系統的原因有3點:
我應該能夠參照谷歌那篇paper搭建一個同樣的或者類似的網絡架構:谷歌提供的那個網絡架構在驗證碼識別上相當不錯,那么講道理的話,用它來識別車牌號應該也會很給力。擁有一個知名的網絡架構將會大大地簡化我學習CNNs的步驟。
我可以很容易地生成訓練數據。訓練神經網絡存在一個很大的問題就是需要大量的標簽樣本。通常要訓練好一個網絡就需要幾十萬張標記過的圖片。僥幸的是,由于UK車牌號相對一致,所以我可以合成訓練數據。
好奇心。傳統的車牌號自動識別系統依賴于自己編寫算法來實現車牌定位,標準化,分割和字符識別等功能。照這樣的話,實現這些系統的代碼可能達到上千行。然而,我比較感興趣的是,如何使用相對較少的代碼和最少的專業領域知識來開發一個不錯的系統。
開發該項目的環境要求有Python,Tensorflow,OpenCV和NumPy等軟件。源代碼在這里。
為了簡化生成的訓練圖片,減少計算量,我決定該網絡可操作的輸入圖片為128*64的灰度圖。
選用128*64分辨率的圖片作為輸入,對于基于適當的資源和合理的時間訓練來說足夠小,對于車牌號讀取來說也足夠大。
為了在更大的圖片中檢測車牌號,采用了一個多尺度的滑窗來解決。
右邊的圖片是神經網絡的輸入圖片,大小為128*64,而左邊的圖片則展示了在原始輸入圖片的上下文中的滑窗。
對于每個滑窗,網絡都會輸出:
輸入圖片中存在車牌的概率。(上邊動畫所顯示的綠框)
每個位置上的字符的概率,比如針對7個可能位置中的每一個位置,網絡都應該返回一個貫穿36個可能的字符的概率分布。(在這個項目中我假定車牌號恰好有7位字符,UK車牌號通常都這樣)
考慮一個車牌存在當且僅當:
車牌完全包含在圖片邊界內。
車牌的寬度小于圖片寬度的80%,且車牌的高度小于圖片高度的87.5%。
車牌的寬度大于圖片寬度的60%,或車牌的高度大于圖片高度的60%。
為了檢測這些號碼,我們可以利用一個滑窗,每次滑動8個像素,而且在保證不丟失車牌的情況下提供一個縮放等級,縮放系數為$\sqrt{2}$,同時對于任何單個的車牌不會生成過量的匹配框。在后處理過程中會做一些復本(稍后解釋)。
為了訓練任何一個神經網絡,必須提供一套擁有正確輸出的訓練數據。在這里表現為一套擁有期望輸出的128*64大小的圖片。這里給出一個本項目生成的訓練數據的實例:
期望輸出的第一部分表示網絡應該輸出的號碼,第二部分表示網絡應該輸出的“存在”值。對于標記過的數據不存在的情況我在括號里作了解釋。
生成圖片的過程如下圖所示:
文本和車牌的顏色是隨機選擇的,但是文本顏色必須比車牌顏色更深一些。這是為了模擬真實場景的光線變化。最后再加入一些噪音,這樣不僅能夠解釋真實傳感器的噪音,而且能夠避免過多依賴于銳化的輪廓邊界而看到的將會是離焦的輸入圖片。
擁有背景是很重要的,這意味著網絡必須學習分辨沒有“欺騙”的車牌號邊界:使用一個黑色背景為例,網絡可能會基于非黑色來學習分辨車牌的位置,這會導致分不清楚真實圖片里的小汽車。
背景圖片來源于SUN database,
http://vision.cs.princeton.edu/projects/2010/SUN/
里面包含了超過10萬張圖片。重要的是大量的圖片可以避免網絡“記住”背景圖片。
車牌變換采用了一種基于隨機滾轉、傾斜、偏轉、平移以及縮放的仿射變換。每個參數允許的范圍是車牌號可能被看到的所有情況的集合。比如,偏轉比滾轉允許變化更多(你更可能看到一輛汽車在拐彎而不是翻轉到一邊)。
生成圖片的代碼相對較短(大約300行)。可以從gen.py里讀取。
使用的網絡結構如下圖所示:
通過維基百科可以查看CNN模塊的介紹。上面的網絡結構實際上是基于Stark的這篇paper,關于這個結構它比谷歌的那篇paper給出了更多的細節。
https://vision.in.tum.de/_media/spezial/bib/stark-gcpr15.pdf
輸出層有一個節點(左邊)被用來作為車牌是否存在的指示器。剩下的節點用來編碼一個特定車牌號的概率:圖中的每一列與車牌號中的每一位號碼一致,每一個節點給出與存在的字符相符合的概率。例如,位于第2列第3行的節點給出車牌號中第二個號碼是字符c的概率。
除了輸出層使用ReLU激活函數之外,所有層都采用深度神經網絡的標準結構。指示存在的節點使用sigmoid激活函數,典型地用于二值輸出。其他輸出節點使用softmax貫穿字符(結果是每一列的概率之和為1),是模型化離散概率分布的標準方法。
定義網絡結構的代碼在model.py里。
根據標簽和網絡輸出的交叉熵來定義損失函數。為了數值穩定性,利用softmax_cross_entropy_with_logits和sigmoid_cross_entropy_with_logits將最后一層的激活函數卷入交叉熵的計算。關于對交叉熵詳細而直觀的介紹可以參考Michael A. Nielsen的free online book中查看這一節。
使用一塊nVidia GTX 970花費大約6小時來訓練(train.py),通過CPU的一個后臺進程來運行訓練數據的生成。
事實上為了從輸入圖片中檢測和識別車牌號,搭建了類似于上面的一個檢測網絡,并采用了多位置和多尺度的128*64滑窗,這在滑窗那一節有所描述。
檢測網絡和訓練網絡的不同點在于最后兩層采用了卷積層而不是全連接層,這樣可以使檢測網絡的輸入圖片大小不僅限于128*64。將一張完整的圖片以一種特定尺寸扔進網絡中,然后返回一張每個“像素”擁有一個存在/字符概率值的圖片。因為相鄰的滑窗會共享很多卷積特征,所以將這些特定圖片卷進同一個網絡可以避免多次計算同樣的特征。
可視化輸出的“存在”部分會返回如下所示的圖片:
圖上的邊界框是網絡檢測存在車牌概率大于99%的區域。設置高閾值的原因是為了解釋訓練過程中引進的一個偏差:幾乎過半的訓練圖片都包含一個車牌,然而真實場景中有車牌的圖片很少見,所以如果設置閾值為50%的話,那么檢測網絡的假陽性就會偏高。
在檢測網絡輸出之后,我們使用非極大值抑制(NMS)的方法來過濾掉冗余的邊界框:
首先將重疊的矩形框分組,然后針對每一組輸出:
所有邊界框的交集。
找出組中車牌存在概率最高的邊界框對應的車牌號。
下圖所示文章最開始給出的那張車牌圖片的檢測結果:
哎呦,字符R被誤檢成了P。上圖中車牌存在概率最大的滑窗如下圖所示:
第一眼似乎以為這個對于檢測器來說是小菜一碟,然而事實證明這是過擬合的問題。下圖給出了生成訓練圖片時所用的車牌號中R的字體:
注意字符R腿的角度是如何不同于輸入圖片中字符R腿的角度。由于網絡僅僅學習過上面的那種R字體,因此當遇到不同字體的R字符時就迷惑了。為了測試這種假設,我在GIMP中改進了圖片,使得其更接近于訓練時的字體:
改進之后,檢測得到了正確的輸出:
檢測的源碼在這里detect.py
我已經開源了一個擁有相對較短代碼(大約800行)的系統,它不用導入任何特定領域的庫以及不需要太多特定領域的知識,就能夠實現車牌號自動識別。此外,我還通過在線合成圖片的方法解決了上千張訓練圖片的需求問題(通常是在深度神經網絡的情況下)。
另一方面,我的系統也存在一些缺點:
只適用于特定車牌號。尤其是,網絡結構明確假定了輸出只有7個字符。
只適用于特定字體。
速度太慢。該系統運行一張適當尺寸的圖片要花費幾秒鐘。
為了解決第1個問題,谷歌團隊將他們的網絡結構的高層拆分成了多個子網絡,每一個子網絡用于假定輸出號碼中的不同號碼位。還有一個并行的子網絡來決定存在多少號碼。我覺得這種方法可以應用到這兒,但是我沒有在這個項目中實現。
關于第2點我在上面舉過例子,由于字體的稍微不同而導致字符R的誤檢。如果嘗試著檢測US車牌號的話,誤檢將會更加嚴重,因為US車牌號字體類型更多。一個可能的解決方案就是使得訓練數據有更多不同的字體類型可選擇,盡管還不清楚需要多少字體類型才能成功。
第3點提到的速度慢的問題是扼殺許多應用的cancer:在一個相當強大的GPU上處理一張適當尺寸的輸入圖片就要花費幾秒鐘。我認為不引進一種級聯式結構的檢測網絡就想避開這個問題是不太可能的,比如Haar級聯,HOG檢測器,或者一個更簡單的神經網絡。
我很有興趣去嘗試和其他機器學習方法的比較會怎樣,特別是姿態回歸看起來有希望,最后可能會附加一個最基本的分類階段。如果使用了像scikit-learn這樣的機器學習庫,那么應該同樣簡單。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。