SVM train without changing source files.

1.3
Micooz 10 years ago
parent c888179d81
commit ddaa31aaa0

@ -12,11 +12,8 @@ namespace easypr {
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) {
Mat src = imread(image);
cv::Mat src = cv::imread(image);
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) {
Mat src = imread(image);
cv::Mat src = cv::imread(image);
assert(!src.empty());

@ -12,49 +12,50 @@
#ifndef __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 {
class CCharsIdentify
{
public:
CCharsIdentify();
//! 字符鉴别
string charsIdentify(Mat, bool, bool);
string charsIdentify(Mat input);
class CCharsIdentify {
public:
CCharsIdentify();
//! 字符分类
int classify(Mat, bool,bool);
int classify(Mat f);
//! 装载ANN模型
void LoadModel();
//! 字符鉴别
std::string charsIdentify(cv::Mat, bool, bool);
//! 装载ANN模型
void LoadModel(string s);
std::string charsIdentify(cv::Mat input);
//! 设置与读取模型路径
inline void setModelPath(string path){ m_path = path; }
inline string getModelPath() const{ return m_path; }
//! 字符分类
int classify(cv::Mat, bool, bool);
private:
//使用的ANN模型
CvANN_MLP ann;
int classify(cv::Mat f);
//! 模型存储路径
string m_path;
//! 装载ANN模型
void LoadModel();
//! 特征尺寸
int m_predictSize;
//! 装载ANN模型
void LoadModel(std::string s);
//! 省份对应map
map<string, string> m_map;
//! 设置与读取模型路径
inline void setModelPath(std::string path) { m_path = path; }
inline std::string getModelPath() const { return m_path; }
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__ */

@ -12,8 +12,6 @@
#ifndef __CHARS_RECOGNISE_H__
#define __CHARS_RECOGNISE_H__
#include "prep.h"
#include "chars_segment.h"
#include "chars_identify.h"
@ -22,54 +20,69 @@ Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CCharsRecognise
{
public:
CCharsRecognise();
class CCharsRecognise {
public:
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 setCRDebug(int param){ m_charsSegment->setDebug(param); }
inline void setColorThreshold(int param) {
m_charsSegment->setColorThreshold(param);
}
//! 获取调试模式状态
inline int getCRDebug(){ return m_charsSegment->getDebug(); }
inline void setBluePercent(float param) {
m_charsSegment->setBluePercent(param);
}
inline float getBluePercent() const {
return m_charsSegment->getBluePercent();
}
//! 获得车牌颜色
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 setWhitePercent(float param) {
m_charsSegment->setWhitePercent(param);
}
//! 设置变量
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 float getWhitePercent() const {
return m_charsSegment->getWhitePercent();
}
private:
//!字符分割
CCharsSegment* m_charsSegment;
private:
//!字符分割
CCharsSegment* m_charsSegment;
//! 字符识别
CCharsIdentify* m_charsIdentify;
};
//! 字符识别
CCharsIdentify* m_charsIdentify;
};
} /* \namespace easypr */
} /* \namespace easypr */
#endif /* endif __CHARS_RECOGNISE_H__ */

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

@ -1,9 +1,8 @@
#ifndef __CORE_FUNC_H__
#define __CORE_FUNC_H__
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
#include <opencv2/opencv.hpp>
namespace easypr {
enum Color{ BLUE, YELLOW };
@ -11,35 +10,35 @@ namespace easypr {
//! 根据一幅图像与颜色模板获取对应的二值图
//! 输入RGB图像, 颜色模板(蓝色、黄色)
//! 输出灰度图只有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与颜色模板
//! 返回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 bFindLeftRightBound1(Mat& bound_threshold,int& posLeft,int& posRight);
bool bFindLeftRightBound2(Mat& bound_threshold,int& posLeft,int& posRight);
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(Mat& img);
void clearLiuDingOnly(Mat& img);
void clearLiuDing(Mat mask,int& top,int& bottom);
bool clearLiuDing(cv::Mat& img);
void clearLiuDingOnly(cv::Mat& img);
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);
Mat features(Mat in, int sizeData);
int ThresholdOtsu(Mat mat);
cv::Mat histeq(cv::Mat in);
cv::Mat features(cv::Mat in, int sizeData);
int ThresholdOtsu(cv::Mat mat);
// !获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t);
cv::Mat ProjectedHistogram(cv::Mat img, int t);
} /*! \namespace easypr*/

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

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

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

@ -13,12 +13,10 @@
#ifndef __PLATE_JUDGE_H__
#define __PLATE_JUDGE_H__
#include "prep.h"
#include "plate.h"
#include "feature.h"
#include "core_func.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
@ -29,16 +27,16 @@ class CPlateJudge {
CPlateJudge();
//! 对多幅车牌进行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模型
void LoadModel(const char* model);

File diff suppressed because it is too large Load Diff

@ -12,8 +12,6 @@
#ifndef __PLATE_RECOGNIZE_H__
#define __PLATE_RECOGNIZE_H__
#include "prep.h"
#include "plate_detect.h"
#include "chars_recognise.h"
@ -27,7 +25,7 @@ class CPlateRecognize : public CPlateDetect, public CCharsRecognise {
CPlateRecognize();
//! 车牌检测与字符识别
int plateRecognize(Mat src, vector<string>& licenseVec);
int plateRecognize(cv::Mat src, std::vector<std::string>& licenseVec);
//! 生活模式与工业模式切换
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
#define EASYPR_SVM_TRAIN_H
@ -14,29 +10,50 @@ namespace easypr {
class Svm {
public:
int train(bool dividePrepared = true, bool trainPrepared = true,
svmCallback getFeatures = getHistogramFeatures);
typedef enum {
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,
std::vector<int>& testingLabels);
void train(bool divide = true, bool train = true,
float divide_percentage = 0.7,
svmCallback getFeatures = getHistogramFeatures);
void getHasPlateTest(std::vector<cv::Mat>& testingImages,
std::vector<int>& testingLabels);
// void getNoPlateTest(std::vector<cv::Mat>& testingImages,
// 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,
std::vector<int>& trainingLabels,
svmCallback getFeatures = getHisteqFeatures);
private:
/*
* 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,
std::vector<int>& trainingLabels,
svmCallback getFeatures = getHisteqFeatures);
void get_train();
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 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());
}
string CCharsRecognise::charsRecognise(Mat plate)
{
return m_charsIdentify->charsIdentify(plate);
}
int CCharsRecognise::charsRecognise(Mat plate, string& plateLicense, int index)
{
//车牌字符方块集合
vector<Mat> matVec;
string plateIdentify = "";
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;
bool isSpeci=false;
//默认首个字符块是中文字符
if (j == 0)
isChinses = true;
if(j==1)
isSpeci=true;
string charcater = m_charsIdentify->charsIdentify(charMat, isChinses,isSpeci);
plateIdentify = plateIdentify + charcater;
}
}
plateLicense = plateIdentify;
if (plateLicense.size() < 7)
{
return -1;
}
return result;
}
} /*! \namespace easypr*/
namespace easypr {
CCharsRecognise::CCharsRecognise() {
//cout << "CCharsRecognise" << endl;
m_charsSegment = new CCharsSegment();
m_charsIdentify = new CCharsIdentify();
}
void CCharsRecognise::LoadANN(std::string s) {
m_charsIdentify->LoadModel(s.c_str());
}
std::string CCharsRecognise::charsRecognise(cv::Mat plate) {
return m_charsIdentify->charsIdentify(plate);
}
int CCharsRecognise::charsRecognise(cv::Mat plate, std::string& plateLicense,
int index) {
//车牌字符方块集合
std::vector<cv::Mat> matVec;
std::string plateIdentify = "";
int result = m_charsSegment->charsSegment(plate, matVec);
if (result == 0) {
size_t num = matVec.size();
for (int j = 0; j < num; j++) {
cv::Mat charMat = matVec[j];
bool isChinses = false;
bool isSpeci = false;
//默认首个字符块是中文字符
if (j == 0)
isChinses = true;
if (j == 1)
isSpeci = true;
std::string charcater = m_charsIdentify
->charsIdentify(charMat, isChinses, isSpeci);
plateIdentify = plateIdentify + charcater;
}
}
plateLicense = plateIdentify;
if (plateLicense.size() < 7) {
return -1;
}
return result;
}
} /*! \namespace easypr*/

@ -4,6 +4,7 @@
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr{
using namespace cv;
const float DEFAULT_BLUEPERCEMT = 0.3;
const float DEFAULT_WHITEPERCEMT = 0.1;
@ -129,7 +130,7 @@ namespace easypr{
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";
imwrite(ss.str(), img_threshold);
}
@ -142,7 +143,7 @@ namespace easypr{
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";
imwrite(ss.str(), img_threshold);
}
@ -197,7 +198,7 @@ namespace easypr{
if (specIndex < sortedRect.size())
{
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";
imwrite(ss.str(), specMat);
}
@ -215,7 +216,7 @@ namespace easypr{
if (m_debug)
{
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";
imwrite(ss.str(), chineseMat);
}
@ -242,7 +243,7 @@ namespace easypr{
auxRoi = preprocessChar(auxRoi);
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";
imwrite(ss.str(), auxRoi);
}

File diff suppressed because it is too large Load Diff

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

@ -5,6 +5,8 @@
*/
namespace easypr {
using namespace cv;
CPlateDetect::CPlateDetect() {
//cout << "CPlateDetect" << endl;
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++) {
Mat img = resultVec[i];
if (1) {
stringstream ss(stringstream::in | stringstream::out);
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "tmp/plate_judge_result_" << i << ".jpg";
imwrite(ss.str(), img);
}

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

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

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

@ -7,6 +7,8 @@
#include "easypr/feature.h"
using namespace easypr;
using namespace std;
using namespace cv;
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();
if (0 == size) {
cout << "No file found in " << source_folder << endl;
std::cout << "No file found in " << source_folder << std::endl;
return;
}

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