1. 程式人生 > >EasyPR--開發詳解(2)車牌定位

EasyPR--開發詳解(2)車牌定位

  這篇文章是一個系列中的第三篇。前兩篇的地址貼下:介紹詳解1。我撰寫這系列文章的目的是:1、普及車牌識別中相關的技術與知識點;2、幫助開發者瞭解EasyPR的實現細節;3、增進溝通。

  EasyPR的專案地址在這:GitHub要想執行EasyPR的程式,首先必須配置好openCV,具體可以參照這篇文章

  在前兩篇文章中,我們已經初步瞭解了EasyPR的大概內容,在本篇內容中我們開始深入EasyRP的程式細節。瞭解EasyPR是如何一步一步實現一個車牌的識別過程的。根據EasyPR的結構,我們把它分為六個部分,前三個部分統稱為“Plate Detect”過程。主要目的是在一副圖片中發現僅包含車牌的圖塊,以此提高整體識別的準確率與速度。這個過程非常重要,如果這步失敗了,後面的字元識別過程就別想了。而“Plate Detect”過程中的三個部分又分別稱之為“Plate Locate” ,“SVM train”,“Plate judge”,其中最重要的部分是第一步“Plate Locate”過程。本篇文章中就是主要介紹“Plate Locate”過程,並且回答以下三個問題:

  1.此過程的作用是什麼,為什麼重要?

  2.此過程是如何實現車牌定位這個功能的?

  3.此過程中的細節是什麼,如何進行調優?

 1.“Plate Locate”的作用與重要性

   在說明“Plate Locate”的作用與重要性之前,請看下面這兩幅圖片。

      

圖1 兩幅包含車牌的不同形式圖片

  左邊的圖片是作者訓練的圖片(作者大部分的訓練與測試都是基於此類交通抓拍圖片),右邊的圖片則是在百度圖片中“車牌”獲得(這個圖片也可以稱之為生活照片)。右邊圖片的問題是一個網友評論時問的。他說EasyPR在處理百度圖片時的識別率不高。確實如此,由於工業與生活應用目的不同,拍攝的車牌的大小,角度,色澤,清晰度不一樣。而對影象處理技術而言,一些演算法對於影象的形式以及結構都有一定的要求或者假設。因此在一個場景下適應的演算法並不適用其他場景。目前EasyPR所有的功能都是基於交通抓拍場景的圖片製作的,因此也就導致了其無法處理生活場景中這些車牌照片。

  那麼是否可以用一致的“Plate Locate”過程中去處理它?答案是也許可以,但是很難,而且最後即便處理成功,效率也許也不盡如人意。我的推薦是:對於不同的場景要做不同的適配。儘管“Plate Locate”過程無法處理生活照片的定位,但是在後面的字元識別過程中兩者是通用的。可以對EasyPR的“Plate Locate”做改造,同時仍然使用整體架構,這樣或許可以處理。

  有一點事實值得了解到是,在生產環境中,你所面對的圖片形式是固定的,例如左邊的圖片。你可以根據特定的圖片形式來調優你的車牌程式,使你的程式對這類圖片足夠健壯,效率也夠高。在上線以後,也有很好的效果。但當圖片形式調整時,就必須要調整你的演算法了。在“Plate Locate”過程中,有一些引數可以調整。如果通過調整這些引數就可以使程式良好工作,那最好不過。當這些引數也不能夠滿足需求時,就需要完全修改EasyPR的實現程式碼,因此需要開發者瞭解EasyPR是如何實現plateLocate這一過程的。

  在EasyPR中,“Plate Locate”過程被封裝成了一個“CPlateLocate”類,通過“plate_locate.h”宣告,在“plate_locate.cpp”中實現。

  CPlateLocate包含三個方法以及數個變數。方法提供了車牌定位的主要功能,變數則提供了可定製的引數,有些引數對於車牌定位的效果有非常明顯的影響,例如高斯模糊半徑、Sobel運算元的水平與垂直方向權值、閉操作的矩形寬度。CPlateLocate類的宣告如下:

class CPlateLocate 
{
public:
    CPlateLocate();

    //! 車牌定位
    int plateLocate(Mat, vector<Mat>& );

