add icdar2003 detect evalution protocal

v1.6alpha
liuruoze 9 years ago
parent cf33fca08b
commit 9ec49badcf

@ -1617,3 +1617,11 @@
总图片数:200, 未识出图片:7, 定位率:96.5%
平均字符差距:0.689119, 完全匹配数:132, 完全匹配率:68.3938%
总时间:289秒, 平均执行时间:1.445秒
2016-06-19 10:40:03
总图片数:200, 未识出图片:7, 定位率:96.5%
平均字符差距:0.689119, 完全匹配数:132, 完全匹配率:68.3938%
总时间:191秒, 平均执行时间:0.955秒
2016-06-19 10:47:14
总图片数:200, 未识出图片:7, 定位率:96.5%
平均字符差距:0.689119, 完全匹配数:132, 完全匹配率:68.3938%
总时间:183秒, 平均执行时间:0.915秒

@ -88,6 +88,10 @@ Mat adaptive_image_from_points(const std::vector<Point>& points,
const Rect& rect, const Size& size, const Scalar& backgroundColor = Scalar(0, 0, 0),
const Scalar& forgroundColor = Scalar(255, 255, 255), bool gray = true);
//! 计算一个安全的Rect
bool calcSafeRect(const RotatedRect& roi_rect, const Mat& src,
Rect_<float>& safeBoundRect);
} /*! \namespace easypr*/
#endif // EASYPR_CORE_COREFUNC_H_

