SVM train without changing source files.

1.3
Micooz 10 years ago
parent c888179d81
commit ddaa31aaa0

@ -12,11 +12,8 @@ namespace easypr {
namespace api { namespace api {
const char* kDefaultSVMModel = "resources/model/svm.xml";
const char* kDefaultANNModel = "resourecs/model/ann.xml";
static bool plate_judge(const char* image,const char *model) { static bool plate_judge(const char* image,const char *model) {
Mat src = imread(image); cv::Mat src = cv::imread(image);
assert(!src.empty()); assert(!src.empty());
@ -30,7 +27,7 @@ static bool plate_judge(const char* image,const char *model) {
} }
static void plate_locate(const char* image, const bool life_mode = true) { static void plate_locate(const char* image, const bool life_mode = true) {
Mat src = imread(image); cv::Mat src = cv::imread(image);
assert(!src.empty()); assert(!src.empty());

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

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

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

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

@ -1,9 +1,8 @@
#ifndef __FEATURE_H__ #ifndef __FEATURE_H__
#define __FEATURE_H__ #define __FEATURE_H__
/*! \namespace easypr #include <opencv2/opencv.hpp>
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr { namespace easypr {
//! 获得车牌的特征数 //! 获得车牌的特征数

@ -10,40 +10,40 @@
#ifndef __PLATE_H__ #ifndef __PLATE_H__
#define __PLATE_H__ #define __PLATE_H__
#include "prep.h" #include <opencv2/opencv.hpp>
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr { namespace easypr {
class CPlate class CPlate {
{ public:
public: bool bColored;
bool bColored;
CPlate();
//! 设置与读取变量 CPlate();
inline void setPlateMat(Mat param){ m_plateMat = param; }
inline Mat getPlateMat() const{ return m_plateMat; }
inline void setPlatePos(RotatedRect param){ m_platePos = param; } //! 设置与读取变量
inline RotatedRect getPlatePos() const{ return m_platePos; } inline void setPlateMat(cv::Mat param) { m_plateMat = param; }
inline void setPlateStr(String param){ m_plateStr = param; } inline cv::Mat getPlateMat() const { return m_plateMat; }
inline String getPlateStr() const{ return m_plateStr; }
private: inline void setPlatePos(cv::RotatedRect param) { m_platePos = param; }
//! 车牌的图块
Mat m_plateMat;
//! 车牌在原图的位置 inline cv::RotatedRect getPlatePos() const { return m_platePos; }
RotatedRect m_platePos;
//! 车牌字符串 inline void setPlateStr(std::string param) { m_plateStr = param; }
String m_plateStr;
};
} /*! \namespace easypr*/ inline std::string getPlateStr() const { return m_plateStr; }
private:
//! 车牌的图块
cv::Mat m_plateMat;
//! 车牌在原图的位置
cv::RotatedRect m_platePos;
//! 车牌字符串
std::string m_plateStr;
};
} /*! \namespace easypr*/
#endif /* endif __PLATE_H__ */ #endif /* endif __PLATE_H__ */

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

@ -13,12 +13,10 @@
#ifndef __PLATE_JUDGE_H__ #ifndef __PLATE_JUDGE_H__
#define __PLATE_JUDGE_H__ #define __PLATE_JUDGE_H__
#include "prep.h"
#include "plate.h" #include "plate.h"
#include "feature.h" #include "feature.h"
#include "core_func.h" #include "core_func.h"
/*! \namespace easypr /*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides Namespace where all the C++ EasyPR functionality resides
*/ */
@ -29,16 +27,16 @@ class CPlateJudge {
CPlateJudge(); CPlateJudge();
//! 对多幅车牌进行SVM判断 //! 对多幅车牌进行SVM判断
int plateJudge(const vector<CPlate>&, vector<CPlate>&); int plateJudge(const std::vector<CPlate>&, std::vector<CPlate>&);
//! 车牌判断 //! 车牌判断
int plateJudge(const vector<Mat>&, vector<Mat>&); int plateJudge(const std::vector<cv::Mat>&, std::vector<cv::Mat>&);
//! 车牌判断(一副图像) //! 车牌判断(一副图像)
int plateJudge(const Mat& inMat, int& result); int plateJudge(const cv::Mat& inMat, int& result);
//! 直方图均衡 //! 直方图均衡
Mat histeq(Mat); cv::Mat histeq(cv::Mat);
//! 装载SVM模型 //! 装载SVM模型
void LoadModel(const char* model); void LoadModel(const char* model);

File diff suppressed because it is too large Load Diff

@ -12,8 +12,6 @@
#ifndef __PLATE_RECOGNIZE_H__ #ifndef __PLATE_RECOGNIZE_H__
#define __PLATE_RECOGNIZE_H__ #define __PLATE_RECOGNIZE_H__
#include "prep.h"
#include "plate_detect.h" #include "plate_detect.h"
#include "chars_recognise.h" #include "chars_recognise.h"
@ -27,7 +25,7 @@ class CPlateRecognize : public CPlateDetect, public CCharsRecognise {
CPlateRecognize(); CPlateRecognize();
//! 车牌检测与字符识别 //! 车牌检测与字符识别
int plateRecognize(Mat src, vector<string>& licenseVec); int plateRecognize(cv::Mat src, std::vector<std::string>& licenseVec);
//! 生活模式与工业模式切换 //! 生活模式与工业模式切换
inline void setLifemode(bool param) { inline void setLifemode(bool param) {

@ -1,35 +0,0 @@
#ifndef __PREP_H__
#define __PREP_H__
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#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__)
#endif
#include <iostream>
#include <fstream>
#include <assert.h>
#include <algorithm>
#include <cstdlib>
#include <time.h>
#include <math.h>
using namespace std;
using namespace cv;
#endif
/* endif __PREP_H__ */

@ -1,7 +1,3 @@
//
// Created by Micooz on 15/5/21.
//
#ifndef EASYPR_SVM_TRAIN_H #ifndef EASYPR_SVM_TRAIN_H
#define EASYPR_SVM_TRAIN_H #define EASYPR_SVM_TRAIN_H
@ -14,29 +10,50 @@ namespace easypr {
class Svm { class Svm {
public: public:
int train(bool dividePrepared = true, bool trainPrepared = true, typedef enum {
svmCallback getFeatures = getHistogramFeatures); kForward = 1, // correspond to "has plate"
kInverse = 0 // correspond to "no plate"
} Label;
void accuracy(cv::Mat& testingclasses_preditc, cv::Mat& testingclasses_real); Svm(const char* forward_data_folder, const char* inverse_data_folder);
void getNoPlateTest(std::vector<cv::Mat>& testingImages, void train(bool divide = true, bool train = true,
std::vector<int>& testingLabels); float divide_percentage = 0.7,
svmCallback getFeatures = getHistogramFeatures);
void getHasPlateTest(std::vector<cv::Mat>& testingImages, // void getNoPlateTest(std::vector<cv::Mat>& testingImages,
std::vector<int>& testingLabels); // std::vector<int>& testingLabels);
//
// void getHasPlateTest(std::vector<cv::Mat>& testingImages,
// std::vector<int>& testingLabels);
//
// void getNoPlateTrain(cv::Mat& trainingImages,
// std::vector<int>& trainingLabels,
// svmCallback getFeatures = getHisteqFeatures);
//
// void getHasPlateTrain(cv::Mat& trainingImages,
// std::vector<int>& trainingLabels,
// svmCallback getFeatures = getHisteqFeatures);
void getNoPlateTrain(cv::Mat& trainingImages, private:
std::vector<int>& trainingLabels, /*
svmCallback getFeatures = getHisteqFeatures); * divide images into train part and test part by percentage
*/
void divide(const char* images_folder, float percentage = 0.7);
void getHasPlateTrain(cv::Mat& trainingImages, void get_train();
std::vector<int>& trainingLabels,
svmCallback getFeatures = getHisteqFeatures);
void learn2NoPlate(float bound = 0.7); void get_test();
void learn2HasPlate(float bound = 0.7); const char* forward_;
const char* inverse_;
// these two variables are used for cv::CvSVM::train_auto()
cv::Mat classes_;
cv::Mat trainingData_;
// these two variables are used for cv::CvSVM::predict()
std::vector<cv::Mat> test_imgaes_;
std::vector<Label> test_labels_;
}; };

File diff suppressed because it is too large Load Diff

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

@ -4,6 +4,7 @@
Namespace where all the C++ EasyPR functionality resides Namespace where all the C++ EasyPR functionality resides
*/ */
namespace easypr{ namespace easypr{
using namespace cv;
const float DEFAULT_BLUEPERCEMT = 0.3; const float DEFAULT_BLUEPERCEMT = 0.3;
const float DEFAULT_WHITEPERCEMT = 0.1; const float DEFAULT_WHITEPERCEMT = 0.1;
@ -129,7 +130,7 @@ namespace easypr{
if (m_debug) if (m_debug)
{ {
stringstream ss(stringstream::in | stringstream::out); std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "tmp/debug_char_threshold" <<iTag<< ".jpg"; ss << "tmp/debug_char_threshold" <<iTag<< ".jpg";
imwrite(ss.str(), img_threshold); imwrite(ss.str(), img_threshold);
} }
@ -142,7 +143,7 @@ namespace easypr{
if (m_debug) if (m_debug)
{ {
stringstream ss(stringstream::in | stringstream::out); std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "tmp/debug_char_clearLiuDing" <<iTag<< ".jpg"; ss << "tmp/debug_char_clearLiuDing" <<iTag<< ".jpg";
imwrite(ss.str(), img_threshold); imwrite(ss.str(), img_threshold);
} }
@ -197,7 +198,7 @@ namespace easypr{
if (specIndex < sortedRect.size()) if (specIndex < sortedRect.size())
{ {
Mat specMat(img_threshold, sortedRect[specIndex]); Mat specMat(img_threshold, sortedRect[specIndex]);
stringstream ss(stringstream::in | stringstream::out); std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "tmp/debug_specMat" << ".jpg"; ss << "tmp/debug_specMat" << ".jpg";
imwrite(ss.str(), specMat); imwrite(ss.str(), specMat);
} }
@ -215,7 +216,7 @@ namespace easypr{
if (m_debug) if (m_debug)
{ {
Mat chineseMat(img_threshold, chineseRect); Mat chineseMat(img_threshold, chineseRect);
stringstream ss(stringstream::in | stringstream::out); std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "tmp/debug_chineseMat" << ".jpg"; ss << "tmp/debug_chineseMat" << ".jpg";
imwrite(ss.str(), chineseMat); imwrite(ss.str(), chineseMat);
} }
@ -242,7 +243,7 @@ namespace easypr{
auxRoi = preprocessChar(auxRoi); auxRoi = preprocessChar(auxRoi);
if (m_debug) if (m_debug)
{ {
stringstream ss(stringstream::in | stringstream::out); std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "tmp/debug_char_auxRoi_" << (i+staticIndex) << ".jpg"; ss << "tmp/debug_char_auxRoi_" << (i+staticIndex) << ".jpg";
imwrite(ss.str(), auxRoi); imwrite(ss.str(), auxRoi);
} }

File diff suppressed because it is too large Load Diff

@ -2,7 +2,6 @@
// 所属命名空间为easypr // 所属命名空间为easypr
// 这个部分中的特征由easypr的开发者修改 // 这个部分中的特征由easypr的开发者修改
#include "easypr/prep.h"
#include "easypr/feature.h" #include "easypr/feature.h"
#include "easypr/core_func.h" #include "easypr/core_func.h"
@ -11,80 +10,73 @@
*/ */
namespace easypr { namespace easypr {
//! 获取垂直和水平的直方图图值 //! 获取垂直和水平的直方图图值
Mat getTheFeatures(Mat in) cv::Mat getTheFeatures(cv::Mat in) {
{ const int VERTICAL = 0;
const int VERTICAL = 0; const int HORIZONTAL = 1;
const int HORIZONTAL = 1;
//Histogram features
//Histogram features cv::Mat vhist = ProjectedHistogram(in, VERTICAL);
Mat vhist = ProjectedHistogram(in, VERTICAL); cv::Mat hhist = ProjectedHistogram(in, HORIZONTAL);
Mat hhist = ProjectedHistogram(in, HORIZONTAL);
//Last 10 is the number of moments components
//Last 10 is the number of moments components int numCols = vhist.cols + hhist.cols;
int numCols = vhist.cols + hhist.cols;
cv::Mat out = cv::Mat::zeros(1, numCols, CV_32F);
Mat out = Mat::zeros(1, numCols, CV_32F);
//Asign values to feature,样本特征为水平、垂直直方图
//Asign values to feature,样本特征为水平、垂直直方图 int j = 0;
int j = 0; for (int i = 0; i < vhist.cols; i++) {
for (int i = 0; i<vhist.cols; i++) out.at<float>(j) = vhist.at<float>(i);
{ j++;
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);
for (int i = 0; i<hhist.cols; i++) j++;
{ }
out.at<float>(j) = hhist.at<float>(i);
j++; return out;
} }
return out;
} //! EasyPR的getFeatures回调函数
//! 本函数是生成直方图均衡特征的回调函数
void getHisteqFeatures(const cv::Mat& image, cv::Mat& features) {
//! EasyPR的getFeatures回调函数 features = histeq(image);
//! 本函数是生成直方图均衡特征的回调函数 }
void getHisteqFeatures(const Mat& image, Mat& features)
{ //! EasyPR的getFeatures回调函数
features = histeq(image); //! 本函数是获取垂直和水平的直方图图值
} void getHistogramFeatures(const cv::Mat& image, cv::Mat& features) {
cv::Mat grayImage;
//! EasyPR的getFeatures回调函数 cvtColor(image, grayImage, CV_RGB2GRAY);
//! 本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const Mat& image, Mat& features) //grayImage = histeq(grayImage);
{
Mat grayImage; cv::Mat img_threshold;
cvtColor(image, grayImage, CV_RGB2GRAY); threshold(grayImage, img_threshold, 0, 255,
CV_THRESH_OTSU + CV_THRESH_BINARY);
//grayImage = histeq(grayImage); features = getTheFeatures(img_threshold);
}
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 cv::Mat& image, cv::Mat& features) {
//待完善
//! EasyPR的getFeatures回调函数 }
//! 本函数是获取SITF特征子
void getSIFTFeatures(const Mat& image, Mat& features)
{ //! EasyPR的getFeatures回调函数
//待完善 //! 本函数是获取HOG特征子
} void getHOGFeatures(const cv::Mat& image, cv::Mat& features) {
//待完善
}
//! EasyPR的getFeatures回调函数
//! 本函数是获取HOG特征子 //! EasyPR的getFeatures回调函数
void getHOGFeatures(const Mat& image, Mat& features) //! 本函数是获取HSV空间量化的直方图特征子
{ void getHSVHistFeatures(const cv::Mat& image, cv::Mat& features) {
//待完善 //TODO
} }
//! EasyPR的getFeatures回调函数 } /* \namespace easypr */
//! 本函数是获取HSV空间量化的直方图特征子
void getHSVHistFeatures(const Mat& image, Mat& features)
{
//TODO
}
} /* \namespace easypr */

@ -5,6 +5,8 @@
*/ */
namespace easypr { namespace easypr {
using namespace cv;
CPlateDetect::CPlateDetect() { CPlateDetect::CPlateDetect() {
//cout << "CPlateDetect" << endl; //cout << "CPlateDetect" << endl;
m_plateLocate = new CPlateLocate(); m_plateLocate = new CPlateLocate();
@ -34,7 +36,7 @@ int CPlateDetect::plateDetect(Mat src, vector<Mat>& resultVec, int index) {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Mat img = resultVec[i]; Mat img = resultVec[i];
if (1) { if (1) {
stringstream ss(stringstream::in | stringstream::out); std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "tmp/plate_judge_result_" << i << ".jpg"; ss << "tmp/plate_judge_result_" << i << ".jpg";
imwrite(ss.str(), img); imwrite(ss.str(), img);
} }

@ -5,6 +5,8 @@
*/ */
namespace easypr { namespace easypr {
using namespace cv;
CPlateJudge::CPlateJudge() CPlateJudge::CPlateJudge()
: m_getFeatures(getHistogramFeatures) { : m_getFeatures(getHistogramFeatures) {
@ -47,7 +49,7 @@ int CPlateJudge::plateJudge(const Mat& inMat, int& result) {
p.convertTo(p, CV_32FC1); p.convertTo(p, CV_32FC1);
float response = svm.predict(p); float response = svm.predict(p);
result = (int)response; result = (int) response;
return 0; return 0;
} }

@ -5,6 +5,9 @@
*/ */
namespace easypr { namespace easypr {
using namespace cv;
using namespace std;
const float DEFAULT_ERROR = 0.6; const float DEFAULT_ERROR = 0.6;
//0.6 //0.6
const float DEFAULT_ASPECT = 3.75; //3.75 const float DEFAULT_ASPECT = 3.75; //3.75
@ -51,7 +54,7 @@ void CPlateLocate::setLifemode(bool param) {
//! 对minAreaRect获得的最小外接矩形用纵横比进行判断 //! 对minAreaRect获得的最小外接矩形用纵横比进行判断
bool CPlateLocate::verifySizes(RotatedRect mr) { bool CPlateLocate::verifySizes(cv::RotatedRect mr) {
float error = m_error; float error = m_error;
//Spain car plate size: 52x11 aspect 4,7272 //Spain car plate size: 52x11 aspect 4,7272
//China car plate size: 440mm*140mmaspect 3.142857 //China car plate size: 440mm*140mmaspect 3.142857

@ -5,6 +5,9 @@
*/ */
namespace easypr { namespace easypr {
using namespace cv;
using namespace std;
CPlateRecognize::CPlateRecognize() { CPlateRecognize::CPlateRecognize() {
} }

@ -7,6 +7,8 @@
#include "easypr/feature.h" #include "easypr/feature.h"
using namespace easypr; using namespace easypr;
using namespace std;
using namespace cv;
extern const string GENERAL_TEST_PATH; extern const string GENERAL_TEST_PATH;

@ -133,7 +133,7 @@ void tag_data(const char* source_folder, const char* has_plate_folder,
size_t size = files.size(); size_t size = files.size();
if (0 == size) { if (0 == size) {
cout << "No file found in " << source_folder << endl; std::cout << "No file found in " << source_folder << std::endl;
return; return;
} }

@ -19,14 +19,12 @@
//#include <sys/io.h> //#include <sys/io.h>
#endif #endif
#include <stdlib.h>
#include <stdio.h>
#include "easypr/plate_recognize.h" #include "easypr/plate_recognize.h"
#include "easypr/feature.h"
#include "easypr/util.h" #include "easypr/util.h"
using namespace easypr; using namespace easypr;
using namespace cv;
using namespace std;
#define HORIZONTAL 1 #define HORIZONTAL 1
#define VERTICAL 0 #define VERTICAL 0
@ -45,7 +43,7 @@ const int numCharacter = 34;
//以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符 //以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符
//有些后面加数字2的表示在训练时常看到字符的一种变形也作为训练数据存储 //有些后面加数字2的表示在训练时常看到字符的一种变形也作为训练数据存储
const string strChinese[] = { const std::string strChinese[] = {
"zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \ "zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \
"zh_gan1"/*甘*/, "zh_gui"/* 贵 */, "zh_gui1"/* 桂 */, \ "zh_gan1"/*甘*/, "zh_gui"/* 贵 */, "zh_gui1"/* 桂 */, \
"zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \ "zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \

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

Loading…
Cancel
Save