    //! 車牌的尺寸驗證
    bool verifySizes(RotatedRect mr);

    //! 結果車牌顯示
    Mat showResultMat(Mat src, Size rect_size, Point2f center);

    //! 設定與讀取變數
    //...

protected:
    //! 高斯模糊所用變數
    int m_GaussianBlurSize;

    //! 連線操作所用變數
    int m_MorphSizeWidth;
    int m_MorphSizeHeight;

    //! verifySize所用變數
    float m_error;
    float m_aspect;
    int m_verifyMin;
    int m_verifyMax;

    //! 角度判斷所用變數
    int m_angle;

    //! 是否開啟除錯模式,0關閉,非0開啟
    int m_debug;
};

  注意,所有EasyPR中的類都宣告在名稱空間easypr內,這裡沒有列出。CPlateLocate中最核心的方法是plateLocate方法。它的宣告如下:

    //! 車牌定位
    int plateLocate(Mat, vector<Mat>& );

  方法有兩個引數,第一個引數代表輸入的源影象,第二個引數是輸出陣列,代表所有檢索到的車牌圖塊。返回值為int型,0代表成功,其他代表失敗。plateLocate內部是如何實現的,讓我們再深入下看看。

2.“Plate Locate”的實現過程

  plateLocate過程基本參考了taotao1233的部落格的處理流程,但略有不同。

  plateLocate的總體識別思路是:如果我們的車牌沒有大的旋轉或變形,那麼其中必然包括很多垂直邊緣(這些垂直邊緣往往緣由車牌中的字元),如果能夠找到一個包含很多垂直邊緣的矩形塊,那麼有很大的可能性它就是車牌。

  依照這個思路我們可以設計一個車牌定位的流程。設計好後,再根據實際效果進行調優。下面的流程是經過多次調整與嘗試後得出的,包含了數月來作者針對測試圖片集的一個最佳過程(這個流程並不一定適用所有情況)。plateLocate的實現程式碼在這裡不貼了,Git上有所有原始碼。plateLocate主要處理流程圖如下:

圖2 plateLocate流程圖

  下面會一步一步參照上面的流程圖,給出每個步驟的中間臨時圖片。這些圖片可以在1.01版的CPlateLocate中設定如下程式碼開啟除錯模式。

    CPlateLocate plate;
    plate.setDebug(1);

   臨時圖片會生成在tmp資料夾下。對多個車牌圖片處理的結果僅會保留最後一個車牌圖片的臨時圖片。

  1、原始圖片。

  2、經過高斯模糊後的圖片。經過這步處理,可以看出影象變的模糊了。這步的作用是為接下來的Sobel運算元去除干擾的噪聲。

  3、將影象進行灰度化。這個步驟是一個分水嶺,意味著後面的所有操作都不能基於色彩資訊了。此步驟是利是弊,後面再做分析。


  4、對影象進行Sobel運算,得到的是影象的一階水平方向導數。這步過後,車牌被明顯的區分出來。


  5、對影象進行二值化。將灰度影象(每個畫素點有256個取值可能)轉化為二值影象(每個畫素點僅有1和0兩個取值可能)。


  6、使用閉操作。對影象進行閉操作以後,可以看到車牌區域被連線成一個矩形裝的區域。

  7、求輪廓。求出圖中所有的輪廓。這個演算法會把全圖的輪廓都計算出來,因此要進行篩選。


  8、篩選。對輪廓求最小外接矩形,然後驗證,不滿足條件的淘汰。經過這步,僅僅只有六個黃色邊框的矩形通過了篩選。


  8、角度判斷與旋轉。把傾斜角度大於閾值(如正負30度)的矩形捨棄。左邊第一、二、四個矩形被捨棄了。餘下的矩形進行微小的旋轉,使其水平。

    


  10、統一尺寸。上步得到的圖塊尺寸是不一樣的。為了進入機器學習模型,需要統一尺寸。統一尺寸的標準寬度是136,長度是36。這個標準是對千個測試車牌平均後得出的通用值。下圖為最終的三個候選”車牌“圖塊。

    

  這些“車牌”有兩個作用:一、積累下來作為支援向量機(SVM)模型的訓練集,以此訓練出一個車牌判斷模型;二、在實際的車牌檢測過程中,將這些候選“車牌”交由訓練好的車牌判斷模型進行判斷。如果車牌判斷模型認為這是車牌的話就進入下一步即字元識別過程,如果不是,則捨棄。