@ -54,11 +54,6 @@ class CPlateLocate {
int sobelOper(const Mat& in, Mat& out, int blurSize, int morphW, int morphH);
//! 计算一个安全的Rect
bool calcSafeRect(const RotatedRect& roi_rect, const Mat& src,
Rect_<float>& safeBoundRect);
//! 旋转操作
bool rotation(Mat& in, Mat& out, const Size rect_size, const Point2f center,

@ -1065,7 +1065,7 @@ Mat mserMatch(const Mat &src, Mat &match, const Color r,
}
}
if (1) {
if (0) {
imshow("result", result);
waitKey(0);
}
@ -1154,6 +1154,37 @@ Mat adaptive_image_from_points(const std::vector<Point>& points,
return result;
}
//! 计算一个安全的Rect
//! 如果不存在返回false
bool calcSafeRect(const RotatedRect &roi_rect, const Mat &src,
Rect_<float> &safeBoundRect) {
Rect_<float> boudRect = roi_rect.boundingRect();
// boudRect的左上的x和y有可能小于0
float tl_x = boudRect.x > 0 ? boudRect.x : 0;
float tl_y = boudRect.y > 0 ? boudRect.y : 0;
// boudRect的右下的x和y有可能大于src的范围
float br_x = boudRect.x + boudRect.width < src.cols
? boudRect.x + boudRect.width - 1
: src.cols - 1;
float br_y = boudRect.y + boudRect.height < src.rows
? boudRect.y + boudRect.height - 1
: src.rows - 1;
float roi_width = br_x - tl_x;
float roi_height = br_y - tl_y;
if (roi_width <= 0 || roi_height <= 0) return false;
// 新建一个mat确保地址不越界以防mat定位roi时抛异常
safeBoundRect = Rect_<float>(tl_x, tl_y, roi_width, roi_height);
return true;
}
}

@ -269,7 +269,7 @@ int CPlateLocate::mserSearch(const Mat &src, const Color r, Mat &out,
//}
}
if (1) {
if (0) {
imshow("result", result);
waitKey(0);
}
@ -912,36 +912,6 @@ void CPlateLocate::affine(const Mat &in, Mat &out, const double slope) {
//! 计算一个安全的Rect
//! 如果不存在返回false
bool CPlateLocate::calcSafeRect(const RotatedRect &roi_rect, const Mat &src,
Rect_<float> &safeBoundRect) {
Rect_<float> boudRect = roi_rect.boundingRect();
// boudRect的左上的x和y有可能小于0
float tl_x = boudRect.x > 0 ? boudRect.x : 0;
float tl_y = boudRect.y > 0 ? boudRect.y : 0;
// boudRect的右下的x和y有可能大于src的范围
float br_x = boudRect.x + boudRect.width < src.cols
? boudRect.x + boudRect.width - 1
: src.cols - 1;
float br_y = boudRect.y + boudRect.height < src.rows
? boudRect.y + boudRect.height - 1
: src.rows - 1;
float roi_width = br_x - tl_x;
float roi_height = br_y - tl_y;
if (roi_width <= 0 || roi_height <= 0) return false;
// 新建一个mat确保地址不越界以防mat定位roi时抛异常
safeBoundRect = Rect_<float>(tl_x, tl_y, roi_width, roi_height);
return true;
}
// !基于颜色信息的车牌定位
int CPlateLocate::plateColorLocate(Mat src, vector<CPlate> &candPlates,
@ -1001,13 +971,29 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int index
for (size_t i = 0; i < channelImages.size(); ++i)
{
Mat channelImage = channelImages[i];
int scale_size = 1024;
double scale_ratio = 1;
Mat image = scaleImage(channelImage, Size(scale_size, scale_size), scale_ratio);
//int scale_size = 1024;
//double scale_ratio = 1;
//Mat image = scaleImage(channelImage, Size(scale_size, scale_size), scale_ratio);
Mat image = channelImage;
mserSearch(image, BLUE, src_b, rects_mser_blue, index);
}
for (size_t i = 0; i < rects_mser_blue.size(); ++i)
{
if (0)
{
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "resources/image/tmp/plate_" << i << ".jpg";
Rect_<float> outputRect;
calcSafeRect(rects_mser_blue[i], src, outputRect);
imwrite(ss.str(), src(outputRect));
}
}
//deskew(src, src_b, rects_mser_blue, plates);
//for (size_t i = 0; i < plates.size(); i++) {

@ -6,7 +6,10 @@
#include <fstream>
#include <list>
#include <memory>
#include <numeric>
#include "xml/xmlParser.h"
#include "easypr/core/core_func.h"
#include "easypr/util/util.h"
using namespace std;
@ -41,7 +44,12 @@ namespace easypr {
string plateStr = plateNode.getText();
RotatedRect rr(Point2f(float(x), float(y)), Size2f(float(width), float(height)), angle);
if (width < height) {
std::swap(width, height);
angle = angle + 90;
}
RotatedRect rr(Point2f(float(x), float(y)), Size2f(float(width), float(height)), (float)angle);
CPlate plate;
plate.setPlateStr(plateStr);
@ -133,6 +141,11 @@ namespace easypr {
float match_rate = 0;
// calucate the detect precise and recall
// use icdar 2003 evalution protoocal
vector<float> icdar2003_recall_all;
vector<float> icdar2003_precise_all;
// 开始和结束时间
time_t begin, end;
@ -159,22 +172,106 @@ namespace easypr {
XMLNode xNode = xMainNode.addChild("image");
xNode.addChild("imageName").addText(plateLicense.c_str());
map<string, vector<CPlate>>::iterator it;
XMLNode rectangleNodes = xNode.addChild("taggedRectangles");
vector<CPlate> plateVec;
int result = pr.plateRecognize(src, plateVec);
// get the ground truth and compare it with the detect list;
map<string, vector<CPlate>>::iterator it;
vector<CPlate> plateVecGT;
it = xmlMap.find(plateLicense);
if (it != xmlMap.end()) {
cout << it->first << endl;
vector<CPlate> plateVec = it->second;
for (auto plate : plateVec) {
cout << plate.getPlateStr() << " (g)" << endl;
plateVecGT = it->second;
}
// calucate the detect recall
// use icdar 2003 evalution protoocal
vector<float> icdar2003_recall;
vector<float> icdar2003_precise;
for (auto plate_g : plateVecGT) {
float bestmatch = 0.f;
RotatedRect platePos_g = plate_g.getPlatePos();
Rect_<float> plateRect_g;
calcSafeRect(platePos_g, src, plateRect_g);
for (auto plate_d : plateVec) {
RotatedRect platePos_d = plate_d.getPlatePos();
Rect_<float> plateRect_d;
calcSafeRect(platePos_d, src, plateRect_d);
Rect interRect = plateRect_g & plateRect_d;
float match = 2 * (interRect.area()) / (plateRect_g.area() + plateRect_d.area());
if (match > bestmatch)
bestmatch = match;
}
icdar2003_recall_all.push_back(bestmatch);
icdar2003_recall.push_back(bestmatch);
string plateLicense = plate_g.getPlateStr();
string license = Utils::splitString(plateLicense, ':')[1];
cout << plate_g.getPlateStr() << " (g)" << endl;
if (1)
{
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "resources/image/tmp/plate_" << license << ".jpg";
Mat outMat = src(plateRect_g);
Mat plate_mat;
plate_mat.create(36, 136, 16);
resize(outMat, plate_mat, plate_mat.size(), 0, 0, INTER_AREA);
imwrite(ss.str(), plate_mat);
}
}
XMLNode rectangleNodes = xNode.addChild("taggedRectangles");
vector<CPlate> plateVec;
// calucate the detect precise
// use icdar 2003 evalution protoocal
for (auto plate_d : plateVec) {
float bestmatch = 0.f;
RotatedRect platePos_d = plate_d.getPlatePos();
Rect_<float> plateRect_d;
calcSafeRect(platePos_d, src, plateRect_d);
for (auto plate_g : plateVecGT) {
RotatedRect platePos_g = plate_g.getPlatePos();
Rect_<float> plateRect_g;
calcSafeRect(platePos_g, src, plateRect_g);
Rect interRect = plateRect_g & plateRect_d;
float match = 2 * (interRect.area()) / (plateRect_g.area() + plateRect_d.area());
if (match > bestmatch)
bestmatch = match;
}
icdar2003_precise_all.push_back(bestmatch);
icdar2003_precise.push_back(bestmatch);
}
double recall_result = 0;
if (icdar2003_recall.size() > 0) {
recall_result = std::accumulate(icdar2003_recall.begin(),
icdar2003_recall.end(), 0.0) / (double)icdar2003_recall.size();
}
double precise_result = 0;
if (icdar2003_precise.size() > 0) {
precise_result = std::accumulate(icdar2003_precise.begin(),
icdar2003_precise.end(), 0.0) / (double)icdar2003_precise.size();
}
double fscore_result = 0;
if (recall_result + precise_result != 0) {
fscore_result = 2 * (recall_result * precise_result) /
(recall_result + precise_result);
}
int result = pr.plateRecognize(src, plateVec);
//int result = pr.plateRecognizeAsText(src, plateVec);
if (result == 0) {
int num = plateVec.size();
@ -222,17 +319,13 @@ namespace easypr {
cout << kv->get("diff") << ":" << mindiff << kv->get("char") << endl;
if (mindiff == 0) {
// 完全匹配
match_count++;
}
diff_all = diff_all + mindiff;
}
else {
// 单车牌只计算一次diff
for (int j = 0; j < num; j++) {
cout << plateVec[j].getPlateStr() << endl;
@ -271,11 +364,17 @@ namespace easypr {
}
}
}
cout << "Recall" << ":" << recall_result << ", ";
cout << "Precise" << ":" << precise_result << ", ";
cout << "Fscore" << ":" << fscore_result << ". " << endl;
}
else {
cout << kv->get("error_code") << ":" << result << endl;
count_err++;
}
count_all++;
}
time(&end);
@ -302,6 +401,29 @@ namespace easypr {
match_rate = match_count / count_recogin * 100;
}
double recall_2003_result = 0;
if (icdar2003_recall_all.size() > 0) {
recall_2003_result = std::accumulate(icdar2003_recall_all.begin(),
icdar2003_recall_all.end(), 0.0) / (double)icdar2003_recall_all.size();
}
double precise_2003_result = 0;
if (icdar2003_precise_all.size() > 0) {
precise_2003_result = std::accumulate(icdar2003_precise_all.begin(),
icdar2003_precise_all.end(), 0.0) / (double)icdar2003_precise_all.size();
}
double fscore_2003_result = 0;
if (recall_2003_result + precise_2003_result != 0) {
fscore_2003_result = 2 * (recall_2003_result * precise_2003_result) /
(recall_2003_result + precise_2003_result);
}
cout << "Detect quality evalution result:" << endl;
cout << "Recall" << ":" << recall_2003_result << ", ";
cout << "Precise" << ":" << precise_2003_result << ", ";
cout << "Fscore" << ":" << fscore_2003_result << ". " << endl;
cout << kv->get("diff_average") << ":" << diff_avg << ", ";
cout << kv->get("full_match") << ":" << match_count << ", ";
cout << kv->get("full_rate") << ":" << match_rate << "% " << endl;
@ -311,7 +433,6 @@ namespace easypr {
cout << kv->get("seconds") << ":" << seconds << kv->get("sec") << ", ";
cout << kv->get("seconds_average") << ":" << avgsec << kv->get("sec") << endl;
cout << kv->get("unrecognized") << ":" << endl;
for (auto it = not_recognized_files.begin(); it != not_recognized_files.end();
@ -320,7 +441,6 @@ namespace easypr {
}
cout << endl;
cout << "------------------" << endl;
ofstream myfile("accuracy.txt", ios::app);

Loading…
Cancel
Save