* remove some chinese text or convert a few improtant chinese to english.

* remove some not used header files.
v1.6alpha
liuruoze 9 years ago
parent 9a85c7e84d
commit 96b7865b1c

@ -10,8 +10,7 @@
#ifndef EASYPR_CORE_CHARACTER_H_
#define EASYPR_CORE_CHARACTER_H_
#include <opencv2/opencv.hpp>
#include "opencv2/opencv.hpp"
using namespace cv;

@ -1,11 +1,12 @@
#ifndef EASYPR_CORE_CHARSIDENTIFY_H_
#define EASYPR_CORE_CHARSIDENTIFY_H_
#include "easypr/util/kv.h"
#include "easypr/core/character.hpp"
#include <memory>
#include "opencv2/opencv.hpp"
#include "easypr/util/kv.h"
#include "easypr/core/character.hpp"
namespace easypr {
class CharsIdentify {

@ -14,7 +14,7 @@
#include "easypr/core/chars_segment.h"
#include "easypr/core/chars_identify.h"
#include "easypr/core/character.hpp"
#include "easypr/core/core_func.h"
#include "easypr/util/util.h"
#include "easypr/core/plate.hpp"
#include "easypr/config.h"
@ -30,8 +30,6 @@ class CCharsRecognise {
int charsRecognise(cv::Mat plate, std::string& plateLicense);
int charsRecognise(CPlate& plate, std::string& plateLicense);
//! 获得车牌颜色
inline std::string getPlateColor(cv::Mat input) const {
std::string color = "未知";
Color result = getPlateType(input, true);
@ -55,7 +53,6 @@ class CCharsRecognise {
return color;
}
//! 设置变量
inline void setLiuDingSize(int param) {
m_charsSegment->setLiuDingSize(param);
}

@ -1,7 +1,10 @@
#ifndef EASYPR_CORE_CHARSSEGMENT_H_
#define EASYPR_CORE_CHARSSEGMENT_H_
#include "easypr/core/core_func.h"
#include "opencv2/opencv.hpp"
#include "easypr/config.h"
using namespace cv;
namespace easypr {
@ -9,42 +12,30 @@ class CCharsSegment {
public:
CCharsSegment();
//! 字符分割
int charsSegment(Mat input, std::vector<Mat>& resultVec, Color color = BLUE);
//! 字符尺寸验证
bool verifyCharSizes(Mat r);
// find the best chinese binaranzation method
void judgeChinese(Mat in, Mat& out, Color plateType);
//! 字符预处理
Mat preprocessChar(Mat in);
//! 根据特殊车牌来构造猜测中文字符的位置和大小
//! to find the position of chinese
Rect GetChineseRect(const Rect rectSpe);
//! 找出指示城市的字符的Rect例如苏A7003X就是A的位置
//! find the character refer to city, like "suA" A
int GetSpecificRect(const std::vector<Rect>& vecRect);
//! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
//! Do two things
// 1.remove rect in the left of city character
// 2.from the city rect, to the right, choose 6 rects
int RebuildRect(const std::vector<Rect>& vecRect, std::vector<Rect>& outRect,
int specIndex);
//! 将Rect按位置从左到右进行排序
int SortRect(const std::vector<Rect>& vecRect, std::vector<Rect>& out);
//! 设置变量
inline void setLiuDingSize(int param) { m_LiuDingSize = param; }
inline void setColorThreshold(int param) { m_ColorThreshold = param; }
@ -53,48 +44,30 @@ class CCharsSegment {
inline void setWhitePercent(float param) { m_WhitePercent = param; }
inline float getWhitePercent() const { return m_WhitePercent; }
//! 是否开启调试模式常量默认0代表关闭
static const int DEFAULT_DEBUG = 1;
//! preprocessChar所用常量
static const int CHAR_SIZE = 20;
static const int HORIZONTAL = 1;
static const int VERTICAL = 0;
//! 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;
};

@ -1,7 +1,7 @@
#ifndef EASYPR_CORE_COREFUNC_H_
#define EASYPR_CORE_COREFUNC_H_
#include <opencv2/opencv.hpp>
#include "opencv2/opencv.hpp"
#include "easypr/core/plate.hpp"
#include "easypr/core/character.hpp"
@ -12,9 +12,9 @@ Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
//! 根据一幅图像与颜色模板获取对应的二值图
//! 输入RGB图像, 颜色模板(蓝色、黄色)
//! 输出灰度图只有0和255两个值255代表匹配0代表不匹配
//! find binary image match to color
//! input rgb, want match color ( blue or yellow)
//! out grey, 255 is match, 0 is not match
Mat colorMatch(const Mat& src, Mat& match, const Color r,
const bool adaptive_minsv);
@ -22,10 +22,6 @@ Mat colorMatch(const Mat& src, Mat& match, const Color r,
//Mat mserMatch(const Mat& src, Mat& match, const Color r,
// std::vector<RotatedRect>& plateRect, std::vector<Rect>& out_charRect);
//! 判断一个车牌的颜色
//! 输入车牌mat与颜色模板
//! 返回true或fasle
bool plateColorJudge(const Mat& src, const Color r, const bool adaptive_minsv,
float& percent);
@ -33,26 +29,17 @@ 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);
Rect GetCenterRect(Mat& in);
Mat CutTheRect(Mat& in, Rect& rect);
int ThresholdOtsu(Mat mat);
//! 获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t);
@ -64,7 +51,7 @@ bool verifyCharSizes(Rect r);
bool verifyPlateSize(Rect mr);
bool verifyRotatedPlateSizes(RotatedRect mr, bool showDebug = false);
//! 非极大值抑制
// non-maximum suppression
void NMStoCharacter(std::vector<CCharacter> &inVec, double overlap);
@ -102,7 +89,7 @@ Mat adaptive_image_from_points(const std::vector<Point>& points,
// Calculate a rect have same length and width and remains the center
Rect adaptive_charrect_from_rect(const Rect& rect, int maxwidth, int maxheight);
//! 计算一个安全的Rect
// calc safe rect
bool calcSafeRect(const RotatedRect& roi_rect, const Mat& src,
Rect_<float>& safeBoundRect);

@ -1,7 +1,7 @@
#ifndef EASYPR_CORE_FEATURE_H_
#define EASYPR_CORE_FEATURE_H_
#include <opencv2/opencv.hpp>
#include "opencv2/opencv.hpp"
namespace easypr {
@ -36,8 +36,6 @@ void getLBPFeatures(const cv::Mat& image, cv::Mat& features);
//! get character feature
cv::Mat charFeatures(cv::Mat in, int sizeData);
//! get character feature
cv::Mat charFeatures2(cv::Mat in, int sizeData);
//! LBP feature + Histom feature

@ -10,7 +10,7 @@
#ifndef EASYPR_CORE_PLATE_H_
#define EASYPR_CORE_PLATE_H_
#include <opencv2/opencv.hpp>
#include "opencv2/opencv.hpp"
#include "easypr/core/character.hpp"
#include "easypr/config.h"

@ -37,28 +37,21 @@ class CPlateDetect {
*/
int plateDetect(Mat src, std::vector<CPlate> &resultVec, int img_index = 0);
//! 展示中间的结果
int showResult(const Mat &result, int img_index = 0);
//! 装载SVM模型
void LoadSVM(std::string s);
//! 生活模式与工业模式切换
inline void setPDLifemode(bool param) { m_plateLocate->setLifemode(param); }
//! 是否开启调试模式
inline void setPDDebug(bool param) {
m_plateLocate->setDebug(param);
setDetectShow(param);
}
//! 获取调试模式状态
inline bool getPDDebug() { return m_plateLocate->getDebug(); }
inline void setDetectType(int param) { m_type = param; }
//! 设置与读取变量
inline void setGaussianBlurSize(int param) {
m_plateLocate->setGaussianBlurSize(param);
}
@ -114,12 +107,8 @@ class CPlateDetect {
private:
//! 设置一幅图中最多有多少车牌
int m_maxPlates;
//! 车牌定位
CPlateLocate* m_plateLocate;
int m_type;

@ -3,7 +3,6 @@
#include "easypr/core/plate.hpp"
#include "easypr/core/feature.h"
#include "easypr/core/core_func.h"
namespace easypr {
@ -11,19 +10,13 @@ class PlateJudge {
public:
static PlateJudge* instance();
//! 对多幅车牌进行SVM判断
void LoadModel(std::string path);
int plateJudge(const std::vector<CPlate> &, std::vector<CPlate> &);
int plateJudgeUsingNMS(const std::vector<CPlate> &, std::vector<CPlate> &, int maxPlates = 5);
//! 车牌判断
int plateJudge(const std::vector<Mat> &, std::vector<Mat> &);
//! 车牌判断(一副图像)
int plateJudge(const Mat &inMat, int &result);
int plateSetScore(CPlate& plate);

@ -15,8 +15,6 @@
#define EASYPR_CORE_PLATELOCATE_H_
#include "easypr/core/plate.hpp"
#include "easypr/core/core_func.h"
#include "easypr/config.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
@ -30,85 +28,46 @@ class CPlateLocate {
public:
CPlateLocate();
//! Sobel第一次搜索
//! 不限制大小和形状获取的BoundRect进入下一步
int sobelFrtSearch(const Mat& src, std::vector<Rect_<float>>& outRects);
//! Sobel第二次搜索
//! 对大小和形状做限制,生成参考坐标
int sobelSecSearch(Mat& bound, Point2f refpoint,
std::vector<RotatedRect>& outRects);
int sobelSecSearchPart(Mat& bound, Point2f refpoint,
std::vector<RotatedRect>& outRects);
//! 抗扭斜处理
int deskew(const Mat& src, const Mat& src_b,
std::vector<RotatedRect>& inRects, std::vector<CPlate>& outPlates,
bool useDeteleArea = true, Color color = UNKNOWN);
//! 是否偏斜
//! 输入二值化图像,输出判断结果
bool isdeflection(const Mat& in, const double angle, double& slope);
//! Sobel运算
//! 输入彩色图像,输出二值化图像
int sobelOper(const Mat& in, Mat& out, int blurSize, int morphW, int morphH);
//! 旋转操作
bool rotation(Mat& in, Mat& out, const Size rect_size, const Point2f center,
const double angle);
//! 扭变操作
void affine(const Mat& in, Mat& out, const double slope);
//! 颜色定位法
int plateColorLocate(Mat src, std::vector<CPlate>& candPlates, int index = 0);
//! Sobel定位法
int plateSobelLocate(Mat src, std::vector<CPlate>& candPlates, int index = 0);
int sobelOperT(const Mat& in, Mat& out, int blurSize, int morphW, int morphH);
int plateMserLocate(Mat src, std::vector<CPlate>& candPlates, int index = 0);
//! Color搜索
int colorSearch(const Mat& src, const Color r, Mat& out,
std::vector<RotatedRect>& outRects, int index = 0);
//! mser search
int mserSearch(const Mat &src, vector<Mat>& out,
vector<vector<CPlate>>& out_plateVec, bool usePlateMser, vector<vector<RotatedRect>>& out_plateRRect,
int img_index = 0, bool showDebug = false);
//! 未使用函数与代码
//! 开始------------
//! 结束------------
//! 未使用函数与代码
//! 车牌定位
int plateLocate(Mat, std::vector<Mat>&, int = 0);
//! 车牌的尺寸验证
bool verifySizes(RotatedRect mr);
//! 生活模式与工业模式切换
void setLifemode(bool param);
//! 设置与读取变量
inline void setGaussianBlurSize(int param) { m_GaussianBlurSize = param; }
inline int getGaussianBlurSize() const { return m_GaussianBlurSize; }
@ -128,15 +87,11 @@ class CPlateLocate {
inline void setJudgeAngle(int param) { m_angle = param; }
//! 是否开启调试模式
inline void setDebug(bool param) { m_debug = param; }
//! 获取调试模式状态
inline bool getDebug() { return m_debug; }
//! PlateLocate所用常量
static const int DEFAULT_GAUSSIANBLUR_SIZE = 5;
static const int SOBEL_SCALE = 1;
@ -147,47 +102,35 @@ class CPlateLocate {
static const int DEFAULT_MORPH_SIZE_WIDTH = 17; // 17
static const int DEFAULT_MORPH_SIZE_HEIGHT = 3; // 3
//! showResultMat所用常量
static const int WIDTH = 136;
static const int HEIGHT = 36;
static const int TYPE = CV_8UC3;
//! verifySize所用常量
static const int DEFAULT_VERIFY_MIN = 1; // 3
static const int DEFAULT_VERIFY_MAX = 24; // 20
//! 角度判断所用常量
static const int DEFAULT_ANGLE = 60; // 30
//! 是否开启调试模式常量默认0代表关闭
static const int DEFAULT_DEBUG = 1;
protected:
//! 高斯模糊所用变量
int m_GaussianBlurSize;
//! 连接操作所用变量
int m_MorphSizeWidth;
int m_MorphSizeHeight;
//! verifySize所用变量
float m_error;
float m_aspect;
int m_verifyMin;
int m_verifyMax;
//! 角度判断所用变量
int m_angle;
//! 是否开启调试模式0关闭非0开启
bool m_debug;
};

@ -24,15 +24,12 @@ namespace easypr {
public:
CPlateRecognize();
//! 车牌检测与字符识别
int plateRecognize(Mat src, std::vector<CPlate> &licenseVec, int img_index = 0);
int plateRecognize(Mat src, std::vector<std::string> &licenseVec);
int plateRecognizeAsText(Mat src, std::vector<CPlate> &licenseVec);
int plateRecognizeAsTextNM(Mat src, std::vector<CPlate> &licenseVec);
//! 生活模式与工业模式切换
inline void setLifemode(bool param) { CPlateDetect::setPDLifemode(param); }
inline void setDetectType(int param) { CPlateDetect::setDetectType(param); }

@ -52,7 +52,6 @@ int CCharsRecognise::charsRecognise(CPlate& plate, std::string& plateLicense) {
Mat plateMat = plate.getPlateMat();
// 判断车牌颜色以此确认threshold方法
Color color;
if (plate.getPlateLocateType() == CMSER) {
color = plate.getPlateColor();

@ -1,5 +1,6 @@
#include "easypr/core/chars_segment.h"
#include "easypr/core/chars_identify.h"
#include "easypr/core/core_func.h"
#include "easypr/core/params.h"
#include "easypr/config.h"
@ -14,8 +15,6 @@ CCharsSegment::CCharsSegment() {
m_LiuDingSize = DEFAULT_LIUDING_SIZE;
m_theMatWidth = DEFAULT_MAT_WIDTH;
//!车牌颜色判断参数
m_ColorThreshold = DEFAULT_COLORTHRESHOLD;
m_BluePercent = DEFAULT_BLUEPERCEMT;
m_WhitePercent = DEFAULT_WHITEPERCEMT;
@ -23,7 +22,6 @@ CCharsSegment::CCharsSegment() {
m_debug = DEFAULT_DEBUG;
}
//! 字符尺寸验证
bool CCharsSegment::verifyCharSizes(Mat r) {
// Char sizes 45x90
@ -49,15 +47,12 @@ bool CCharsSegment::verifyCharSizes(Mat r) {
return false;
}
//! 字符预处理
Mat CCharsSegment::preprocessChar(Mat in) {
// Remap image
int h = in.rows;
int w = in.cols;
//统一每个字符的大小
int charSize = CHAR_SIZE;
Mat transformMat = Mat::eye(2, 3, CV_32F);
@ -69,8 +64,6 @@ Mat CCharsSegment::preprocessChar(Mat in) {
warpAffine(in, warpImage, transformMat, warpImage.size(), INTER_LINEAR,
BORDER_CONSTANT, Scalar(0));
// 将所有的字符调整成统一的尺寸
Mat out;
resize(warpImage, out, Size(charSize, charSize));
@ -233,7 +226,6 @@ bool slideChineseWindow(Mat& image, Rect mr, Mat& newRoi, Color plateType, float
}
//! 字符分割与排序
int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color) {
if (!input.data) return 0x01;
@ -250,9 +242,7 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
Mat img_threshold;
// 二值化
// 根据车牌的不同颜色使用不同的阈值判断方法
// TODO使用MSER来提取这些轮廓
//if (BLUE == plateType) {
// // cout << "BLUE" << endl;
// img_threshold = input_grey.clone();
@ -295,15 +285,12 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
destroyWindow("plate");
}
// 去除车牌上方的柳钉以及下方的横线等干扰
// 并且也判断了是否是车牌
// 并且在此对字符的跳变次数以及字符颜色所占的比重做了是否是车牌的判别条件
// 如果不是车牌返回ErrorCode=0x02
// remove liuding and hor lines
// also judge weather is plate use jump count
if (!clearLiuDing(img_threshold)) return 0x02;
//clearLiuDing(img_threshold);
// 在二值化图像中提取轮廓
Mat img_contours;
img_threshold.copyTo(img_contours);
@ -317,8 +304,6 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
vector<vector<Point> >::iterator itc = contours.begin();
vector<Rect> vecRect;
// 将不符合特定尺寸的字符块排除出去
while (itc != contours.end()) {
Rect mr = boundingRect(Mat(*itc));
Mat auxRoi(img_threshold, mr);
@ -327,27 +312,17 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
++itc;
}
// 如果找不到任何字符块则返回ErrorCode=0x03
if (vecRect.size() == 0) return 0x03;
// 对符合尺寸的图块按照从左到右进行排序;
// 直接使用stl的sort方法更有效率
vector<Rect> sortedRect(vecRect);
std::sort(sortedRect.begin(), sortedRect.end(),
[](const Rect& r1, const Rect& r2) { return r1.x < r2.x; });
size_t specIndex = 0;
// 获得特殊字符对应的Rectt,如苏A的"A"
specIndex = GetSpecificRect(sortedRect);
// 根据特定Rect向左反推出中文字符
// 这样做的主要原因是根据findContours方法很难捕捉到中文字符的准确Rect因此仅能
// 退过特定算法来指定
Rect chineseRect;
if (specIndex < sortedRect.size())
chineseRect = GetChineseRect(sortedRect[specIndex]);
@ -361,19 +336,13 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
destroyWindow("plate");
}
//新建一个全新的排序Rect
//将中文字符Rect第一个加进来因为它肯定是最左边的
//其余的Rect只按照顺序去6个车牌只可能是7个字符这样可以避免阴影导致的“1”字符
vector<Rect> newSortedRect;
newSortedRect.push_back(chineseRect);
RebuildRect(sortedRect, newSortedRect, specIndex);
if (newSortedRect.size() == 0) return 0x05;
// 开始截取每个字符
bool useSlideWindow = true;
bool useAdapThreshold = true;
//bool useAdapThreshold = CParams::instance()->getParam1b();
@ -381,9 +350,6 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
Rect mr = newSortedRect[i];
// Mat auxRoi(img_threshold, mr);
// 使用灰度图来截取图块,然后依次对每个图块进行大津阈值来二值化
Mat auxRoi(input_grey, mr);
Mat newRoi;
@ -411,7 +377,6 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
}
// 归一化大小
newRoi = preprocessChar(newRoi);
}
@ -428,14 +393,12 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
}
}
// 每个字符图块输入到下面的步骤进行处理
resultVec.push_back(newRoi);
}
return 0;
}
//! 根据特殊车牌来构造猜测中文字符的位置和大小
Rect CCharsSegment::GetChineseRect(const Rect rectSpe) {
int height = rectSpe.height;
@ -451,8 +414,6 @@ Rect CCharsSegment::GetChineseRect(const Rect rectSpe) {
return a;
}
//! 找出指示城市的字符的Rect例如苏A7003X就是"A"的位置
int CCharsSegment::GetSpecificRect(const vector<Rect>& vecRect) {
vector<int> xpositions;
int maxHeight = 0;
@ -474,9 +435,8 @@ int CCharsSegment::GetSpecificRect(const vector<Rect>& vecRect) {
Rect mr = vecRect[i];
int midx = mr.x + mr.width / 2;
//如果一个字符有一定的大小并且在整个车牌的1/7到2/7之间则是我们要找的特殊字符
//当前字符和下个字符的距离在一定的范围内
// use known knowledage to find the specific character
// position in 1/7 and 2/7
if ((mr.width > maxWidth * 0.8 || mr.height > maxHeight * 0.8) &&
(midx < int(m_theMatWidth / 7) * 2 &&
midx > int(m_theMatWidth / 7) * 1)) {
@ -487,10 +447,6 @@ int CCharsSegment::GetSpecificRect(const vector<Rect>& vecRect) {
return specIndex;
}
//! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
int CCharsSegment::RebuildRect(const vector<Rect>& vecRect,
vector<Rect>& outRect, int specIndex) {
int count = 6;

File diff suppressed because it is too large Load Diff

@ -1,14 +1,9 @@
// 这个文件定义了EasyPR里所有特征生成的函数
// 所属命名空间为easypr
// 这个部分中的特征由easypr的开发者修改
#include "easypr/core/feature.h"
#include "easypr/core/core_func.h"
#include "thirdparty/LBP/lbp.hpp"
namespace easypr {
//! 获取垂直和水平的直方图图值
Mat getHistogram(Mat in) {
const int VERTICAL = 0;
@ -23,8 +18,6 @@ Mat getHistogram(Mat in) {
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);
@ -38,9 +31,6 @@ Mat getHistogram(Mat in) {
return out;
}
//! EasyPR的getFeatures回调函数
//! 本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const Mat& image, Mat& features) {
Mat grayImage;
cvtColor(image, grayImage, CV_RGB2GRAY);
@ -53,26 +43,16 @@ void getHistogramFeatures(const Mat& image, Mat& features) {
features = getHistogram(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
@ -98,7 +78,6 @@ void getLBPFeatures(const Mat& image, Mat& features) {
// destroyWindow("grayImage");
//}
Mat lbpimage;
lbpimage = libfacerec::olbp(grayImage);
Mat lbp_hist = libfacerec::spatial_histogram(lbpimage, 32, 4, 4);
@ -129,8 +108,6 @@ Mat charFeatures(Mat in, int sizeData) {
Mat out = Mat::zeros(1, numCols, CV_32F);
// Asign values to
// feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量
int j = 0;
for (int i = 0; i < vhist.cols; i++) {
out.at<float>(j) = vhist.at<float>(i);

@ -58,7 +58,7 @@ namespace easypr {
}
}
// 使用非极大值抑制来判断车牌
// use nms to judge plate
PlateJudge::instance()->plateJudgeUsingNMS(all_result_Plates, resultVec, m_maxPlates);
if (showDetectArea || getDetectShow()) {
@ -93,7 +93,6 @@ namespace easypr {
line(result, rect_points[j], rect_points[(j + 1) % 4], lineColor, 2, 8);
}
//显示定位框的图片
showResult(result, img_index);
}

@ -28,7 +28,6 @@ namespace easypr {
}
}
//! 对单幅图像进行SVM判断
int PlateJudge::plateJudge(const Mat &inMat, int &result) {
Mat features;
@ -40,7 +39,6 @@ namespace easypr {
return 0;
}
//! 对多幅图像进行SVM判断
int PlateJudge::plateJudge(const std::vector<Mat> &inVec,
std::vector<Mat> &resultVec) {
@ -56,16 +54,16 @@ namespace easypr {
return 0;
}
//! 设置车牌图像的置信度
//! 返回值0代表是车牌其他值代表不是
// set the score of plate
// 0 is plate, -1 is not.
int PlateJudge::plateSetScore(CPlate& plate) {
Mat features;
extractFeature(plate.getPlateMat(), features);
float score = svm_->predict(features, noArray(), cv::ml::StatModel::Flags::RAW_OUTPUT);
// score值代表离margin的距离小于0代表是车牌大于0代表不是车牌
// 当小于0时值越小代表是车牌的概率越大
// score is the distance of marginbelow zero is plate, up is not
// when score is below zero, the samll the value, the more possibliy to be a plate.
plate.setPlateScore(score);
if (score < 0)
@ -74,13 +72,7 @@ namespace easypr {
return -1;
}
////! 比较函数
//struct PlateScoreCompaer {
// bool operator() (const CPlate& i, const CPlate& j) { return (i.getPlateScore() < j.getPlateScore()); }
//} plateScoreCompaerObject;
//! 非极大值抑制
// non-maximum suppression
void NMS(std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec, double overlap) {
std::sort(inVec.begin(), inVec.end());
@ -111,7 +103,6 @@ namespace easypr {
resultVec = inVec;
}
//! 使用非极大值抑制的车牌判断
int PlateJudge::plateJudgeUsingNMS(const std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec, int maxPlates) {
std::vector<CPlate> plateVec;
int num = inVec.size();
@ -174,8 +165,6 @@ namespace easypr {
// int w = inMat.cols;
// int h = inMat.rows;
// //再取中间部分判断一次
// Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8));
// Mat tmpDes = inMat.clone();
// resize(tmpmat, tmpDes, Size(inMat.size()));
@ -209,8 +198,6 @@ namespace easypr {
std::vector<CPlate> reDupPlateVec;
// 使用非极大值抑制来去除那些重叠的车牌
// overlap阈值设置为0.5
double overlap = 0.5;
NMS(plateVec, reDupPlateVec, overlap);
@ -235,7 +222,6 @@ namespace easypr {
}
//! 对多幅车牌进行SVM判断
int PlateJudge::plateJudge(const std::vector<CPlate> &inVec,
std::vector<CPlate> &resultVec) {
int num = inVec.size();
@ -252,8 +238,6 @@ namespace easypr {
int w = inMat.cols;
int h = inMat.rows;
//再取中间部分判断一次
Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8));
Mat tmpDes = inMat.clone();
resize(tmpmat, tmpDes, Size(inMat.size()));

File diff suppressed because it is too large Load Diff

@ -15,8 +15,6 @@ int test_plate_locate() {
cv::Mat src = imread(file);
// TODO原plateLocate需要被替换
vector<cv::Mat> resultVec;
CPlateLocate plate;
plate.setDebug(1);

@ -97,6 +97,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%OPENCV%\x86\vc12\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>opencv_world300d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<Profile>false</Profile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -114,6 +115,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%OPENCV%\x64\vc12\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>opencv_world300d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<Profile>true</Profile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

Loading…
Cancel
Save