3.“Plate Locate”的深入討論與調優策略

  好了,說了這麼多,讀者想必對整個“Plate Locate”過程已經有了一個完整的認識。那麼讓我們一步步稽核一下處理流程中的每一個步驟。回答下面三個問題:這個步驟的作用是什麼?省略這步或者替換這步可不可以?這個步驟中是否有引數可以調優的?通過這幾個問題可以幫助我們更好的理解車牌定位功能,並且便於自己做修改、定製。

  由於篇幅關係,下面的深入討論放在下期。

版權說明:

  本文中的所有文字,圖片,程式碼的版權都是屬於作者和部落格園共同所有。歡迎轉載,但是務必註明作者與引用來源。任何未經允許的剽竊以及爬蟲抓取都屬於侵權,作者和部落格園保留所有權利。

參考文獻:

相關推薦

EasyPR--開發2車牌定位

  這篇文章是一個系列中的第三篇。前兩篇的地址貼下:介紹、詳解1。我撰寫這系列文章的目的是:1、普及車牌識別中相關的技術與知識點;2、幫助開發者瞭解EasyPR的實現細節;3、增進溝通。   EasyPR的專案地址在這:GitHub。要想執行EasyPR的程式,首先必須配置好openCV,具體可以參照這篇文

EasyPR--開發8文字定位

dont bubuko 通用 設置 光照 detect improve nmp easy 轉自https://www.cnblogs.com/subconscious/p/5637735.html 今天我們來介紹車牌定位中的一種新方法--文字定位方法(MSER),包括其主要

EasyPR--開發7顏色定位與偏斜扭轉

  本篇文章介紹EasyPR裡新的定位功能:顏色定位與偏斜扭正。希望這篇文件可以幫助開發者與使用者更好的理解EasyPR的設計思想。   讓我們先看一下示例圖片,這幅圖片中的車牌通過顏色的定位法進行定位並從偏斜的視角中扭正為正視角(請看右圖的左上角)。 圖1 新版本的定位效果     下面內容會對這兩

EasyPR--開發9文字定位

  今天我們來介紹車牌定位中的一種新方法–文字定位方法(MSER),包括其主要設計思想與實現。接著我們會介紹一下EasyPR v1.5-beta版本中帶來的幾項改動。 一. 文字定位法   在EasyPR前面幾個版本中,最為人所詬病的就是定位效果不佳,尤其是在面對生活場景(例如手機拍攝)時。由於EasyP

EasyPR--開發5顏色定位與偏斜扭轉

  本篇文章介紹EasyPR裡新的定位功能:顏色定位與偏斜扭正。希望這篇文件可以幫助開發者與使用者更好的理解EasyPR的設計思想。   讓我們先看一下示例圖片,這幅圖片中的車牌通過顏色的定位法進行定位並從偏斜的視角中扭正為正視角(請看右圖的左上角)。 圖1 新版本的定位效果     下

EasyPR--開發7字元分割

大家好,好久不見了。   一轉眼距離上一篇部落格已經是4個月前的事了。要問博主這段時間去幹了什麼,我只能說:我去“外面看了看”。 圖1 我想去看看    在外面跟幾家創業公司談了談,交流了一些大資料與機器視覺相關的心得與經驗。不過由於各種原因,博主又回來了。

EasyPR--開發6SVM開發

  在前面的幾篇文章中,我們介紹了EasyPR中車牌定位模組的相關內容。本文開始分析車牌定位模組後續步驟的車牌判斷模組。車牌判斷模組是EasyPR中的基於機器學習模型的一個模組,這個模型就是作者前文中從機器學習談起中提到的SVM(支援向量機)。  我們已經知道,車牌定位模組的輸出是一些候選車牌的圖片。但如何從

