|
|
|
|
#ifndef EASYPR_ACCURACY_HPP
|
|
|
|
|
#define EASYPR_ACCURACY_HPP
|
|
|
|
|
|
|
|
|
|
#include <easypr.h>
|
|
|
|
|
#include <ctime>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
|
|
#include "xml\xmlParser.h"
|
|
|
|
|
|
|
|
|
|
namespace easypr {
|
|
|
|
|
|
|
|
|
|
namespace demo {
|
|
|
|
|
|
|
|
|
|
int accuracyTest(const char* test_path) {
|
|
|
|
|
|
|
|
|
|
//XMLNode xMainNode = XMLNode::openFileHelper("TestLocation.xml", "tagset");
|
|
|
|
|
|
|
|
|
|
//int n = xMainNode.nChildNode("image");
|
|
|
|
|
|
|
|
|
|
//cout << n << endl;
|
|
|
|
|
//
|
|
|
|
|
////for (int i = 0; i < n; i++) {
|
|
|
|
|
//// XMLNode xNode = xMainNode.getChildNode("image", i);
|
|
|
|
|
//// cout << xNode.getChildNode("imageName").getText() << endl;
|
|
|
|
|
////}
|
|
|
|
|
|
|
|
|
|
////XMLNode xNode = xMainNode.getChildNode("image", 0);
|
|
|
|
|
////cout << xNode.getChildNode("imageName").getText() << endl;
|
|
|
|
|
////xNode.getChildNode("imageName").updateText("test1");
|
|
|
|
|
//
|
|
|
|
|
//XMLNode xNode = xMainNode.addChild("image");
|
|
|
|
|
|
|
|
|
|
//cout << xNode.getChildNode("imageName").getText() << endl;
|
|
|
|
|
//xNode.getChildNode("imageName").updateText("test1");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//char *t = xNode.createXMLString(true);
|
|
|
|
|
//printf("%s\n", t);
|
|
|
|
|
//free(t);
|
|
|
|
|
|
|
|
|
|
XMLNode xMainNode = XMLNode::createXMLTopNode("tagset");
|
|
|
|
|
XMLNode::setGlobalOptions(XMLNode::char_encoding_GBK);
|
|
|
|
|
|
|
|
|
|
auto files = Utils::getFiles(test_path);
|
|
|
|
|
|
|
|
|
|
CPlateRecognize pr;
|
|
|
|
|
|
|
|
|
|
pr.LoadANN("resources/model/ann.xml");
|
|
|
|
|
pr.LoadSVM("resources/model/svm.xml");
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>Debugģʽ
|
|
|
|
|
pr.setDebug(false);
|
|
|
|
|
|
|
|
|
|
pr.setLifemode(true);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>ٳ<EFBFBD><D9B3><EFBFBD>
|
|
|
|
|
pr.setMaxPlates(4);
|
|
|
|
|
|
|
|
|
|
int size = files.size();
|
|
|
|
|
|
|
|
|
|
if (0 == size) {
|
|
|
|
|
cout << "No File Found in general_test/native_test!" << endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cout << "Begin to test the easypr accuracy!" << endl;
|
|
|
|
|
|
|
|
|
|
// <20>ܵIJ<DCB5><C4B2><EFBFBD>ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD>
|
|
|
|
|
int count_all = 0;
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD>
|
|
|
|
|
int count_err = 0;
|
|
|
|
|
// δʶ<CEB4><CAB6><EFBFBD><EFBFBD>ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD>
|
|
|
|
|
int count_norecogin = 0;
|
|
|
|
|
// not recognized pictures
|
|
|
|
|
std::list<std::string> not_recognized_files;
|
|
|
|
|
|
|
|
|
|
// <20>ܵ<EFBFBD><DCB5>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
float diff_all = 0;
|
|
|
|
|
// ƽ<><C6BD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
float diff_avg = 0;
|
|
|
|
|
// <20><>ȫƥ<C8AB><C6A5><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
float match_count = 0;
|
|
|
|
|
// <20><>ȫƥ<C8AB><C6A5><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռʶ<D5BC><CAB6>ͼƬ<CDBC>еı<D0B5><C4B1><EFBFBD>
|
|
|
|
|
float match_rate = 0;
|
|
|
|
|
|
|
|
|
|
// <20><>ʼ<EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
|
|
|
|
time_t begin, end;
|
|
|
|
|
time(&begin);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
|
|
|
string filepath = files[i].c_str();
|
|
|
|
|
|
|
|
|
|
// EasyPR<50><52>ʼ<EFBFBD>жϳ<D0B6><CFB3><EFBFBD>
|
|
|
|
|
Mat src = imread(filepath);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ֱ<EFBFBD>ӹ<EFBFBD>ȥ
|
|
|
|
|
if (!src.data) continue;
|
|
|
|
|
|
|
|
|
|
cout << "------------------" << endl;
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1>ʵ<EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
|
|
|
|
|
string plateLicense = Utils::getFileName(filepath);
|
|
|
|
|
cout << "ԭ<EFBFBD><EFBFBD>:" << plateLicense << endl;
|
|
|
|
|
|
|
|
|
|
XMLNode xNode = xMainNode.addChild("image");
|
|
|
|
|
xNode.addChild("imageName").addText(plateLicense.c_str());
|
|
|
|
|
|
|
|
|
|
XMLNode rectangleNodes = xNode.addChild("taggedRectangles");
|
|
|
|
|
|
|
|
|
|
vector<CPlate> plateVec;
|
|
|
|
|
int result = pr.plateRecognize(src, plateVec, i);
|
|
|
|
|
if (result == 0) {
|
|
|
|
|
int num = plateVec.size();
|
|
|
|
|
|
|
|
|
|
if (num == 0) {
|
|
|
|
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << endl;
|
|
|
|
|
if (plateLicense != "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>") {
|
|
|
|
|
not_recognized_files.push_back(plateLicense);
|
|
|
|
|
count_norecogin++;
|
|
|
|
|
}
|
|
|
|
|
} else if (num > 1) {
|
|
|
|
|
// <20><EFBFBD><E0B3B5>ʹ<EFBFBD><CAB9>diff<66><66>С<EFBFBD><D0A1><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD>¼
|
|
|
|
|
int mindiff = 10000;
|
|
|
|
|
for (int j = 0; j < num; j++) {
|
|
|
|
|
cout << plateVec[j].getPlateStr() << " (" << j + 1 << ")" << endl;
|
|
|
|
|
|
|
|
|
|
XMLNode rectangleNode = rectangleNodes.addChild("taggedRectangle");
|
|
|
|
|
RotatedRect rr = plateVec[j].getPlatePos();
|
|
|
|
|
LocateType locateType = plateVec[j].getPlateLocateType();
|
|
|
|
|
|
|
|
|
|
rectangleNode.addAttribute("x", to_string((int)rr.center.x).c_str());
|
|
|
|
|
rectangleNode.addAttribute("y", to_string((int)rr.center.y).c_str());
|
|
|
|
|
rectangleNode.addAttribute("width", to_string((int)rr.size.width).c_str());
|
|
|
|
|
rectangleNode.addAttribute("height", to_string((int)rr.size.height).c_str());
|
|
|
|
|
|
|
|
|
|
rectangleNode.addAttribute("rotation", to_string((int)rr.angle).c_str());
|
|
|
|
|
rectangleNode.addAttribute("locateType", to_string(locateType).c_str());
|
|
|
|
|
//rectangleNode.addText(plateVec[j].getPlateStr().c_str());
|
|
|
|
|
rectangleNode.addAttribute("text", plateVec[j].getPlateStr().c_str());
|
|
|
|
|
|
|
|
|
|
string colorplate = plateVec[j].getPlateStr();
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>"<22><><EFBFBD><EFBFBD>:<3A><>E7KU22"<22><>ð<EFBFBD>ź<EFBFBD><C5BA><EFBFBD><EFBFBD>ij<EFBFBD><C4B3>ƴ<EFBFBD>С"
|
|
|
|
|
vector<string> spilt_plate = Utils::splitString(colorplate, ':');
|
|
|
|
|
|
|
|
|
|
int size = spilt_plate.size();
|
|
|
|
|
if (size == 2 && spilt_plate[1] != "") {
|
|
|
|
|
int diff = utils::levenshtein_distance(plateLicense,
|
|
|
|
|
spilt_plate[size - 1]);
|
|
|
|
|
if (diff < mindiff) mindiff = diff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << mindiff << "<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>" << endl;
|
|
|
|
|
if (mindiff == 0) {
|
|
|
|
|
// <20><>ȫƥ<C8AB><C6A5>
|
|
|
|
|
match_count++;
|
|
|
|
|
}
|
|
|
|
|
diff_all = diff_all + mindiff;
|
|
|
|
|
} else {
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>diff
|
|
|
|
|
for (int j = 0; j < num; j++) {
|
|
|
|
|
cout << plateVec[j].getPlateStr() << endl;
|
|
|
|
|
|
|
|
|
|
XMLNode rectangleNode = rectangleNodes.addChild("taggedRectangle");
|
|
|
|
|
RotatedRect rr = plateVec[j].getPlatePos();
|
|
|
|
|
LocateType locateType = plateVec[j].getPlateLocateType();
|
|
|
|
|
|
|
|
|
|
rectangleNode.addAttribute("x", to_string((int)rr.center.x).c_str());
|
|
|
|
|
rectangleNode.addAttribute("y", to_string((int)rr.center.y).c_str());
|
|
|
|
|
rectangleNode.addAttribute("width", to_string((int)rr.size.width).c_str());
|
|
|
|
|
rectangleNode.addAttribute("height", to_string((int)rr.size.height).c_str());
|
|
|
|
|
|
|
|
|
|
rectangleNode.addAttribute("rotation", to_string((int)rr.angle).c_str());
|
|
|
|
|
rectangleNode.addAttribute("locateType", to_string(locateType).c_str());
|
|
|
|
|
//rectangleNode.addText(plateVec[j].getPlateStr().c_str());
|
|
|
|
|
rectangleNode.addAttribute("text", plateVec[j].getPlateStr().c_str());
|
|
|
|
|
|
|
|
|
|
string colorplate = plateVec[j].getPlateStr();
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>"<22><><EFBFBD><EFBFBD>:<3A><>E7KU22"<22><>ð<EFBFBD>ź<EFBFBD><C5BA><EFBFBD><EFBFBD>ij<EFBFBD><C4B3>ƴ<EFBFBD>С"
|
|
|
|
|
vector<string> spilt_plate = Utils::splitString(colorplate, ':');
|
|
|
|
|
|
|
|
|
|
int size = spilt_plate.size();
|
|
|
|
|
if (size == 2 && spilt_plate[1] != "") {
|
|
|
|
|
int diff = utils::levenshtein_distance(plateLicense,
|
|
|
|
|
spilt_plate[size - 1]);
|
|
|
|
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << diff << "<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>" << endl;
|
|
|
|
|
|
|
|
|
|
if (diff == 0) {
|
|
|
|
|
// <20><>ȫƥ<C8AB><C6A5>
|
|
|
|
|
match_count++;
|
|
|
|
|
}
|
|
|
|
|
diff_all = diff_all + diff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << result << endl;
|
|
|
|
|
count_err++;
|
|
|
|
|
}
|
|
|
|
|
count_all++;
|
|
|
|
|
}
|
|
|
|
|
time(&end);
|
|
|
|
|
|
|
|
|
|
cout << "------------------" << endl;
|
|
|
|
|
cout << "Easypr accuracy test end!" << endl;
|
|
|
|
|
cout << "------------------" << endl;
|
|
|
|
|
cout << endl;
|
|
|
|
|
|
|
|
|
|
xMainNode.writeToFile("Result.xml");
|
|
|
|
|
|
|
|
|
|
cout << "ͳ<EFBFBD>Ʋ<EFBFBD><EFBFBD><EFBFBD>:" << endl;
|
|
|
|
|
cout << "<EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD>:" << count_all << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
cout << "δʶ<EFBFBD><EFBFBD>ͼƬ:" << count_norecogin << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
|
|
|
|
|
float count_recogin = float(count_all - (count_err + count_norecogin));
|
|
|
|
|
float count_rate = count_recogin / count_all;
|
|
|
|
|
cout << "<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>:" << count_rate * 100 << "% " << endl;
|
|
|
|
|
|
|
|
|
|
if (count_recogin > 0) {
|
|
|
|
|
diff_avg = diff_all / count_recogin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (count_recogin > 0) {
|
|
|
|
|
match_rate = match_count / count_recogin * 100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cout << "ƽ<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << diff_avg << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
cout << "<EFBFBD><EFBFBD>ȫƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << match_count << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
cout << "<EFBFBD><EFBFBD>ȫƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << match_rate << "% " << endl;
|
|
|
|
|
|
|
|
|
|
double seconds = difftime(end, begin);
|
|
|
|
|
double avgsec = seconds / double(count_all);
|
|
|
|
|
|
|
|
|
|
cout << "<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>:" << seconds << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
cout << "ƽ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>:" << avgsec << "<EFBFBD><EFBFBD>" << endl;
|
|
|
|
|
|
|
|
|
|
cout << "δʶ<EFBFBD><EFBFBD>ͼƬ:" << endl;
|
|
|
|
|
|
|
|
|
|
for (auto it = not_recognized_files.begin(); it != not_recognized_files.end();
|
|
|
|
|
++it) {
|
|
|
|
|
cout << *it << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cout << endl;
|
|
|
|
|
|
|
|
|
|
cout << "------------------" << endl;
|
|
|
|
|
|
|
|
|
|
ofstream myfile("accuracy.txt", ios::app);
|
|
|
|
|
if (myfile.is_open()) {
|
|
|
|
|
time_t t = time(0); // get time now
|
|
|
|
|
struct tm* now = localtime(&t);
|
|
|
|
|
char buf[80];
|
|
|
|
|
|
|
|
|
|
strftime(buf, sizeof(buf), "%Y-%m-%d %X", now);
|
|
|
|
|
myfile << string(buf) << endl;
|
|
|
|
|
|
|
|
|
|
myfile << "<EFBFBD><EFBFBD>ͼƬ<EFBFBD><EFBFBD>:" << count_all << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
myfile << "δʶ<EFBFBD><EFBFBD>ͼƬ:" << count_norecogin << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
myfile << "<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>:" << count_rate * 100 << "% " << endl;
|
|
|
|
|
myfile << "ƽ<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << diff_avg << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
myfile << "<EFBFBD><EFBFBD>ȫƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << match_count << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
myfile << "<EFBFBD><EFBFBD>ȫƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << match_rate << "% " << endl;
|
|
|
|
|
myfile << "<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>:" << seconds << "<EFBFBD><EFBFBD>, ";
|
|
|
|
|
myfile << "ƽ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>:" << avgsec << "<EFBFBD><EFBFBD>" << endl;
|
|
|
|
|
myfile.close();
|
|
|
|
|
} else {
|
|
|
|
|
cout << "Unable to open file";
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // EASYPR_ACCURACY_HPP
|