Merge branch 'Micooz-master-gbk'

Conflicts:
	run_accuracy.txt
	src/core/chars_segment.cpp
1.3
liuruoze 10 years ago
commit 50de5ed2d6

9
.gitignore vendored

@ -187,3 +187,12 @@ UpgradeLog*.htm
# Microsoft Fakes
FakesAssemblies/
# idea IDE
.idea/
# XCode IDE
EasyPR.xcodeproj/
# Debug tmp files
image/tmp/

@ -93,6 +93,7 @@
<ClCompile Include="src\core\chars_segment.cpp" />
<ClCompile Include="src\core\features.cpp" />
<ClCompile Include="src\core\plate.cpp" />
<ClCompile Include="src\core\core_func.cpp" />
<ClCompile Include="src\test\accuracy_test.cpp" />
<ClCompile Include="src\train\ann_train.cpp" />
<ClCompile Include="src\train\svm_train.cpp" />
@ -121,6 +122,7 @@
<ClInclude Include="src\include\plate_judge.h" />
<ClInclude Include="src\include\plate_locate.h" />
<ClInclude Include="src\include\plate_recognize.h" />
<ClInclude Include="src\include\core_func.h" />
<ClInclude Include="src\include\prep.h" />
<ClInclude Include="src\include\util.h" />
</ItemGroup>

