Merge branch 'master-gbk'

# Conflicts:
#	include/easypr/chars_identify.h
#	include/easypr/chars_recognise.h
#	include/easypr/chars_segment.h
#	include/easypr/core_func.h
#	include/easypr/plate.h
#	include/easypr/plate_detect.h
#	include/easypr/plate_judge.h
#	include/easypr/plate_locate.h
#	include/easypr/plate_recognize.h
#	include/easypr/util.h
#	src/core/chars_identify.cpp
#	src/core/chars_recognise.cpp
#	src/core/chars_segment.cpp
#	src/core/core_func.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/train/ann_train.cpp
#	test/accuracy.hpp
#	test/main.cpp
v1.6alpha
Micooz 10 years ago
commit a0d3741f09

28
.gitignore vendored

@ -6,14 +6,29 @@ Thumbs.db
*.exe
*.pdb
*.user
*.sln.docstates
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
experiment/
experi/
bak/
@ -197,3 +212,6 @@ EasyPR.xcodeproj/
# Debug tmp files
tmp/
# native_test files
native_test/

@ -0,0 +1,86 @@
EasyPR版本更新
======
本次更新是1.2版主要改进在于提升了车牌定位模块的准确性从70%左右到目前的94%,见下图:
![1.2版综合效果](doc/res/testresult.png)
主要改动如下:
* 车牌定位使用了“颜色信息”+“二次Sobel”的综合搜索方法。在下面的window中红框代表Sobel定位结果黄框代表颜色定位结果。
* “批量测试”增加了一个结果查看window这个窗口可以用SetDebug()方法开闭(true开false关)。
![查看结果](doc/res/window.png)
* 基本攻克了“大角度定位”问题,下图的车牌被定位并转到了正确的视角。
![大角度定位](doc/res/bigangle.png)
* GDTS里新增了若干张新测试图包括数张大角度图。
* “批量测试”结果现在同时会保存在“run_accuracy”文件中可以查询历史信息。
* 与Linux版本做了整合可以实现跨平台编译。
======
目前EasyPR的版本是1.1相比上一个版本1.0,有以下更新(这次的更新内容较多,为了跟你现有的项目和代码不冲突,请
谨慎选择全部更新,最好新起一个目录试试新增的功能和内容):
* 新的SVM模型。新模型使用rbf核替代了liner核在车牌判断的准确率提升了8个百分点。
![svm准确率改进](res/svm_upgragde.png)
* 新增两个特征提取方法。并提供了相关的回调函数接口供二次开发。
![fetures](res/fetures.png)
* 新增Debug模式。可以在image/tmp文件夹下看到所有输出的中间图片。
![Debug模式](res/debug.jpg)
* 增加了LifeMode模式相比默认模式更适合在生活场景下定位车牌。
![LifeMode模式](res/lifemode.jpg)
* 增加了批量测试功能这个功能可供测试EasyPR在多幅图片上的整体表现效果。
![批量测试](res/batch_operation.jpg) ![批量测试结果](res/batch_result.png)
* 引入了GDTS(General Data Test Set通用数据测试集)这个概念作为EasyPR准确率的评测数据集。
![GDTS](res/general_test.jpg)
* 为了确保GDTS的数据仅用于非商业目的引入了新的[GDSL协议](../image/GDSL.txt)。
![GDSL](res/gdsl.jpg)
* 完善SVM训练功能。提供了一个方便简单的训练窗口。这些增加的功能是为了配合即将推出的SVM开发详解这篇文章。
![SVM训练](res/svm_train.jpg)
* 强化SVM模型验证。使用了三个新的数据集概念即learn datatrain datatest data。
![SVM训练集](res/svm_data.jpg)
* 新增评价指标。引入PreciseRecallFSocre三个指标这三个指标作为SVM模型准确率评判的参数与改善的依据。
![SVM指标](res/svm_rate.jpg)
* 新增整体指标。引入levenshtein距离作为EasyPR整体识别准确率误差的评判参数与改善依据。
![levenshtein1](res/levenshtein1.jpg) ![levenshtein2](res/levenshtein2.jpg) ![levenshtein3](res/levenshtein3.jpg)
![levenshteinAll](res/levenshteinAll.JPG)
* 大幅增加训练数据。SVM训练数据中增加了近千张新数据(未经直方图均衡化的车牌图片和非车牌图片)。
请自行解压train/data/plate_detect_svm/learn下的压缩文件查看相关信息。
* 新增命令行窗口,作为测试与训练的辅助工具。
注意上一个版本中image文件下的test.jpg如果有同学下载了请删除。它的格式不符合新的GDSL协议的约定。
如果想使用测试图片可以使用1.1版本中新增的test.jpg替代。