EasyPR--開發4形態學操作、尺寸驗證、旋轉等操作

  在上一篇深度分析與調優討論中,我們介紹了高斯模糊,灰度化和Sobel運算元。在本文中,會分析剩餘的定位步驟。  根據前文的內容,車牌定位的功能還剩下如下的步驟,見下圖中未塗灰的部分。 圖1 車牌定位步驟   我們首先從Soble運算元分析出來的邊緣來看。通過下圖可見,Sobel運算元有很強的區分性

EasyPR--開發3高斯模糊、灰度化和Sobel運算元

在上篇文章中我們瞭解了PlateLocate的過程中的所有步驟。在本篇文章中我們對前3個步驟,分別是高斯模糊、灰度化和Sobel運算元進行分析。 一、高斯模糊  1.目標   對影象去噪,為邊緣檢測演算法做準備。    2.效果   在我們的車牌定位中的第一步就是高斯模糊處理。    圖1 高斯

EasyPR--中文開源車牌識別系統 開發1

  在上篇文件中作者已經簡單的介紹了EasyPR,現在在本文件中詳細的介紹EasyPR的開發過程。   正如淘寶誕生於一個購買來的LAMP系統,EasyPR也有它誕生的原型,起源於CSDN的taotao1233的一個部落格,博主以讀書筆記的形式記述了通過閱讀“Mastering OpenCV”這本書完成的一

canvas特效代碼2

text pre javascrip css png tco border src null canvas是一個就基於像素的畫圖h5元素。 利用canvas做一個如下描述所示的動態圖形:當鼠標點下去時開始繪圖,在鼠標結束時完成一個矩形,當再一次點擊時重復第一次的繪圖步驟

PHP與Java集成開發

new 編程語言 到你 其中 web-inf request 測試 add 輸入 很久以前,有人從www上看到看到天空上一個很亮的亮點,它就是Java語言,與此同時,在另一個地方一位夢想家也看到了一個亮點,它就是PHP。 時間一天天過去,這兩個亮點也變得越來越亮,很快,它

經典算法2尋找數組中的次大數

etc n) esp arr else second include 尋找 char 題目:10個互不相等的整數,求其中的第2大的數字,要求數組不能用排序,設計的算法效率越高越好。 1 #include<iostream> 2 3 using name

屬性配置文件2

環境配置 gap 通過 數據庫 訪問 基本 需要 .profile 實驗 通過命令行設置屬性值 相信使用過一段時間Spring Boot的用戶,一定知道這條命令:java -jar xxx.jar --server.port=8888,通過使用–server.port屬性來

Spring MVC @RequestMapping註解2

並不是 value get ecif 使用 .com java代碼 處理方法 分開 @RequestMapping 參數說明   value:定義處理方法的請求的 URL 地址。(重點)   method:定義處理方法的 http method 類型,如 GET、POST

Java2--JDK安裝與環境變數配置

JDK安裝與環境變數配置 ---------------------  作者:文動天下 來源:CSDN  連結:https://blog.csdn.net/li_yi_kun?t=1 版權宣告:本文為博主原創文章,轉載請附上博文連結! 1、JDK&nb

JAVA:Excel匯入匯出2--匯入

1. 瀏覽資料夾,選擇需要上傳的檔案 程式碼 jsp <li class="col-sm-1"> <span>上&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&a

SpringBoot開發--SpringBoot配置檔案YML注意事項

轉載自:https://blog.csdn.net/qq_31001665/article/details/70197543#commentBox 一、多重層級讀取 在YML中我們再新增一個ZZP2的配置資訊,其中包含了girl節點以及girl下的name,age屬性。 zzp2:

SpringBoot開發--SpringBoot的配置檔案以及註解

轉載自:https://blog.csdn.net/qq_31001665/article/details/69938750 一、Spring Boot註解 通過上一篇文章,我們已經快速構建了一個spring boot的專案,那spring boot專案和我們之前使用的springMVC專案

SpringBoot開發--初識SpringBoot

轉載自:https://blog.csdn.net/qq_31001665/article/details/54803354 一、寫在前面的話: 越來越多的公司開始使用sprinbgboot作為後臺伺服器開發的框架,作為目前微服務框架的佼佼者,現在學習springboot框架是一個很好的機會