@ -93,6 +93,9 @@
<ClCompile Include="src\core\plate.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\core_func.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\include\chars_identify.h">
@ -131,5 +134,8 @@
<ClInclude Include="src\include\plate.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\core_func.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -5,46 +5,44 @@ EasyPR是一个中文的开源车牌识别系统其目标是成为一个简
相比于其他的车牌识别系统EasyPR有如下特点
* 它基于openCV这个开源库。这意味着你可以获取全部源代码并且移植到java等平台。
* 它基于openCV这个开源库。这意味着你可以获取全部源代码并且移植到opencv支持的所有平台。
* 它能够识别中文。例如车牌为苏EUK722的图片它可以准确地输出std:string类型的"苏EUK722"的结果。
* 它的识别率较高。图片清晰情况下车牌检测与字符识别可以达到90%以上的精度。
### 版本
EasyPR最开始是发布在[GitHub](https://github.com/liuruoze/EasyPR)上的,然后在国内的[oschina](http://git.oschina.net/easypr/EasyPR)上也部署了一份镜像。
相关的issue欢迎在GitHub上统一提交。目前除了windows版本以外还有以下其他平台的版本
|版本 | 开发者 | 地址
|------|-------|-------
| android | goldriver | [linuxxx/EasyPR_Android](https://github.com/linuxxx/EasyPR_Android)
| linux | Micooz | [Micooz/EasyPR/tree/linux-dev](https://github.com/Micooz/EasyPR/tree/linux-dev)
| ios | zhoushiwei | [zhoushiwei/EasyPR-iOS](https://github.com/zhoushiwei/EasyPR-iOS)
| mac | zhoushiwei | [zhoushiwei/EasyPR](https://github.com/zhoushiwei/EasyPR)
| c# | 暂无 |
| java | 暂无 |
感谢以上所有开发者的努力!
* 它的识别率较高。图片清晰情况下车牌检测与字符识别可以达到80%以上的精度。
### 更新
本版本是EasyPR 1.2版本相比前版本的主要改进是提升了车牌定位模块的准确性从上个版本70%左右的准确率提升到目前的94%。见下图:
![1.2版综合效果](doc/res/testresult.png)
主要内容如下:
* 1.车牌定位使用了“颜色信息”+“二次Sobel”的综合搜索方法。在下面的window中红框代表Sobel定位结果黄框代表颜色定位结果。
* 车牌定位使用了“颜色信息”+“二次Sobel”的综合搜索方法。在下面的window中红框代表Sobel定位结果黄框代表颜色定位结果。
* 2.“批量测试”功能增加了一个结果查看window这个窗口可以用SetDebug()方法开闭(true开false关)。
* “批量测试”增加了一个结果查看window这个窗口可以用SetDebug()方法开闭(true开false关)。
![查看结果](doc/res/window.png)
* 3.解决了“大角度定位”问题,见下图。原图中的车牌可以被定位并转换到正确的视角。
* 基本攻克了“大角度定位”问题,下图的车牌被定位并转到了正确的视角。
![大角度定位](doc/res/bigangle.png)
* 4.GDTS里新增了若干张新测试图包括数张大角度图。
* GDTS里新增了若干张新测试图包括数张大角度图。
* “批量测试”结果现在同时会保存在“run_accuracy”文件中可以查询历史运行信息。
* 与Linux版本做了整合可以实现跨平台编译。
### 平台
目前除了windows平台以外还有以下其他平台的EasyPR版本。一些平台的版本可能会暂时落后于主平台。
|版本 | 开发者 | 版本 | 地址
|------|-------|-------|-------
| android | goldriver | 1.1 | [linuxxx/EasyPR_Android](https://github.com/linuxxx/EasyPR_Android)
| linux | Micooz | 1.2 | 已跟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)
### 兼容性
@ -117,7 +115,7 @@ EasyPR不需要安装开发者直接在其上做改动。如果想使用DLL
| plate_recognize | 车牌识别,是车牌检测与字符识别的共有子类
| features | 特征提取回调函数
| plate | 车牌抽象
| prep.h | 预包含头文件
| core_func.h | 共有的一些函数
以下表格是src目录下一些辅助文件的解释与关系:
@ -130,10 +128,17 @@ EasyPR不需要安装开发者直接在其上做改动。如果想使用DLL
| svm_train.cpp | svm训练函数
| generate_gdts.cpp | GDTS生成函数
### 问题
### Contributer
* liuruoze作者与核心代码编写
* Micoozlinux平台编译性能优化util类
* jsxyheludeface版本一
* zhoushiweideface版本二
如果有任何问题或者建议请在issues里直接提交或者发emaileasypr_dev@163.com。
建议与问题一经采纳即会将您的贡献大名列入EasyPR的感谢名单 Credits )中。
* ahccom新的plateLocate函数
### 鸣谢

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

File diff suppressed because it is too large Load Diff

@ -1,50 +1,50 @@
#include "../include/chars_recognise.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr{
CCharsRecognise::CCharsRecognise()
{
//cout << "CCharsRecognise" << endl;
m_charsSegment = new CCharsSegment();
m_charsIdentify = new CCharsIdentify();
}
void CCharsRecognise::LoadANN(string s)
{
m_charsIdentify->LoadModel(s.c_str());
}
int CCharsRecognise::charsRecognise(Mat plate, string& plateLicense)
{
//车牌字符方块集合
vector<Mat> matVec;
CCharsRecognise::CCharsRecognise()
{
//cout << "CCharsRecognise" << endl;
m_charsSegment = new CCharsSegment();
m_charsIdentify = new CCharsIdentify();
}
string plateIdentify = "";
void CCharsRecognise::LoadANN(string s)
{
m_charsIdentify->LoadModel(s.c_str());
}
int result = m_charsSegment->charsSegment(plate, matVec);
if (result == 0)
int CCharsRecognise::charsRecognise(Mat plate, string& plateLicense)
{
int num = matVec.size();
for (int j = 0; j < num; j++)
{
Mat charMat = matVec[j];
bool isChinses = false;
//车牌字符方块集合
vector<Mat> matVec;
//默认首个字符块是中文字符
if (j == 0)
isChinses = true;
string plateIdentify = "";
string charcater = m_charsIdentify->charsIdentify(charMat, isChinses);
plateIdentify = plateIdentify + charcater;
int result = m_charsSegment->charsSegment(plate, matVec);
if (result == 0)
{
int num = matVec.size();
for (int j = 0; j < num; j++)
{
Mat charMat = matVec[j];
bool isChinses = false;
//默认首个字符块是中文字符
if (j == 0)
isChinses = true;
string charcater = m_charsIdentify->charsIdentify(charMat, isChinses);
plateIdentify = plateIdentify + charcater;
}
}
}
plateLicense = plateIdentify;
plateLicense = plateIdentify;
return 0;
}
return 0;
}
} /*! \namespace easypr*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -4,120 +4,87 @@
#include "../include/prep.h"
#include "../include/features.h"
#include "../include/core_func.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
//! 直方图均衡
Mat histeq(Mat in)
{
Mat out(in.size(), in.type());
if(in.channels()==3)
//! 获取垂直和水平的直方图图值
Mat getTheFeatures(Mat in)
{
Mat hsv;
vector<Mat> hsvSplit;
cvtColor(in, hsv, CV_BGR2HSV);
split(hsv, hsvSplit);
equalizeHist(hsvSplit[2], hsvSplit[2]);
merge(hsvSplit, hsv);
cvtColor(hsv, out, CV_HSV2BGR);
}
else if(in.channels()==1)
{
equalizeHist(in, out);
}
return out;
}
// !获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t)
{
int sz=(t)?img.rows:img.cols;
Mat mhist=Mat::zeros(1,sz,CV_32F);
for(int j=0; j<sz; j++){
Mat data=(t)?img.row(j):img.col(j);
mhist.at<float>(j)=countNonZero(data); //统计这一行或一列中非零元素的个数并保存到mhist中
const int VERTICAL = 0;
const int HORIZONTAL = 1;
//Histogram features
Mat vhist = ProjectedHistogram(in, VERTICAL);
Mat hhist = ProjectedHistogram(in, HORIZONTAL);
//Last 10 is the number of moments components
int numCols = vhist.cols + hhist.cols;
Mat out = Mat::zeros(1, numCols, CV_32F);
//Asign values to feature,样本特征为水平、垂直直方图
int j = 0;
for (int i = 0; i<vhist.cols; i++)
{
out.at<float>(j) = vhist.at<float>(i);
j++;
}
for (int i = 0; i<hhist.cols; i++)
{
out.at<float>(j) = hhist.at<float>(i);
j++;
}
return out;
}
//Normalize histogram
double min, max;
minMaxLoc(mhist, &min, &max);
if(max>0)
mhist.convertTo(mhist,-1 , 1.0f/max, 0);//用mhist直方图中的最大值归一化直方图
//! EasyPR的getFeatures回调函数
//! 本函数是生成直方图均衡特征的回调函数
void getHisteqFeatures(const Mat& image, Mat& features)
{
features = histeq(image);
}
return mhist;
}
//! EasyPR的getFeatures回调函数
//! 本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const Mat& image, Mat& features)
{
Mat grayImage;
cvtColor(image, grayImage, CV_RGB2GRAY);
//grayImage = histeq(grayImage);
//! 获得车牌的特征数
Mat getTheFeatures(Mat in)
{
const int VERTICAL = 0;
const int HORIZONTAL = 1;
Mat img_threshold;
threshold(grayImage, img_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
features = getTheFeatures(img_threshold);
}
//Histogram features
Mat vhist=ProjectedHistogram(in, VERTICAL);
Mat hhist=ProjectedHistogram(in, HORIZONTAL);
//Last 10 is the number of moments components
int numCols = vhist.cols + hhist.cols;
//! EasyPR的getFeatures回调函数
//! 本函数是获取SITF特征子
void getSIFTFeatures(const Mat& image, Mat& features)
{
//待完善
}
Mat out = Mat::zeros(1, numCols, CV_32F);
//Asign values to feature,样本特征为水平、垂直直方图
int j=0;
for(int i=0; i<vhist.cols; i++)
//! EasyPR的getFeatures回调函数
//! 本函数是获取HOG特征子
void getHOGFeatures(const Mat& image, Mat& features)
{
out.at<float>(j)=vhist.at<float>(i);
j++;
//待完善
}
for(int i=0; i<hhist.cols; i++)
//! EasyPR的getFeatures回调函数
//! 本函数是获取HSV空间量化的直方图特征子
void getHSVHistFeatures(const Mat& image, Mat& features)
{
out.at<float>(j)=hhist.at<float>(i);
j++;
//TODO
}
return out;
}
// ! EasyPR的getFeatures回调函数
// !本函数是生成直方图均衡特征的回调函数
void getHisteqFeatures(const Mat& image, Mat& features)
{
features = histeq(image);
}
// ! EasyPR的getFeatures回调函数
// !本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const Mat& image, Mat& features)
{
Mat grayImage;
cvtColor(image, grayImage, CV_RGB2GRAY);
//grayImage = histeq(grayImage);
Mat img_threshold;
threshold(grayImage, img_threshold, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY);
features = getTheFeatures(img_threshold);
}
// ! EasyPR的getFeatures回调函数
// 本函数是获取SITF特征子
// !
void getSIFTFeatures(const Mat& image, Mat& features)
{
//待完善
}
// ! EasyPR的getFeatures回调函数
// 本函数是获取HOG特征子
void getHOGFeatures(const Mat& image, Mat& features)
{
//待完善
}
} /* \namespace easypr */

@ -10,6 +10,9 @@ CPlateDetect::CPlateDetect()
//cout << "CPlateDetect" << endl;
m_plateLocate = new CPlateLocate();
m_plateJudge = new CPlateJudge();
// 默认EasyPR在一幅图中定位最多3个车
m_maxPlates = 3;
}
void CPlateDetect::LoadSVM(string s)
@ -65,7 +68,7 @@ int CPlateDetect::plateDetectDeep(Mat src, vector<Mat>& resultVec, bool showDete
vector<CPlate> all_result_Plates;
//如果颜色查找找到n个以上包含n个的车牌就不再进行Sobel查找了。
const int color_find_max = 4;
const int color_find_max = m_maxPlates;
Mat result;
src.copyTo(result);

File diff suppressed because it is too large Load Diff

@ -57,7 +57,7 @@ int CPlateRecognize::plateRecognize(Mat src, vector<string>& licenseVec)
Mat plate = plateVec[j];
//»ñÈ¡³µÅÆÑÕÉ«
string plateType = getPlateType(plate);
string plateType = getPlateColor(plate);
//»ñÈ¡³µÅƺÅ
string plateIdentify = "";

@ -1,11 +1,3 @@
//////////////////////////////////////////////////////////////////////////
// Name: CParser Header
// Date: 2015-02-05
// Author: Micooz
// Copyright: Micooz
// Desciption:
// Defines OptionError, CParseItem, CParser
//////////////////////////////////////////////////////////////////////////
#ifndef __CPARSER_H__
#define __CPARSER_H__
@ -15,32 +7,35 @@
#include <sstream>
#include <stdexcept>
// CParser can be used for parsing command line. It stores options and values to a map.
// It's easy to check whether an option exist, get value with a specified type.
namespace easypr {
// class OptionError
class OptionError : public std::exception
{
public:
explicit OptionError(const std::string &msg);
const char *what() const throw();
~OptionError() throw();
private:
std::string _msg;
};
// class CParseItem
class CParseItem
{
public:
explicit CParseItem(const std::string &val);
/*
* dynamic type cast, support base data types including std::string
* return T
@ -53,70 +48,70 @@ namespace easypr {
buf >> r;
return r;
}
/*
* alias of as<std::string>()
* return std::string
*/
std::string val() const;
private:
std::string _val;
};
// class CParser
typedef std::vector<std::string> ArgList;
typedef std::map<std::string, CParseItem *> ParseResult;
class CParser
{
public:
explicit CParser(int argc, char *argv[]);
/*
* parse the cmd line
* return ParseResult*
*/
ParseResult *parse();
/*
* check whether a cretain option exist
* return bool
*/
bool has(const char *key);
/*
* check whether a sequence of options exist
* example: has_or(3, "he", "or", "she");
* return bool
*/
bool has_or(int n, ...);
/*
* check whether a sequence of options exist
* example: has_and(3, "he", "and", "she");
* return bool
*/
bool has_and(int n, ...);
/*
* get the certain option's value
* return ParseItem*
*/
CParseItem *get(const std::string &key);
/*
* output all ParseResult
*/
void dump();
/*
* release memory allocated in parse()
*/
~CParser();
private:
ArgList _args;
ParseResult *_pr;

@ -18,55 +18,55 @@
#include "chars_identify.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CCharsRecognise
{
public:
CCharsRecognise();
class CCharsRecognise
{
public:
CCharsRecognise();
//! 字符分割与识别
int charsRecognise(Mat, String&);
//! 字符分割与识别
int charsRecognise(Mat, String&);
//! 装载ANN模型
void LoadANN(string s);
//! 装载ANN模型
void LoadANN(string s);
//! 是否开启调试模式
inline void setCRDebug(int param){ m_charsSegment->setDebug(param);}
//! 是否开启调试模式
inline void setCRDebug(int param){ m_charsSegment->setDebug(param); }
//! 获取调试模式状态
inline int getCRDebug(){ return m_charsSegment->getDebug();}
//! 获取调试模式状态
inline int getCRDebug(){ return m_charsSegment->getDebug(); }
//! 获得车牌颜色
inline string getPlateType(Mat input) const
{
string color = "未知";
int result = m_charsSegment->getPlateType(input);
if (1 == result)
color = "蓝牌";
if (2 == result)
color = "黄牌";
return color;
}
//! 获得车牌颜色
inline string getPlateColor(Mat input) const
{
string color = "未知";
Color result = getPlateType(input, true);
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();}
//! 设置变量
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;
private:
//!字符分割
CCharsSegment* m_charsSegment;
//! 字符识别
CCharsIdentify* m_charsIdentify;
};
//! 字符识别
CCharsIdentify* m_charsIdentify;
};
} /* \namespace easypr */

@ -13,101 +13,84 @@
#define __CHARS_SEGMENT_H__
#include "prep.h"
#include "core_func.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CCharsSegment
{
public:
enum Color { BLUE, YELLOW };
class CCharsSegment
{
public:
CCharsSegment();
CCharsSegment();
bool plateColorJudge(Mat src, Color r);
//! 字符分割
int charsSegment(Mat, vector<Mat>&);
//! 字符分割
int charsSegment(Mat, vector<Mat>& );
//! 字符尺寸验证
bool verifyCharSizes(Mat r);
//! 字符尺寸验证
bool verifySizes(Mat r);
//! 字符预处理
Mat preprocessChar(Mat in);
//! 字符预处理
Mat preprocessChar(Mat in);
//! 根据特殊车牌来构造猜测中文字符的位置和大小
Rect GetChineseRect(const Rect rectSpe);
//! 生成直方图
Mat ProjectedHistogram(Mat img, int t);
//! 找出指示城市的字符的Rect例如苏A7003X就是A的位置
int GetSpecificRect(const vector<Rect>& vecRect);
//! 生成字符的特定特征
Mat features(Mat in, int sizeData);
//! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
int RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect, int specIndex);
//! 直方图均衡,为判断车牌颜色做准备
Mat histeq(Mat in);
//! 将Rect按位置从左到右进行排序
int SortRect(const vector<Rect>& vecRect, vector<Rect>& out);
//! 获得车牌颜色
int getPlateType(Mat input);
//! 设置变量
inline void setLiuDingSize(int param){ m_LiuDingSize = param; }
inline void setColorThreshold(int param){ m_ColorThreshold = param; }
//! 去除影响字符识别的柳钉
Mat clearLiuDing(Mat img);
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; }
//! 根据特殊车牌来构造猜测中文字符的位置和大小
Rect GetChineseRect(const Rect rectSpe);
//! 是否开启调试模式常量默认0代表关闭
static const int DEFAULT_DEBUG = 0;
//! 找出指示城市的字符的Rect例如苏A7003X就是A的位置
int GetSpecificRect(const vector<Rect>& vecRect);
//! preprocessChar所用常量
static const int CHAR_SIZE = 20;
static const int HORIZONTAL = 1;
static const int VERTICAL = 0;
//! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
int RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect, int specIndex);
//! preprocessChar所用常量
static const int DEFAULT_LIUDING_SIZE = 7;
static const int DEFAULT_MAT_WIDTH = 136;
static const int DEFAULT_COLORTHRESHOLD = 150;
//! 将Rect按位置从左到右进行排序
int SortRect(const vector<Rect>& vecRect, vector<Rect>& out);
//! 是否开启调试模式
inline void setDebug(int param){ m_debug = param; }
//! 设置变量
inline void setLiuDingSize(int param){ m_LiuDingSize = param;}
inline void setColorThreshold(int param){ m_ColorThreshold = param;}
//! 获取调试模式状态
inline int getDebug(){ return m_debug; }
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;}
private:
//!柳钉判断参数
int m_LiuDingSize;
//! 是否开启调试模式常量默认0代表关闭
static const int DEFAULT_DEBUG = 0;
//!车牌大小参数
int m_theMatWidth;
//! preprocessChar所用常量
static const int CHAR_SIZE = 20;
static const int HORIZONTAL = 1;
static const int VERTICAL = 0;
//!车牌颜色判断参数
int m_ColorThreshold;
float m_BluePercent;
float m_WhitePercent;
//! 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开启
int m_debug;
};
//! 是否开启调试模式0关闭非0开启
int m_debug;
};
} /* \namespace easypr */

