OpenCV學習案例之車牌識別easyPR
起始
github上開源中文車牌識別庫比較少:
- HyperLPR,基於深度學習高性能中文車牌識別庫,支持python、c++, 可以在Android,Linux等各種平臺使用
- EasyPR ,一個簡單、高效、準確的非限制場景(unconstrained situation)下的車牌識別庫
兩者中EasyPR作者有一系列博客文章,詳細介紹了EasyPR的開發過程,其中還介紹了很多OpenCV基礎知識,十分適合案例學習。
EasyPR博客: https://www.cnblogs.com/subconscious/p/3979988.html
1. Windows編譯
根據EasyPR readme介紹,windows下是vs+cmake編譯,但我電腦用的是mingw64,所以自己編寫Makefile,沒有用官方的vs+cmake
1.1 環境準備
- Windows10 x64
- OpenCV3.4.0 編譯好的文件,編譯方法可以見我的另一篇博客
- mingw-w64 gcc-7.3.0
- EasyPR 最新版源代碼
1.2 編譯之前需要修改一下源碼
-
在include\easypr\config.h第134行
#ifdef CV_VERSION_THREE_TWO #define LOAD_SVM_MODEL(model, path) \ model = ml::SVM::load(path); #define LOAD_ANN_MODEL(model, path) \ model = ml::ANN_MLP::load(path); #else #define LOAD_SVM_MODEL(model, path) \ model = ml::SVM::load<ml::SVM>(path); #define LOAD_ANN_MODEL(model, path) \ model = ml::ANN_MLP::load<ml::ANN_MLP>(path); #endif
替換爲
#define LOAD_SVM_MODEL(model, path) \ model = Algorithm::load<ml::SVM>(path) #define LOAD_ANN_MODEL(model, path) \ model = Algorithm::load<ml::ANN_MLP>(path)
原因是,使用的OpenCV版本是3.4.0,SVM和ANN_MLP加載方式變了
1.3 編寫Makefile文件
library目錄是OpenCV編譯好的lib,bin,include三個文件夾的父目錄
lib := -lopencv_aruco340\
-lopencv_bgsegm340\
-lopencv_bioinspired340\
-lopencv_calib3d340\
-lopencv_ccalib340\
-lopencv_core340\
-lopencv_datasets340\
-lopencv_dnn340\
-lopencv_dpm340\
-lopencv_face340\
-lopencv_features2d340\
-lopencv_flann340\
-lopencv_fuzzy340\
-lopencv_highgui340\
-lopencv_imgcodecs340\
-lopencv_imgproc340\
-lopencv_img_hash340\
-lopencv_line_descriptor340\
-lopencv_ml340\
-lopencv_objdetect340\
-lopencv_optflow340\
-lopencv_phase_unwrapping340\
-lopencv_photo340\
-lopencv_plot340\
-lopencv_reg340\
-lopencv_rgbd340\
-lopencv_saliency340\
-lopencv_shape340\
-lopencv_stereo340\
-lopencv_stitching340\
-lopencv_structured_light340\
-lopencv_superres340\
-lopencv_surface_matching340\
-lopencv_text340\
-lopencv_tracking340\
-lopencv_video340\
-lopencv_videoio340\
-lopencv_videostab340\
-lopencv_xfeatures2d340\
-lopencv_ximgproc340\
-lopencv_xobjdetect340\
-lopencv_xphoto340\
-lopencv_ffmpeg340_64\
base_dir := C:\\Users\\supre\\Desktop\\EasyPR-master
lib_dir := ${base_dir}\\library\bin
include_dir := ${base_dir}\\library\include
src := src/core/core_func.cpp \
src/core/chars_identify.cpp \
src/core/chars_recognise.cpp \
src/core/chars_segment.cpp \
src/core/feature.cpp \
src/core/plate_detect.cpp \
src/core/plate_judge.cpp \
src/core/plate_locate.cpp \
src/core/plate_recognize.cpp \
src/core/params.cpp \
src/train/ann_train.cpp \
src/train/annCh_train.cpp \
src/train/svm_train.cpp \
src/train/train.cpp \
src/train/create_data.cpp \
src/util/util.cpp \
src/util/program_options.cpp \
src/util/kv.cpp \
test/main.cpp \
thirdparty/xmlParser/xmlParser.cpp \
thirdparty/textDetect/erfilter.cpp \
thirdparty/LBP/helper.cpp \
thirdparty/LBP/lbp.cpp \
thirdparty/mser/mser2.cpp
main:
g++ $(src) -I ${include_dir} -I ${include_dir}\opencv -I ${include_dir}\opencv2 -I ${base_dir}\include -I ${base_dir} -L ${lib_dir} $(lib) -o easypr.exe
1.4 在Makefile文件目錄下執行mingw32-make
1.5 生成好的easypr.exe執行報找不到dll錯誤
這裏需要將opencv dll所在目錄library\bin,配在環境變量PATH上。重新打開命令行,執行easypr.exe
1.6 最終顯示
2. 代碼閱讀
2.1 車牌定位(plate_locate)
-
從main.cpp開始找到測試車牌定位的代碼,可以看到讀取resources/image/plate_locate.jpg車牌照片,執行CPlateLocate的plateLocate方法,得到車牌數量result和車牌vector<Mat> resultVec
-
繼續跟進,可以看到對車牌進行了三次處理定位,顏色,sobel算子, MSER文字定位。
EasyPR作者有文章分別講解這三部分:顏色定位和偏斜扭轉, 高斯模糊、灰度化和Sobel算子,文字定位
2.2 車牌判斷(plate_judge)
-
找到車牌判斷部分代碼,前面是車牌定位,後面是車牌判斷,主要是plateJudge這個方法,後面是通過getHistomPlusColoFeatures獲取特徵,通過svm對車牌判斷,得出分數,0是車牌,-1不是。EasyPR作者對SVM有篇文章https://www.cnblogs.com/subconscious/p/4249581.html,值得一看
2.3 字符分割(char_segment)
-
通過charsSegment對車牌照片字符分隔,EasyPR作者有一篇文章,字符分割,詳細介紹了代碼中分割的流程
2.4 字符識別(char_identify)
- 通過identify函數進行識別,block_i爲0代表第一個字符,車牌第一個字符是中文,所以identify第二個參數傳true進行識別。在identify最主要還是classify函數,對字符識別分類。在classify函數中,可以看到是通過ANN_MLP對字符進行識別