* add plateMser locate and change the evaluation protocol.

v1.6alpha
liuruoze 9 years ago
parent 87081ebfb1
commit 2509bfe296

@ -2067,3 +2067,53 @@ Recall:62.3397%, Precise:77.1824%, Fscore:68.9715%.
Recall:62.3397%, Precise:77.1824%, Fscore:68.9715%.
0-error:61.1111%, 1-error:72.2222%, Chinese-precise:75%
总时间:172秒, 平均执行时间:3.44秒
2016-06-30 11:50:01
总图片数:50, Plates count:52, 未识出图片:16, 定位率:69.2308%
Recall:62.3397%, Precise:77.1824%, Fscore:68.9715%.
0-error:61.1111%, 1-error:72.2222%, Chinese-precise:75%
总时间:455秒, 平均执行时间:9.1秒
2016-06-30 12:02:16
总图片数:50, Plates count:52, 未识出图片:15, 定位率:71.1538%
Recall:64.2118%, Precise:75.8867%, Fscore:69.5628%.
0-error:59.4595%, 1-error:72.973%, Chinese-precise:75.6757%
总时间:472秒, 平均执行时间:9.44秒
2016-06-30 12:21:43
总图片数:200, Plates count:238, 未识出图片:49, 定位率:79.4118%
Recall:71.03%, Precise:81.2747%, Fscore:75.8078%.
0-error:59.2593%, 1-error:66.6667%, Chinese-precise:68.7831%
总时间:964秒, 平均执行时间:4.82秒
2016-06-30 15:33:43
总图片数:50, Plates count:52, 未识出图片:15, 定位率:71.1538%
Recall:64.2313%, Precise:75.9097%, Fscore:69.5839%.
0-error:51.3513%, 1-error:64.8649%, Chinese-precise:67.5676%
总时间:323秒, 平均执行时间:6.46秒
2016-06-30 15:38:38
总图片数:50, Plates count:52, 未识出图片:18, 定位率:65.3846%
Recall:59.0292%, Precise:74.8663%, Fscore:66.0111%.
0-error:44.1176%, 1-error:55.8824%, Chinese-precise:58.8235%
总时间:247秒, 平均执行时间:4.94秒
2016-06-30 15:43:40
总图片数:50, Plates count:52, 未识出图片:18, 定位率:65.3846%
Recall:54.2126%, Precise:72.2835%, Fscore:61.9573%.
0-error:52.9412%, 1-error:58.8235%, Chinese-precise:64.7059%
总时间:240秒, 平均执行时间:4.8秒
2016-06-30 15:51:54
总图片数:50, Plates count:52, 未识出图片:23, 定位率:55.7692%
Recall:50.6695%, Precise:75.2804%, Fscore:60.5704%.
0-error:31.0345%, 1-error:37.931%, Chinese-precise:44.8276%
总时间:235秒, 平均执行时间:4.7秒
2016-06-30 16:01:57
总图片数:50, Plates count:52, 未识出图片:15, 定位率:71.1538%
Recall:64.2118%, Precise:75.8867%, Fscore:69.5628%.
0-error:59.4595%, 1-error:72.973%, Chinese-precise:75.6757%
总时间:235秒, 平均执行时间:4.7秒
2016-06-30 16:06:32
总图片数:50, Plates count:52, 未识出图片:10, 定位率:80.7692%
Recall:72.5576%, Precise:70.7495%, Fscore:71.6422%.
0-error:52.381%, 1-error:64.2857%, Chinese-precise:78.5714%
总时间:235秒, 平均执行时间:4.7秒
2016-06-30 16:17:43
总图片数:50, Plates count:52, 未识出图片:42, 定位率:80.7692%
Recall:72.5576%, Precise:70.7495%, Fscore:71.6422%.
0-error:59.4595%, 1-error:72.973%, Chinese-precise:75.6757%
总时间:232秒, 平均执行时间:4.64秒