@ -0,0 +1,39 @@
#ifndef __CORE_FUNC_H__
#define __CORE_FUNC_H__
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
enum Color{ BLUE, YELLOW };
//! 根据一幅图像与颜色模板获取对应的二值图
//! 输入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);
//clearLiuDing
//去除车牌上方的钮钉
//计算每行元素的阶跃数如果小于X认为是柳丁将此行全部填0涂黑
//X的推荐值为可根据实际调整
Mat clearLiuDing(Mat img);
//! 获得车牌颜色
Color getPlateType(const Mat& src, const bool adaptive_minsv);
//! 直方图均衡
Mat histeq(Mat in);
// !获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t);
} /*! \namespace easypr*/
#endif
/* endif __CORE_FUNC_H__ */

@ -6,34 +6,29 @@
*/
namespace easypr {
//! 直方图均衡
Mat histeq(Mat in);
//! 获得车牌的特征数
Mat getTheFeatures(Mat in);
// !获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t);
//! EasyPR的getFeatures回调函数
//! 用于从车牌的image生成svm的训练特征features
typedef void(*svmCallback)(const Mat& image, Mat& features);
//! 获得车牌的特征数
Mat getTheFeatures(Mat in);
//! EasyPR的getFeatures回调函数
//! 本函数是生成直方图均衡特征的回调函数
void getHisteqFeatures(const Mat& image, Mat& features);
// ! EasyPR的getFeatures回调函数
// 用于从车牌的image生成svm的训练特征features
typedef void(*svmCallback)(const Mat& image, Mat& features);
//! EasyPR的getFeatures回调函数
//! 本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const Mat& image, Mat& features);
// ! EasyPR的getFeatures回调函数
// !本函数是生成直方图均衡特征的回调函数
void getHisteqFeatures(const Mat& image, Mat& features);
// ! EasyPR的getFeatures回调函数
// !本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const Mat& image, Mat& features);
// 本函数是获取SIFT特征子
void getSIFTFeatures(const Mat& image, Mat& features);
// 本函数是获取HOG特征子
void getHOGFeatures(const Mat& image, Mat& features);
//! 本函数是获取SIFT特征子
void getSIFTFeatures(const Mat& image, Mat& features);
//! 本函数是获取HOG特征子
void getHOGFeatures(const Mat& image, Mat& features);
//! 本函数是获取HSV空间量化的直方图特征子
void getHSVHistFeatures(const Mat& image, Mat& features);
} /*! \namespace easypr*/

