zhaohaoyi
Www-369 12 months ago
parent 682a5d4669
commit fa1a23a978

@ -1,9 +1,11 @@
//该代码主要用于车牌识别。它定义了一个名为PlateJudge的类该类包含了一系列用于车牌识别的方法。
#include "easypr/core/plate_judge.h" #include "easypr/core/plate_judge.h"
#include "easypr/config.h" #include "easypr/config.h"
#include "easypr/core/core_func.h" #include "easypr/core/core_func.h"
#include "easypr/core/params.h" #include "easypr/core/params.h"
namespace easypr { namespace easypr { //这部分代码实现了单例模式确保PlateJudge类只有一个实例
PlateJudge* PlateJudge::instance_ = nullptr; PlateJudge* PlateJudge::instance_ = nullptr;
@ -14,7 +16,7 @@ namespace easypr {
return instance_; return instance_;
} }
PlateJudge::PlateJudge() { PlateJudge::PlateJudge() { //PlateJudge决定了使用哪种特征提取方法。
bool useLBP = false; bool useLBP = false;
if (useLBP) { if (useLBP) {
LOAD_SVM_MODEL(svm_, kLBPSvmPath); LOAD_SVM_MODEL(svm_, kLBPSvmPath);
@ -26,7 +28,7 @@ namespace easypr {
} }
} }
void PlateJudge::LoadModel(std::string path) { void PlateJudge::LoadModel(std::string path) { //LoadModel函数用于加载SVM模型。
if (path != std::string(kDefaultSvmPath)) { if (path != std::string(kDefaultSvmPath)) {
if (!svm_->empty()) if (!svm_->empty())
svm_->clear(); svm_->clear();
@ -36,7 +38,7 @@ namespace easypr {
// set the score of plate // set the score of plate
// 0 is plate, -1 is not. // 0 is plate, -1 is not.
int PlateJudge::plateSetScore(CPlate& plate) { int PlateJudge::plateSetScore(CPlate& plate) { //plateSetScore函数用于设置车牌的评分。
Mat features; Mat features;
extractFeature(plate.getPlateMat(), features); extractFeature(plate.getPlateMat(), features);
float score = svm_->predict(features, noArray(), cv::ml::StatModel::Flags::RAW_OUTPUT); float score = svm_->predict(features, noArray(), cv::ml::StatModel::Flags::RAW_OUTPUT);
@ -53,53 +55,60 @@ namespace easypr {
else return -1; else return -1;
} }
int PlateJudge::plateJudge(const Mat& plateMat) { int PlateJudge::plateJudge(const Mat& plateMat) { //plateJudge函数用于判断输入的图像是否为车牌。
CPlate plate; CPlate plate;
plate.setPlateMat(plateMat); plate.setPlateMat(plateMat);
return plateSetScore(plate); return plateSetScore(plate);
} }
int PlateJudge::plateJudge(const std::vector<Mat> &inVec, int PlateJudge::plateJudge(const std::vector<Mat> &inVec, //inVec是输入的图像向量resultVec是输出的结果向量。
std::vector<Mat> &resultVec) { std::vector<Mat> &resultVec) { //对inVec中的每一张图像进行车牌判断。如果判断结果为车牌即plateJudge(inMat)的返回值为0则将该图像添加到resultVec中。
int num = inVec.size(); int num = inVec.size(); // 获取输入图像的数量
for (int j = 0; j < num; j++) { for (int j = 0; j < num; j++) { // 遍历每一张图像
Mat inMat = inVec[j]; Mat inMat = inVec[j]; // 获取当前图像
int response = -1; int response = -1;
response = plateJudge(inMat); response = plateJudge(inMat); // 对当前图像进行车牌判断
if (response == 0) resultVec.push_back(inMat); if (response == 0) resultVec.push_back(inMat); // 如果判断结果为车牌,将该图像添加到结果向量中
} }
return 0; return 0; // 返回0表示执行成功
} }
int PlateJudge::plateJudge(const std::vector<CPlate> &inVec, //属于PlateJudge类用于判断输入的车牌向量中哪些是有效的车牌。这个方法的输入是一个CPlate对象的向量inVec输出是一个有效车牌的CPlate对象的向量resultVec。
std::vector<CPlate> &resultVec) { int PlateJudge::plateJudge(const std::vector<CPlate> &inVec,
int num = inVec.size(); std::vector<CPlate> &resultVec) { //接收两个参数一个CPlate对象的向量inVec输入的车牌向量和一个CPlate对象的向量resultVec输出的有效车牌向量
for (int j = 0; j < num; j++) { int num = inVec.size(); // 获取输入向量的大小
CPlate inPlate = inVec[j]; for (int j = 0; j < num; j++) { //遍历输入向量中的每一个元素
//获取当前的CPlate对象和它的车牌图像
CPlate inPlate = inVec[j];
Mat inMat = inPlate.getPlateMat(); Mat inMat = inPlate.getPlateMat();
//调用plateJudge方法判断当前的车牌图像是否有效结果存储在response中
int response = -1; int response = -1;
response = plateJudge(inMat); response = plateJudge(inMat);
//如果当前的车牌图像有效response等于0则将当前的CPlate对象添加到结果向量中
if (response == 0) if (response == 0)
resultVec.push_back(inPlate); resultVec.push_back(inPlate);
//如果当前的车牌图像无效,那么对车牌图像进行裁剪和调整大小
else { else {
int w = inMat.cols; int w = inMat.cols;
int h = inMat.rows; int h = inMat.rows;
Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8)); Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8));
Mat tmpDes = inMat.clone(); Mat tmpDes = inMat.clone();
resize(tmpmat, tmpDes, Size(inMat.size())); resize(tmpmat, tmpDes, Size(inMat.size()));
//再次调用plateJudge方法判断调整后的车牌图像是否有效如果有效则将当前的CPlate对象添加到结果向量中
response = plateJudge(tmpDes); response = plateJudge(tmpDes);
if (response == 0) resultVec.push_back(inPlate); if (response == 0) resultVec.push_back(inPlate);
} }
} }
return 0; return 0; //结束循环并返回0表示方法执行成功
} }
// non-maximum suppression // non-maximum suppression
void NMS(std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec, double overlap) { void NMS(std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec, double overlap) { //NMS函数实现了非极大值抑制用于消除重叠的车牌。
std::sort(inVec.begin(), inVec.end()); std::sort(inVec.begin(), inVec.end());
std::vector<CPlate>::iterator it = inVec.begin(); std::vector<CPlate>::iterator it = inVec.begin();
for (; it != inVec.end(); ++it) { for (; it != inVec.end(); ++it) {
@ -123,7 +132,7 @@ namespace easypr {
} }
// judge plate using nms // judge plate using nms
int PlateJudge::plateJudgeUsingNMS(const std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec, int maxPlates) { int PlateJudge::plateJudgeUsingNMS(const std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec, int maxPlates) { //plateJudgeUsingNMS函数使用非极大值抑制进行车牌识别。
std::vector<CPlate> plateVec; std::vector<CPlate> plateVec;
int num = inVec.size(); int num = inVec.size();
bool useCascadeJudge = true; bool useCascadeJudge = true;

Loading…
Cancel
Save