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对字符进行识别