@ -69,8 +69,14 @@ public:
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;
//! łľĹĆĹĐśĎ

@ -14,8 +14,9 @@
#define __PLATE_JUDGE_H__
#include "prep.h"
#include "features.h"
#include "plate.h"
#include "features.h"
#include "core_func.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides

@ -16,6 +16,7 @@
#include "prep.h"
#include "plate.h"
#include "core_func.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
@ -28,7 +29,6 @@ public:
CPlateLocate();
enum LocateType { SOBEL, COLOR };
enum Color { BLUE, YELLOW };
//! Sobel第一次搜索
//! 不限制大小和形状获取的BoundRect进入下一步
@ -65,24 +65,13 @@ public:
int plateSobelLocate(Mat src, vector<CPlate>& candPlates, int index = 0);
//! Color搜索
int colorMatch(const Mat& src, const Color r, Mat& out, vector<RotatedRect>& outRects, int index = 0);
int colorSearch(const Mat& src, const Color r, Mat& out, vector<RotatedRect>& outRects, int index = 0);
//! 未使用函数与代码
//! 开始------------
int sobelFind(const Mat& src, vector<RotatedRect>& rects);
int sobelFindAgn(const Mat& src, vector<RotatedRect>& outRects, vector<Mat>& resultVec);
bool charJudge(Mat roi);
bool sobelJudge(Mat roi);
int colorJudge(const Mat& src, const Color r, vector<RotatedRect>& rects);
int deskewOld(Mat src, vector<RotatedRect>& inRects, vector<RotatedRect>& outRects, vector<Mat>& outMats, LocateType locateType);
bool verifyCharSizes(Mat r);
int getPlateType(Mat src);
bool plateColorJudge(Mat src, const Color r);
Mat clearLiuDing(Mat img);
//! 结束------------
//! 未使用函数与代码