@ -78,7 +78,10 @@ Mat scaleImage(const Mat& image, const Size& maxSize, double& scale_ratio);
RotatedRect scaleBackRRect(const RotatedRect& rr, const float scale_ratio);
//! use verify size to first generate char candidates
Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& plateVec, Color color, int index = 0, bool showDebug = false);
Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& plateVec, Color color,
bool usePlateMser, std::vector<RotatedRect>& out_plateRRect, int index = 0, bool showDebug = false);
bool computeIOU(RotatedRect rrect1, RotatedRect rrect2, const Mat& img, float thresh);
/** @brief convert form mser point to image.

@ -86,8 +86,9 @@ class CPlateLocate {
std::vector<RotatedRect>& outRects, int index = 0);
//! mser search
int mserSearch(const Mat& src, const Color r, Mat& out,
vector<CPlate>& plateVec, int index = 0, bool showDebug = false);
int mserSearch(const Mat &src, const Color color, Mat &out,
vector<CPlate>& out_plateVec, bool usePlateMser, vector<RotatedRect>& out_plateRRect,
int img_index = 0, bool showDebug = false);
//! 未使用函数与代码
//! 开始------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 KiB

After

Width:  |  Height:  |  Size: 172 KiB

@ -27,7 +27,7 @@
<image>
<imageName>川A561WP</imageName>
<taggedRectangles>
<taggedRectangle x="512" y="180" width="126" height="33" rotation="0" locateType="2">À¶ÅÆ:´¨A561WP</taggedRectangle>
<taggedRectangle x="513" y="180" width="124" height="33" rotation="0" locateType="2">蓝牌:川A561WP</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -69,17 +69,19 @@
<image>
<imageName>川AKQ291</imageName>
<taggedRectangles>
<taggedRectangle x="400" y="156" width="100" height="27" rotation="0" locateType="2">À¶ÅÆ:´¨AKQ291</taggedRectangle>
<taggedRectangle x="404" y="156" width="92" height="27" rotation="0" locateType="2">蓝牌:川AKQ291</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>川AM1186</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="485" y="218" width="88" height="23" rotation="-1" locateType="2">蓝牌</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>川AN4E10</imageName>
<taggedRectangles>
<taggedRectangle x="452" y="186" width="139" height="35" rotation="1" locateType="2">À¶ÅÆ:ÇàAN4E1M</taggedRectangle>
<taggedRectangle x="456" y="186" width="131" height="35" rotation="1" locateType="2">蓝牌:川AW4E10</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -90,7 +92,9 @@
</image>
<image>
<imageName>川AS9V79</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="203" y="39" width="74" height="16" rotation="0" locateType="2">蓝牌</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>川AUU093</imageName>
@ -116,7 +120,9 @@
</image>
<image>
<imageName>桂ATK071</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="1139" y="370" width="71" height="25" rotation="1" locateType="2">蓝牌</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>沪ALB022</imageName>
@ -172,7 +178,10 @@
</image>
<image>
<imageName>渝BE7773</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="841" y="362" width="209" height="65" rotation="13" locateType="2">蓝牌:新6E7743</taggedRectangle>
<taggedRectangle x="695" y="26" width="113" height="25" rotation="-14" locateType="2">蓝牌</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>粤A2HQ34</imageName>
@ -208,12 +217,14 @@
</image>
<image>
<imageName>粤BA103N</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="313" y="177" width="105" height="32" rotation="7" locateType="2">蓝牌</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>粤BDB720</imageName>
<taggedRectangles>
<taggedRectangle x="920" y="657" width="125" height="30" rotation="0" locateType="2">À¶ÅÆ:ÔÁBDB720</taggedRectangle>
<taggedRectangle x="918" y="657" width="120" height="30" rotation="0" locateType="2">蓝牌:粤BDB720</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -231,11 +242,14 @@
<imageName>粤X30479</imageName>
<taggedRectangles>
<taggedRectangle x="1692" y="895" width="226" height="49" rotation="0" locateType="2">蓝牌:新QF5224</taggedRectangle>
<taggedRectangle x="1095" y="793" width="196" height="53" rotation="-3" locateType="2">黄牌</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>苏A20Q03</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="483" y="351" width="257" height="60" rotation="-2" locateType="2">蓝牌</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>苏A36E80</imageName>
@ -267,13 +281,18 @@
</image>
<image>
<imageName>苏AVW997</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="365" y="414" width="85" height="32" rotation="-15" locateType="2">蓝牌</taggedRectangle>
<taggedRectangle x="317" y="428" width="57" height="21" rotation="-26" locateType="2">蓝牌</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>豫U00000</imageName>
<taggedRectangles>
<taggedRectangle x="888" y="650" width="112" height="28" rotation="0" locateType="2">蓝牌:豫1DQPQU</taggedRectangle>
<taggedRectangle x="1278" y="84" width="297" height="51" rotation="15" locateType="2">黄牌:渝1QXT11</taggedRectangle>
<taggedRectangle x="211" y="28" width="125" height="28" rotation="0" locateType="2">蓝牌:辽0T507</taggedRectangle>
<taggedRectangle x="208" y="104" width="94" height="28" rotation="0" locateType="2">蓝牌</taggedRectangle>
</taggedRectangles>
</image>
<image>

@ -1313,6 +1313,27 @@ bool judegMDOratio2(const Mat& image, const Rect& rect, std::vector<Point>& cont
return true;
}
bool computeIOU(RotatedRect rrect1, RotatedRect rrect2, const Mat& img, float thresh) {
Rect_<float> safe_rect1;
calcSafeRect(rrect1, img, safe_rect1);
Rect_<float> safe_rect2;
calcSafeRect(rrect2, img, safe_rect2);
Rect inter = safe_rect1 & safe_rect2;
Rect urect = safe_rect1 | safe_rect2;
float iou = (float)inter.area() / (float)urect.area();
//std::cout << "iou" << iou << std::endl;
if (iou > thresh) {
return true;
}
return false;
}
bool judegMDOratio(const Mat& image, const Rect& rect, std::vector<Point>& contour, Mat& result){
Rect normalRect = adaptive_charrect_from_rect(rect, image.cols, image.rows);
@ -1571,7 +1592,8 @@ void removeOutliers(std::vector<CCharacter>& charGroup, double thresh, Mat resul
}
//! use verify size to first generate char candidates
Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& out_plateVec, Color color, int img_index,
Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& out_plateVec, Color color,
bool usePlateMser, std::vector<RotatedRect>& out_plateRRect, int img_index,
bool showDebug) {
Mat image = src;
@ -1605,7 +1627,14 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& out_plateVec,
for (size_t index = 0; index < size; index++) {
Rect rect = all_boxes[index];
std::vector<Point> contour = all_contours[index];
RotatedRect rrect = minAreaRect(Mat(contour));
if (usePlateMser && verifyRotatedPlateSizes(rrect)) {
//rotatedRectangle(result, rrect, Scalar(255, 0, 0), 2);
out_plateRRect.push_back(rrect);
}
// find character
if (verifyCharSizes(rect)) {
Mat mserMat = adaptive_image_from_points(contour, rect, Size(char_size, char_size));
Mat charInput = preprocessChar(mserMat, char_size);
@ -1832,7 +1861,7 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& out_plateVec,
}
if (mserCharacter.size() < 7) {
double thresh1 = 0.1;
double thresh1 = 0.15;
double thresh2 = 2.0;
searchWeakSeed(searchCandidate, searchRightWeakSeed, thresh1, thresh2, line, rightPoint,
maxrect, plateResult, result, CharSearchDirection::RIGHT);

@ -180,7 +180,7 @@ namespace easypr {
if (1) {
imshow("EasyPR", img_window);
waitKey(500);
waitKey(0);
destroyWindow("EasyPR");
}

@ -135,6 +135,8 @@ namespace easypr {
int resultCascade = plateSetScore(plate);
//plate.setPlateMat(inMat);
if (resultCascade == 0) {
if (0) {
imshow("inMat", inMat);

@ -81,12 +81,18 @@ bool CPlateLocate::verifySizes(RotatedRect mr) {
//! mser search method
int CPlateLocate::mserSearch(const Mat &src, const Color color, Mat &out,
vector<CPlate>& out_plateVec, int img_index, bool showDebug) {
vector<CPlate>& out_plateVec, bool usePlateMser, vector<RotatedRect>& out_plateRRect,
int img_index, bool showDebug) {
Mat match_grey;
vector<CPlate> plateVec;
//mserMatch(src, match_grey, r, plateRects, charRects);
mserCharMatch(src, match_grey, plateVec, color, img_index, showDebug);
vector<RotatedRect> plateRRect;
mserCharMatch(src, match_grey, plateVec, color, usePlateMser, plateRRect, img_index, showDebug);
for (auto rrect : plateRRect) {
out_plateRRect.push_back(rrect);
}
//calculet avg dist
/*float sumdist = 0, avgdist = 0;
@ -861,7 +867,8 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
CPlate plate;
plate.setPlatePos(roi_rect);
plate.setPlateMat(plate_mat);
if (color != UNKNOWN) plate.setPlateColor(color);
outPlates.push_back(plate);
}
}
@ -1105,6 +1112,15 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
std::vector<Mat> channelImages;
std::vector<Color> flags;
std::vector<RotatedRect> all_plateRRect;
vector<CPlate> all_plates;
vector<Mat> src_b_vec;
bool usePlateMser = false;
int scale_size = 1024;
double scale_ratio = 1;
// only conside blue plate
if (1) {
Mat grayImage;
@ -1121,9 +1137,6 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
flags.push_back(YELLOW);
}
int scale_size = 1024;
double scale_ratio = 1;
for (size_t i = 0; i < channelImages.size(); ++i) {
vector<RotatedRect> rects_mser;
vector<CPlate> plates;
@ -1134,7 +1147,9 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
Mat image = scaleImage(channelImage, Size(scale_size, scale_size), scale_ratio);
// vector<RotatedRect> rects;
mserSearch(image, color, src_b, plates, img_index, false);
mserSearch(image, color, src_b, plates, usePlateMser, all_plateRRect, img_index, false);
//std::copy(plateRRect.begin(), plateRRect.end(), all_plateRRect.end());
std::vector<CPlate> deskewPlate;
std::vector<CPlate> mserPlate;
@ -1148,39 +1163,94 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
RotatedRect scaleRect = scaleBackRRect(rrect, (float)scale_ratio);
plate.setPlatePos(scaleRect);
plate.setPlateColor(color);
rects_mser.push_back(scaleRect);
mserPlate.push_back(plate);
all_plates.push_back(plate);
}
Mat resize_src_b;
resize(src_b, resize_src_b, Size(channelImage.cols, channelImage.rows));
src_b_vec.push_back(resize_src_b);
deskew(src, resize_src_b, rects_mser, deskewPlate, false, color);
for (auto dplate : deskewPlate) {
RotatedRect drect = dplate.getPlatePos();
Mat dmat = dplate.getPlateMat();
Rect_<float> safe_dRect;
calcSafeRect(drect, src, safe_dRect);
//Rect_<float> safe_dRect;
//calcSafeRect(drect, src, safe_dRect);
for (auto splate : mserPlate) {
RotatedRect srect = splate.getPlatePos();
Rect_<float> safe_sRect;
calcSafeRect(srect, src, safe_sRect);
Rect inter = safe_dRect & safe_sRect;
Rect urect = safe_dRect | safe_sRect;
float iou = (float)inter.area() / (float)urect.area();
//std::cout << "iou" << iou << std::endl;
if (iou > 0.95) {
bool isSimilar = computeIOU(drect, srect, src, 0.95f);
if (isSimilar) {
splate.setPlateMat(dmat);
candPlates.push_back(splate);
break;
}
//Rect_<float> safe_sRect;
//calcSafeRect(srect, src, safe_sRect);
//Rect inter = safe_dRect & safe_sRect;
//Rect urect = safe_dRect | safe_sRect;
//float iou = (float)inter.area() / (float)urect.area();
////std::cout << "iou" << iou << std::endl;
//if (iou > 0.95) {
// splate.setPlateMat(dmat);
// candPlates.push_back(splate);
// break;
//}
}
}
}
if (usePlateMser) {
std::vector<RotatedRect> plateRRect_B;
std::vector<RotatedRect> plateRRect_Y;
for (auto rrect : all_plateRRect) {
RotatedRect theRect = scaleBackRRect(rrect, (float)scale_ratio);
//rotatedRectangle(src, theRect, Scalar(255, 0, 0));
for (auto plate : all_plates) {
RotatedRect plateRect = plate.getPlatePos();
//rotatedRectangle(src, plateRect, Scalar(0, 255, 0));
bool isSimilar = computeIOU(theRect, plateRect, src, 0.8f);
if (isSimilar) {
//rotatedRectangle(src, theRect, Scalar(0, 0, 255));
Color color = plate.getPlateColor();
if (color == BLUE) plateRRect_B.push_back(theRect);
if (color == YELLOW) plateRRect_Y.push_back(theRect);
}
}
}
for (size_t i = 0; i < channelImages.size(); ++i) {
Color color = flags.at(i);
Mat resize_src_b = src_b_vec.at(i);
std::vector<CPlate> deskewMserPlate;
if (color == BLUE)
deskew(src, resize_src_b, plateRRect_B, deskewMserPlate, false, color);
if (color == YELLOW)
deskew(src, resize_src_b, plateRRect_Y, deskewMserPlate, false, color);
for (auto plate : deskewMserPlate) {
candPlates.push_back(plate);
}
}
}
if (0) {
imshow("src", src);
waitKey(0);
destroyWindow("src");
}
return 0;
}

@ -350,6 +350,9 @@ int CPlateRecognize::plateRecognize(Mat src, std::vector<CPlate> &licenseVec, in
licenseVec.push_back(item);
}
else {
std::string license = plateColor;
item.setPlateStr(license);
licenseVec.push_back(item);
if (1) {
std::cout << "resultCR:" << resultCR << std::endl;
}

@ -86,7 +86,7 @@ namespace easypr {
CPlateRecognize pr;
// 设置Debug模式
pr.setResultShow(true);
pr.setResultShow(false);
pr.setLifemode(true);
// 设置要处理的一张图片中最多有多少车牌
pr.setMaxPlates(4);
@ -118,11 +118,11 @@ namespace easypr {
// 未识别的图片数量
int count_norecogin = 0;
int count_nodetect = 0;
int count_norecogn = 0;
std::list<std::string> not_recognized_files;
// all the ground-truth plates
float all_plate_count = 0;
@ -225,7 +225,7 @@ namespace easypr {
all_plate_count++;
if (matchPlate) {
if (matchPlate && bestmatch > 0.5f) {
string matchPlateLicense = matchPlate->getPlateStr();
vector<string> spilt_plate = Utils::splitString(matchPlateLicense, ':');
@ -263,13 +263,14 @@ namespace easypr {
}
else {
cout << "No string" << " (d)" << endl;
count_norecogn++;
}
}
else {
cout << kv->get("empty_plate") << endl;
if (license != kv->get("empty_plate")) {
not_recognized_files.push_back(license);
count_norecogin++;
count_nodetect++;
}
}
@ -360,10 +361,12 @@ namespace easypr {
xMainNode.writeToFile(path_result.c_str());
float count_recogin = float(all_plate_count - count_norecogin);
float count_rate = count_recogin / all_plate_count;
float count_detect = float(all_plate_count - count_nodetect);
float count_rate = count_detect / all_plate_count;
cout << kv->get("locate_rate") << ":" << count_rate * 100 << "% " << endl;
float count_recogin = float(count_detect - count_norecogn);
if (count_recogin > 0) {
non_error_rate = non_error_count / count_recogin;
one_error_rate = one_error_count / count_recogin;
@ -424,7 +427,7 @@ namespace easypr {
myfile << kv->get("sum_pictures") << ":" << count_all << ", ";
myfile << "Plates count" << ":" << all_plate_count << ", ";
myfile << kv->get("unrecognized") << ":" << count_norecogin << ", ";
myfile << kv->get("unrecognized") << ":" << count_nodetect << ", ";
myfile << kv->get("locate_rate") << ":" << count_rate * 100 << "% "
<< endl;

Loading…
Cancel
Save