@ -10,11 +10,9 @@ EasyPR是一个中文的开源车牌识别系统其目标是成为一个简
### 更新
本次更新是1.3alpha版主要改进在于提升了字符识别模块的准确性
本次更新是1.3beta版主要改进在于提升了字符识别模块的准确性
平均字符差距从2.0降低到0.7完整匹配度从25%左右上升到目前的68%。
同时车牌定位模块准确率进一步提升从上一个版本的94%上升到现在的99%。见下图:
平均字符差距从0.7降低到0.4完整匹配度从68%左右上升到目前的81%平均执行时间从2秒降低到1.5秒。见下图:
![1.3版综合效果](resources/doc/res/testresult_1.3.png)
@ -24,7 +22,7 @@ EasyPR是一个中文的开源车牌识别系统其目标是成为一个简
* 使用了更鲁棒性的办法提升了车牌定位模块的准确率。
目前版本的问题是处理时间大幅度上升1.3正式版本中会对这个问题进行fix。
目前版本的问题是处理时间还是偏高1.3正式版本中会对这个问题进行fix。
### 跨平台
@ -34,8 +32,8 @@ EasyPR是一个中文的开源车牌识别系统其目标是成为一个简
|------|-------|-------|-------
| android | goldriver | 1.1 | [linuxxx/EasyPR_Android](https://github.com/linuxxx/EasyPR_Android)
| linux | Micooz | 1.3 | 已跟EasyPR整合
| ios | zhoushiwei | 1.1 | [zhoushiwei/EasyPR-iOS](https://github.com/zhoushiwei/EasyPR-iOS)
| mac | zhoushiwei | 1.1 | [zhoushiwei/EasyPR](https://github.com/zhoushiwei/EasyPR)
| ios | zhoushiwei | 1.3 | [zhoushiwei/EasyPR-iOS](https://github.com/zhoushiwei/EasyPR-iOS)
| mac | zhoushiwei,Micooz | 1.3 | 已跟EasyPR整合
| java | fan-wenjie | 1.2 | [fan-wenjie/EasyPR-Java](https://github.com/fan-wenjie/EasyPR-Java)
### 兼容性
@ -56,6 +54,14 @@ EasyPR是基于opencv2.4.8版本开发的2.4.8以上的版本应该可以兼
“蓝牌苏EUK722”
### 版权
EasyPR的源代码与训练数据遵循Apache v2.0协议开源。
EasyPR的resources/image/general_test文件夹下的图片数据遵循[GDSL协议](image/GDSL.txt)(通用数据共享协议)进行开放。
请确保在使用前了解以上协议的内容。
### 目录结构
以下表格是本工程中所有目录的解释:
@ -207,11 +213,11 @@ $ ./easypr_test svm --train --has-plate=has/ --no-plate=no/ --divide --svm=save/
### Contributors
* liuruoze1.0-1.2版核心代码作者
* liuruoze1.0-1.2版核心代码作者1.3版整合工作
* 海豚嘎嘎1.3版作者,提升了字符识别准确率
* 海豚嘎嘎1.3alpha-beta版作者,提升了车牌定位与字符识别准确率
* Micoozlinux平台编译性能优化util类
* Micoozlinux与mac的跨平台编译性能优化util类
* jsxyheludeface版本一
@ -219,6 +225,8 @@ $ ./easypr_test svm --train --has-plate=has/ --no-plate=no/ --divide --svm=save/
* ahccom新的plateLocate函数
* 阿水1.3版整合,数据标注等工作
### 鸣谢
taotao1233邱锦山唐大侠jsxyhelu如果有一天(zhoushiwei),学习奋斗,袁承志,

@ -957,11 +957,111 @@
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.652542个, 完全匹配数:81张, 完全匹配率:68.6441%
总时间:259秒, 平均执行时间:2.15833秒
2015-05-21 08:41:27
2015-05-05 15:53:11
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.754237个, 完全匹配数:82张, 完全匹配率:69.4915%
总时间:28秒, 平均执行时间:0.233333秒
2015-05-21 21:02:13
平均字符差距:0.652542个, 完全匹配数:81张, 完全匹配率:68.6441%
总时间:234秒, 平均执行时间:1.95秒
2015-05-05 17:01:19
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.415254个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:235秒, 平均执行时间:1.95833秒
2015-05-05 18:16:11
总图片数:120张, 未识出图片:3张, 定位率:97.5%
平均字符差距:0.982906个, 完全匹配数:69张, 完全匹配率:58.9744%
总时间:175秒, 平均执行时间:1.45833秒
2015-05-05 18:21:27
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.415254个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:193秒, 平均执行时间:1.60833秒
2015-05-05 18:27:28
总图片数:1张, 未识出图片:0张, 定位率:100%
平均字符差距:0个, 完全匹配数:1张, 完全匹配率:100%
总时间:0秒, 平均执行时间:0秒
2015-05-05 18:31:09
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.415254个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:219秒, 平均执行时间:1.825秒
2015-05-06 21:13:22
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.415254个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:452秒, 平均执行时间:3.76667秒
2015-05-06 22:22:21
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.415254个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:434秒, 平均执行时间:3.61667秒
2015-05-06 22:52:03
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.415254个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:199秒, 平均执行时间:1.65833秒
2015-05-06 22:58:48
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.415254个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:188秒, 平均执行时间:1.56667秒
2015-05-08 17:00:15
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.415254个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:4176秒, 平均执行时间:34.8秒
2015-05-10 10:19:02
总图片数:9张, 未识出图片:7张, 定位率:22.2222%
平均字符差距:3个, 完全匹配数:0张, 完全匹配率:0%
总时间:21秒, 平均执行时间:2.33333秒
2015-05-10 11:21:09
总图片数:17张, 未识出图片:15张, 定位率:11.7647%
平均字符差距:3个, 完全匹配数:0张, 完全匹配率:0%
总时间:69秒, 平均执行时间:4.05882秒
2015-05-10 11:31:27
总图片数:6张, 未识出图片:0张, 定位率:100%
平均字符差距:3.33333个, 完全匹配数:1张, 完全匹配率:16.6667%
总时间:95秒, 平均执行时间:15.8333秒
2015-05-10 12:00:56
总图片数:47张, 未识出图片:20张, 定位率:57.4468%
平均字符差距:2.66667个, 完全匹配数:8张, 完全匹配率:29.6296%
总时间:33秒, 平均执行时间:0.702128秒
2015-05-10 12:02:47
总图片数:47张, 未识出图片:20张, 定位率:57.4468%
平均字符差距:2.66667个, 完全匹配数:8张, 完全匹配率:29.6296%
总时间:34秒, 平均执行时间:0.723404秒
2015-05-13 21:08:17
总图片数:50张, 未识出图片:23张, 定位率:54%
平均字符差距:2.85185个, 完全匹配数:7张, 完全匹配率:25.9259%
总时间:28秒, 平均执行时间:0.56秒
2015-06-04 20:03:57
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.398305个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:187秒, 平均执行时间:1.55833秒
2015-06-04 20:40:49
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.398305个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:177秒, 平均执行时间:1.475秒
2015-06-04 20:55:54
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.398305个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:177秒, 平均执行时间:1.475秒
2015-06-05 21:05:43
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.398305个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:184秒, 平均执行时间:1.53333秒
2015-06-08 18:52:48
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.398305个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:144秒, 平均执行时间:1.2秒
2015-06-08 19:18:27
总图片数:120张, 未识出图片:2张, 定位率:98.3333%
平均字符差距:0.754237个, 完全匹配数:82张, 完全匹配率:69.4915%
总时间:35秒, 平均执行时间:0.291667秒
平均字符差距:0.398305个, 完全匹配数:96张, 完全匹配率:81.3559%
总时间:143秒, 平均执行时间:1.19167秒
2015-06-08 19:38:25
总图片数:170张, 未识出图片:3张, 定位率:98.2353%
平均字符差距:0.473054个, 完全匹配数:131张, 完全匹配率:78.4431%
总时间:163秒, 平均执行时间:0.958824秒
2015-06-08 21:55:33
总图片数:170张, 未识出图片:3张, 定位率:98.2353%
平均字符差距:0.473054个, 完全匹配数:131张, 完全匹配率:78.4431%
总时间:209秒, 平均执行时间:1.22941秒
2015-06-08 22:03:30
总图片数:170张, 未识出图片:5张, 定位率:97.0588%
平均字符差距:0.472727个, 完全匹配数:130张, 完全匹配率:78.7879%
总时间:211秒, 平均执行时间:1.24118秒
2015-06-08 22:15:07
总图片数:170张, 未识出图片:5张, 定位率:97.0588%
平均字符差距:0.472727个, 完全匹配数:130张, 完全匹配率:78.7879%
总时间:631秒, 平均执行时间:3.71176秒

@ -13,47 +13,49 @@
#define __CHARS_IDENTIFY_H__
#include <opencv2/opencv.hpp>
#include <string>
using namespace cv;
using namespace std;
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CCharsIdentify {
public:
CCharsIdentify();
//! 字符鉴别
std::string charsIdentify(cv::Mat, bool, bool);
std::string charsIdentify(cv::Mat input);
//! 字符分割
string charsIdentify(Mat, bool, bool);
string charsIdentify(Mat input);
//! 字符分类
int classify(cv::Mat, bool, bool);
//! 字符分类
int classify(Mat, bool, bool);
int classify(Mat f);
int classify(cv::Mat f);
//! 装载ANN模型
//! 装载ANN模型
void LoadModel();
//! 装载ANN模型
void LoadModel(std::string s);
//! 设置与读取模型路径
inline void setModelPath(std::string path) { m_path = path; }
//! 装载ANN模型
void LoadModel(string s);
inline std::string getModelPath() const { return m_path; }
//! 设置与读取模型路径
inline void setModelPath(string path) { m_path = path; }
inline string getModelPath() const { return m_path; }
private:
//使用的ANN模型
//使用的ANN模型
CvANN_MLP ann;
//! 模型存储路径
std::string m_path;
//! 模型存储路径
string m_path;
//! 特征尺寸
//! 特征尺寸
int m_predictSize;
//! 省份对应map
std::map<std::string, std::string> m_map;
//! 省份对应map
std::map<string, string> m_map;
};
} /* \namespace easypr */

@ -12,8 +12,8 @@
#ifndef __CHARS_RECOGNISE_H__
#define __CHARS_RECOGNISE_H__
#include "chars_segment.h"
#include "chars_identify.h"
#include "easypr/chars_segment.h"
#include "easypr/chars_identify.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
@ -24,62 +24,54 @@ class CCharsRecognise {
public:
CCharsRecognise();
//! 字符分割与识别
int charsRecognise(cv::Mat, std::string&, int = 0);
//! 字符分割与识别
int charsRecognise(Mat, String&);
cv::string charsRecognise(cv::Mat plate);
string charsRecognise(Mat plate);
//! 装载ANN模型
void LoadANN(cv::string s);
//! 装载ANN模型
void LoadANN(string s);
//! 是否开启调试模式
//! 是否开启调试模式
inline void setCRDebug(int param) { m_charsSegment->setDebug(param); }
//! 获取调试模式状态
//! 获取调试模式状态
inline int getCRDebug() { return m_charsSegment->getDebug(); }
//! 获得车牌颜色
inline cv::string getPlateColor(cv::Mat input) const {
cv::string color = "未知";
//! 获得车牌颜色
inline string getPlateColor(Mat input) const {
string color = "未知";
Color result = getPlateType(input, true);
if (BLUE == result)
color = "蓝牌";
if (YELLOW == result)
color = "黄牌";
if (BLUE == result) color = "蓝牌";
if (YELLOW == result) color = "黄牌";
return color;
}
//! 设置变量
//! 设置变量
inline void setLiuDingSize(int param) {
m_charsSegment->setLiuDingSize(param);
}
inline void setColorThreshold(int param) {
m_charsSegment->setColorThreshold(param);
}
inline void setBluePercent(float param) {
m_charsSegment->setBluePercent(param);
}
inline float getBluePercent() const {
return m_charsSegment->getBluePercent();
}
inline void setWhitePercent(float param) {
m_charsSegment->setWhitePercent(param);
}
inline float getWhitePercent() const {
return m_charsSegment->getWhitePercent();
}
private:
//!字符分割
//!字符分割
CCharsSegment* m_charsSegment;
//! 字符识别
//! 字符识别
CCharsIdentify* m_charsIdentify;
};

@ -23,77 +23,71 @@ class CCharsSegment {
public:
CCharsSegment();
//! 字符分割
int charsSegment(cv::Mat, std::vector<cv::Mat>&);
//! 字符分割
int charsSegment(Mat, vector<Mat>&);
//! 字符尺寸验证
bool verifyCharSizes(cv::Mat r);
//! 字符尺寸验证
bool verifyCharSizes(Mat r);
//! 字符预处理
cv::Mat preprocessChar(cv::Mat in);
//! 字符预处理
Mat preprocessChar(Mat in);
//! 根据特殊车牌来构造猜测中文字符的位置和大小
cv::Rect GetChineseRect(const cv::Rect rectSpe);
//! 根据特殊车牌来构造猜测中文字符的位置和大小
Rect GetChineseRect(const Rect rectSpe);
//! 找出指示城市的字符的Rect例如苏A7003X就是A的位置
int GetSpecificRect(const std::vector<cv::Rect>& vecRect);
//! 找出指示城市的字符的Rect例如苏A7003X就是A的位置
int GetSpecificRect(const vector<Rect>& vecRect);
//! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
int RebuildRect(const std::vector<cv::Rect>& vecRect,
std::vector<cv::Rect>& outRect,
//! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
int RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect,
int specIndex);
//! 将Rect按位置从左到右进行排序
int SortRect(const std::vector<cv::Rect>& vecRect,
std::vector<cv::Rect>& out);
//! 将Rect按位置从左到右进行排序
int SortRect(const vector<Rect>& vecRect, vector<Rect>& out);
//! 设置变量
//! 设置变量
inline void setLiuDingSize(int param) { m_LiuDingSize = param; }
inline void setColorThreshold(int param) { m_ColorThreshold = param; }
inline void setBluePercent(float param) { m_BluePercent = param; }
inline float getBluePercent() const { return m_BluePercent; }
inline void setWhitePercent(float param) { m_WhitePercent = param; }
inline float getWhitePercent() const { return m_WhitePercent; }
//! 是否开启调试模式常量默认0代表关闭
//! 是否开启调试模式常量默认0代表关闭
static const int DEFAULT_DEBUG = 1;
//! preprocessChar所用常量
//! preprocessChar所用常量
static const int CHAR_SIZE = 20;
static const int HORIZONTAL = 1;
static const int VERTICAL = 0;
//! preprocessChar所用常量
//! preprocessChar所用常量
static const int DEFAULT_LIUDING_SIZE = 7;
static const int DEFAULT_MAT_WIDTH = 136;
static const int DEFAULT_COLORTHRESHOLD = 150;
//! 是否开启调试模式
//! 是否开启调试模式
inline void setDebug(int param) { m_debug = param; }
//! 获取调试模式状态
//! 获取调试模式状态
inline int getDebug() { return m_debug; }
private:
//!柳钉判断参数
//!柳钉判断参数
int m_LiuDingSize;
//!车牌大小参数
//!车牌大小参数
int m_theMatWidth;
//!车牌颜色判断参数
//!车牌颜色判断参数
int m_ColorThreshold;
float m_BluePercent;
float m_WhitePercent;
//! 是否开启调试模式0关闭非0开启
//! 是否开启调试模式0关闭非0开启
int m_debug;
};

@ -3,42 +3,52 @@
#include <opencv2/opencv.hpp>
namespace easypr {
enum Color{ BLUE, YELLOW };
//! 根据一幅图像与颜色模板获取对应的二值图
//! 输入RGB图像, 颜色模板(蓝色、黄色)
//! 输出灰度图只有0和255两个值255代表匹配0代表不匹配
cv::Mat colorMatch(const cv::Mat& src, cv::Mat& match, const Color r, const bool adaptive_minsv);
//! 判断一个车牌的颜色
//! 输入车牌mat与颜色模板
//! 返回true或fasle
bool plateColorJudge(const cv::Mat& src, const Color r, const bool adaptive_minsv);
bool bFindLeftRightBound(cv::Mat& bound_threshold,int& posLeft,int& posRight);
bool bFindLeftRightBound1(cv::Mat& bound_threshold,int& posLeft,int& posRight);
bool bFindLeftRightBound2(cv::Mat& bound_threshold,int& posLeft,int& posRight);
//去除车牌上方的钮钉
//计算每行元素的阶跃数如果小于X认为是柳丁将此行全部填0涂黑
//X的推荐值为可根据实际调整
bool clearLiuDing(cv::Mat& img);
void clearLiuDingOnly(cv::Mat& img);
void clearLiuDing(cv::Mat mask,int& top,int& bottom);
//! 获得车牌颜色
Color getPlateType(const cv::Mat& src, const bool adaptive_minsv);
//! 直方图均衡
cv::Mat histeq(cv::Mat in);
cv::Mat features(cv::Mat in, int sizeData);
int ThresholdOtsu(cv::Mat mat);
using namespace cv;
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
// !获取垂直和水平方向直方图
cv::Mat ProjectedHistogram(cv::Mat img, int t);
enum Color { BLUE, YELLOW, WHITE, UNKNOWN };
enum LocateType { SOBEL, COLOR, OTHER };
//! 根据一幅图像与颜色模板获取对应的二值图
//! 输入RGB图像, 颜色模板(蓝色、黄色)
//! 输出灰度图只有0和255两个值255代表匹配0代表不匹配
Mat colorMatch(const Mat& src, Mat& match, const Color r,
const bool adaptive_minsv);
//! 判断一个车牌的颜色
//! 输入车牌mat与颜色模板
//! 返回true或fasle
bool plateColorJudge(const Mat& src, const Color r, const bool adaptive_minsv,
float& percent);
bool bFindLeftRightBound(Mat& bound_threshold, int& posLeft, int& posRight);
bool bFindLeftRightBound1(Mat& bound_threshold, int& posLeft, int& posRight);
bool bFindLeftRightBound2(Mat& bound_threshold, int& posLeft, int& posRight);
//去除车牌上方的钮钉
//计算每行元素的阶跃数如果小于X认为是柳丁将此行全部填0涂黑
// X的推荐值为可根据实际调整
bool clearLiuDing(Mat& img);
void clearLiuDingOnly(Mat& img);
void clearLiuDing(Mat mask, int& top, int& bottom);
//! 获得车牌颜色
Color getPlateType(const Mat& src, const bool adaptive_minsv);
//! 直方图均衡
Mat histeq(Mat in);
Mat features(Mat in, int sizeData);
Rect GetCenterRect(Mat& in);
Mat CutTheRect(Mat& in, Rect& rect);
int ThresholdOtsu(Mat mat);
//! 获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t);
} /*! \namespace easypr*/

@ -5,43 +5,50 @@
// Author: liuruoze
// Copyright: liuruoze
// Desciption:
// Defines CPlate
// An abstract class for car plate.
//////////////////////////////////////////////////////////////////////////
#ifndef __PLATE_H__
#define __PLATE_H__
#include <opencv2/opencv.hpp>
#include "core_func.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CPlate {
public:
bool bColored;
//! 构造函数
CPlate();
//! 设置与读取变量
inline void setPlateMat(cv::Mat param) { m_plateMat = param; }
//! 设置与读取变量
inline void setPlateMat(Mat param) { m_plateMat = param; }
inline Mat getPlateMat() const { return m_plateMat; }
inline cv::Mat getPlateMat() const { return m_plateMat; }
inline void setPlatePos(RotatedRect param) { m_platePos = param; }
inline RotatedRect getPlatePos() const { return m_platePos; }
inline void setPlatePos(cv::RotatedRect param) { m_platePos = param; }
inline void setPlateStr(String param) { m_plateStr = param; }
inline String getPlateStr() const { return m_plateStr; }
inline cv::RotatedRect getPlatePos() const { return m_platePos; }
inline void setPlateStr(std::string param) { m_plateStr = param; }
inline std::string getPlateStr() const { return m_plateStr; }
inline void setPlateLocateType(LocateType param) { m_locateType = param; }
inline LocateType getPlateLocateType() const { return m_locateType; }
private:
//! 车牌的图块
cv::Mat m_plateMat;
//! 车牌的图块
Mat m_plateMat;
//! 车牌在原图的位置
RotatedRect m_platePos;
//! 车牌在原图的位置
cv::RotatedRect m_platePos;
//! 车牌字符串
String m_plateStr;
//! 车牌字符串
std::string m_plateStr;
//! 车牌定位的方法
LocateType m_locateType;
};
} /*! \namespace easypr*/

@ -13,8 +13,8 @@
#ifndef __PLATE_DETECT_H__
#define __PLATE_DETECT_H__
#include "plate_locate.h"
#include "plate_judge.h"
#include "easypr/plate_locate.h"
#include "easypr/plate_judge.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
@ -25,32 +25,32 @@ class CPlateDetect {
public:
CPlateDetect();
//! 车牌检测:车牌定位与判断
int plateDetect(cv::Mat, std::vector<cv::Mat>&, int index = 0);
//! 车牌检测:车牌定位与判断
int plateDetect(Mat, vector<Mat>&, int index = 0);
//! 深度车牌检测使用颜色与二次Sobel法综合
int plateDetectDeep(cv::Mat src, std::vector<CPlate>& resultVec,
//! 深度车牌检测使用颜色与二次Sobel法综合
int plateDetectDeep(Mat src, vector<CPlate>& resultVec,
bool showDetectArea = true, int index = 0);
int showResult(const cv::Mat& result);
//! 展示中间的结果
int showResult(const Mat& result);
//! 装载SVM模型
void LoadSVM(std::string s);
//! 装载SVM模型
void LoadSVM(string s);
//! 生活模式与工业模式切换
//! 生活模式与工业模式切换
inline void setPDLifemode(bool param) { m_plateLocate->setLifemode(param); }
//! 是否开启调试模式
//! 是否开启调试模式
inline void setPDDebug(int param) { m_plateLocate->setDebug(param); }
//! 获取调试模式状态
//! 获取调试模式状态
inline int getPDDebug() { return m_plateLocate->getDebug(); }
//! 设置与读取变量
//! 设置与读取变量
inline void setGaussianBlurSize(int param) {
m_plateLocate->setGaussianBlurSize(param);
}
inline int getGaussianBlurSize() const {
return m_plateLocate->getGaussianBlurSize();
}
@ -58,7 +58,6 @@ class CPlateDetect {
inline void setMorphSizeWidth(int param) {
m_plateLocate->setMorphSizeWidth(param);
}
inline int getMorphSizeWidth() const {
return m_plateLocate->getMorphSizeWidth();
}
@ -66,7 +65,6 @@ class CPlateDetect {
inline void setMorphSizeHeight(int param) {
m_plateLocate->setMorphSizeHeight(param);
}
inline int getMorphSizeHeight() const {
return m_plateLocate->getMorphSizeHeight();
}
@ -74,37 +72,32 @@ class CPlateDetect {
inline void setVerifyError(float param) {
m_plateLocate->setVerifyError(param);
}
inline float getVerifyError() const {
return m_plateLocate->getVerifyError();
}
inline void setVerifyAspect(float param) {
m_plateLocate->setVerifyAspect(param);
}
inline float getVerifyAspect() const {
return m_plateLocate->getVerifyAspect();
}
inline void setVerifyMin(int param) { m_plateLocate->setVerifyMin(param); }
inline void setVerifyMax(int param) { m_plateLocate->setVerifyMax(param); }
inline void setJudgeAngle(int param) { m_plateLocate->setJudgeAngle(param); }
inline void setMaxPlates(float param) { m_maxPlates = param; }
inline float getMaxPlates() const { return m_maxPlates; }
private:
//! 设置一幅图中最多有多少车牌
//! 设置一幅图中最多有多少车牌
int m_maxPlates;
//! 车牌定位
//! 车牌定位
CPlateLocate* m_plateLocate;
//! 车牌判断
//! 车牌判断
CPlateJudge* m_plateJudge;
};

@ -13,9 +13,9 @@
#ifndef __PLATE_JUDGE_H__
#define __PLATE_JUDGE_H__
#include "plate.h"
#include "feature.h"
#include "core_func.h"
#include "easypr/plate.h"
#include "easypr/feature.h"
#include "easypr/core_func.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
@ -26,28 +26,38 @@ class CPlateJudge {
public:
CPlateJudge();
//! 对多幅车牌进行SVM判断
int plateJudge(const std::vector<CPlate>&, std::vector<CPlate>&);
//! 对多幅车牌进行SVM判断
int plateJudge(const vector<CPlate>&, vector<CPlate>&);
//! 车牌判断
int plateJudge(const std::vector<cv::Mat>&, std::vector<cv::Mat>&);
//! 车牌判断
int plateJudge(const vector<Mat>&, vector<Mat>&);
//! 车牌判断(一副图像)
int plateJudge(const cv::Mat& inMat, int& result);
//! 车牌判断(一副图像)
int plateJudge(const Mat& inMat, int& result);
//! 直方图均衡
cv::Mat histeq(cv::Mat);
//! 直方图均衡
Mat histeq(Mat);
//! 装载SVM模型
void LoadModel(const char* model);
//! 装载SVM模型
void LoadModel();
//! 装载SVM模型
void LoadModel(string s);
//! 设置与读取模型路径
inline void setModelPath(string path) { m_path = path; }
inline string getModelPath() const { return m_path; }
private:
//使用的SVM模型
//! 使用的SVM模型
CvSVM svm;
// ! EasyPR的getFeatures回调函数
// 用于从车牌的image生成svm的训练特征features
//! EasyPR的getFeatures回调函数
//! 用于从车牌的image生成svm的训练特征features
svmCallback m_getFeatures;
//! 模型存储路径
string m_path;
};
} /*! \namespace easypr*/

File diff suppressed because it is too large Load Diff

@ -12,8 +12,8 @@
#ifndef __PLATE_RECOGNIZE_H__
#define __PLATE_RECOGNIZE_H__
#include "plate_detect.h"
#include "chars_recognise.h"
#include "easypr/plate_detect.h"
#include "easypr/chars_recognise.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
@ -24,20 +24,18 @@ class CPlateRecognize : public CPlateDetect, public CCharsRecognise {
public:
CPlateRecognize();
//! 车牌检测与字符识别
int plateRecognize(cv::Mat src, std::vector<std::string>& licenseVec);
//! 车牌检测与字符识别
int plateRecognize(cv::Mat src, std::vector<std::string>& licenseVec,
int index = 0);
//! 生活模式与工业模式切换
inline void setLifemode(bool param) {
CPlateDetect::setPDLifemode(param);
}
//! 生活模式与工业模式切换
inline void setLifemode(bool param) { CPlateDetect::setPDLifemode(param); }
//! 是否开启调试模式
//! 是否开启调试模式
inline void setDebug(int param) {
CPlateDetect::setPDDebug(param);
CCharsRecognise::setCRDebug(param);
}
};
} /* \namespace easypr */

@ -23,7 +23,6 @@
#endif
namespace easypr {
class Utils {
public:
static long getTimestamp();
@ -44,7 +43,7 @@ class Utils {
/*
* returns the smaller of the two numbers
*/
template<typename T>
template <typename T>
static T min(const T& v1, const T& v2) {
return (v1 < v2) ? v1 : v2;
}
@ -78,20 +77,17 @@ class Utils {
}
}
//! levenshtein距离用于计算两个车牌的距离
//EasyPR中用levenshtein距离衡量车牌识别与真实车牌的误差
template<class T>
template <class T>
static unsigned int levenshtein_distance(const T& s1, const T& s2) {
const size_t len1 = s1.size(), len2 = s2.size();
std::vector<unsigned int> col(len2 + 1), prevCol(len2 + 1);
for (unsigned int i = 0; i < prevCol.size(); i++)
prevCol[i] = i;
for (unsigned int i = 0; i < prevCol.size(); i++) prevCol[i] = i;
for (unsigned int i = 0; i < len1; i++) {
col[0] = i + 1;
for (unsigned int j = 0; j < len2; j++)
col[j + 1] = easypr::Utils::min(
easypr::Utils::min(prevCol[1 + j] + 1, col[j] + 1), \
easypr::Utils::min(prevCol[1 + j] + 1, col[j] + 1),
prevCol[j] + (s1[i] == s2[j] ? 0 : 1));
col.swap(prevCol);
}
@ -108,14 +104,10 @@ class Utils {
* if not, create it, then call cv::imwrite.
*/
static bool imwrite(const std::string& file, const cv::Mat& image);
};
typedef Utils utils;
} // namespace easypr
/// general_test_prepare.cpp中方法
int general_test();
#endif // EASYPR_UTIL_H_

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<IncludePath>$(OPENCV)\include;$(IncludePath)</IncludePath>
<LibraryPath Condition="'$(Platform)'=='Win32'">$(OPENCV)\x86\vc10\lib;$(LibraryPath)</LibraryPath>
<LibraryPath Condition="'$(Platform)'=='X64'">$(OPENCV)\x64\vc10\lib;$(LibraryPath)</LibraryPath>
<SourcePath>G:\opencv\opencv\sources;$(SourcePath)</SourcePath>
</PropertyGroup>
<ItemDefinitionGroup>
<Link Condition="'$(Configuration)'=='Debug'">
<AdditionalDependencies>opencv_calib3d248d.lib;opencv_contrib248d.lib;opencv_core248d.lib;opencv_features2d248d.lib;opencv_flann248d.lib;opencv_gpu248d.lib;opencv_highgui248d.lib;opencv_imgproc248d.lib;opencv_legacy248d.lib;opencv_ml248d.lib;opencv_nonfree248d.lib;opencv_objdetect248d.lib;opencv_ocl248d.lib;opencv_photo248d.lib;opencv_stitching248d.lib;opencv_superres248d.lib;opencv_ts248d.lib;opencv_video248d.lib;opencv_videostab248d.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Link Condition="'$(Configuration)'=='Release'">
<AdditionalDependencies>opencv_calib3d248.lib;opencv_contrib248.lib;opencv_core248.lib;opencv_features2d248.lib;opencv_flann248.lib;opencv_gpu248.lib;opencv_highgui248.lib;opencv_imgproc248.lib;opencv_legacy248.lib;opencv_ml248.lib;opencv_nonfree248.lib;opencv_objdetect248.lib;opencv_ocl248.lib;opencv_photo248.lib;opencv_stitching248.lib;opencv_superres248.lib;opencv_ts248.lib;opencv_video248.lib;opencv_videostab248.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save