@ -7,10 +7,19 @@
#include "opencv2/nonfree/features2d.hpp"
#include "opencv/cvaux.h"
#if defined (WIN32) || defined (_WIN32)
#include <objbase.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#if defined (WIN32) || defined (_WIN32)
#include <io.h>
#elif defined (linux) || defined (__linux__)
#include <sys/io.h>
#endif
#include <iostream>
#include <fstream>
#include <assert.h>
@ -23,4 +32,4 @@ using namespace std;
using namespace cv;
#endif
/* endif __PREP_H__ */
/* endif __PREP_H__ */

@ -2,28 +2,55 @@
#ifndef __UTIL_H__
#define __UTIL_H__
//C++的获取文件夹函数
void getFiles(string path, vector<string>& files);
#ifdef min
#undef min
#endif
//C++的spilt函数
void SplitString(const string& s, vector<string>& v, const string& c);
namespace easypr {
class Utils {
public:
static long getTimestamp();
/*
* Get file name from a given path
* bool postfix: including the postfix
*/
static std::string getFileName(const std::string &path, const bool postfix = false);
/*
* Split the given string into segements by a delimiter
*/
static std::vector<std::string> splitString(const std::string &str, const char delimiter);
/*
* returns the smaller of the two numbers
*/
template<typename T>
static T min(const T &v1, const T &v2) {
return (v1 < v2) ? v1 : v2;
}
};
}
//C++的从文件路径名称到文件名称(不包括后缀)的方法
void getFileName(const string& filepath, string& name);
//C++µÄ»ñÈ¡Îļþ¼Ðº¯Êý
void getFiles(std::string path, std::vector<std::string>& files);
//! levenshtein距离用于计算两个车牌的距离
//EasyPR中用levenshtein距离衡量车牌识别与真实车牌的误差
template<class T>
unsigned int levenshtein_distance(const T &s1, const T & s2) {
const size_t len1 = s1.size(), len2 = s2.size();
vector<unsigned int> col(len2+1), prevCol(len2+1);
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 < len1; i++) {
col[0] = i+1;
for (unsigned int j = 0; j < len2; j++)
col[j+1] = min( min(prevCol[1 + j] + 1, col[j] + 1), \
col[j+1] = easypr::Utils::min(easypr::Utils::min(prevCol[1 + j] + 1, col[j] + 1), \
prevCol[j] + (s1[i]==s2[j] ? 0 : 1) );
col.swap(prevCol);
}
@ -35,13 +62,13 @@ unsigned int levenshtein_distance(const T &s1, const T & s2) {
int testMain();
/// accuracy_test.cpp中方法
int acurayTest(const string&);
int acurayTest(const std::string&);
/// mc_data_prepare.cpp中方法
void getLearnData();
void Code2Province(const string& code, string& province);
void Code2Province(const std::string& code, std::string& province);
void changeFileName();
void getPlateLicense(const string& filepath, string& plateLicense);
void getPlateLicense(const std::string& filepath, std::string& plateLicense);
/// learn_prepare.cpp中方法
void label_data();
@ -60,4 +87,4 @@ int deface();
int generate_gdts();
#endif
/* endif __UTIL_H__ */
/* endif __UTIL_H__ */

File diff suppressed because it is too large Load Diff

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

Loading…
Cancel
Save