* optimization for speed, using openMP and vector reserve for 10x times faster.

* use native rect inter and rect union, and native min and max to accelerate the speed.
v1.6alpha
liuruoze 9 years ago committed by Micooz
parent f2629b60f3
commit 94755feec8

2
.gitignore vendored

@ -13,6 +13,8 @@ resources/image/tmp/
experi
/tmp
resources/image/native_test/*.jpg
*.vsp
*.psess
#ignore thumbnails created by windows
Thumbs.db

@ -35,4 +35,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
EndGlobal

@ -54,7 +54,6 @@ bool verifyRotatedPlateSizes(RotatedRect mr, bool showDebug = false);
// non-maximum suppression
void NMStoCharacter(std::vector<CCharacter> &inVec, double overlap);
// draw rotatedRectangle
void rotatedRectangle(InputOutputArray img, RotatedRect rect,
const Scalar& color, int thickness = 1,
@ -73,7 +72,12 @@ RotatedRect scaleBackRRect(const RotatedRect& rr, const float scale_ratio);
void mserCharMatch(const Mat &src, std::vector<Mat> &match, std::vector<CPlate>& out_plateVec_blue, std::vector<CPlate>& out_plateVec_yellow,
bool usePlateMser, std::vector<RotatedRect>& out_plateRRect_blue, std::vector<RotatedRect>& out_plateRRect_yellow, int index = 0, bool showDebug = false);
bool computeIOU(RotatedRect rrect1, RotatedRect rrect2, const Mat& img, float thresh);
// computer the insert over union about two rrect
bool computeIOU(const RotatedRect& rrect1, const RotatedRect& rrect2, const int width, const int height, const float thresh, float& result);
float computeIOU(const RotatedRect& rrect1, const RotatedRect& rrect2, const int width, const int height);
bool computeIOU(const Rect& rect1, const Rect& rect2, const float thresh, float& result);
float computeIOU(const Rect& rect1, const Rect& rect2);
/** @brief convert form mser point to image.
@ -92,6 +96,8 @@ Rect adaptive_charrect_from_rect(const Rect& rect, int maxwidth, int maxheight);
// calc safe rect
bool calcSafeRect(const RotatedRect& roi_rect, const Mat& src,
Rect_<float>& safeBoundRect);
bool calcSafeRect(const RotatedRect &roi_rect, const int width, const int height,
Rect_<float> &safeBoundRect);
// shift an image
Mat translateImg(Mat img, int offsetx, int offsety);

@ -436,7 +436,7 @@
<image>
<imageName>ÕãAM690M</imageName>
<taggedRectangles>
<taggedRectangle x="1783" y="1031" width="311" height="73" rotation="0" locateType="2">À¶ÅÆ:ÕãAM69UM</taggedRectangle>
<taggedRectangle x="1772" y="1031" width="285" height="73" rotation="-1" locateType="2">À¶ÅÆ:ÔÁAM69UT</taggedRectangle>
</taggedRectangles>
</image>
<image>

@ -1718,3 +1718,133 @@ Recall:72.9967%, Precise:72.0466%, Fscore:72.5186%.
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:639秒, 平均执行时间:2.54582秒
2016-07-04 15:30:38
总图片数:251, Plates count:290, 未定位车牌:52, 定位率:82.069%
Recall:73.6455%, Precise:72.9158%, Fscore:73.2788%.
0-error:61.1872%, 1-error:69.4064%, Chinese-precise:72.1461%
总时间:911秒, 平均执行时间:3.62948秒
2016-07-04 16:01:24
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:516秒, 平均执行时间:2.05578秒
2016-07-04 16:28:30
总图片数:0, Plates count:0, 未定位车牌:0, 定位率:-1.#IND%
Recall:0%, Precise:0%, Fscore:0%.
0-error:0%, 1-error:0%, Chinese-precise:100%
总时间:0秒, 平均执行时间:-1.#IND秒
2016-07-04 16:34:18
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:344秒, 平均执行时间:1.37052秒
2016-07-04 17:20:33
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:106秒, 平均执行时间:0.422311秒
2016-07-04 17:28:44
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:109秒, 平均执行时间:0.434263秒
2016-07-04 17:37:16
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:90秒, 平均执行时间:0.358566秒
2016-07-04 17:39:16
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:92秒, 平均执行时间:0.366534秒
2016-07-04 17:45:25
总图片数:251, Plates count:290, 未定位车牌:123, 定位率:57.5862%
Recall:55.0799%, Precise:70.6969%, Fscore:61.9189%.
0-error:12.3288%, 1-error:17.1233%, Chinese-precise:21.2329%
总时间:28秒, 平均执行时间:0.111554秒
2016-07-04 17:48:10
总图片数:251, Plates count:290, 未定位车牌:123, 定位率:57.5862%
Recall:55.0799%, Precise:70.6969%, Fscore:61.9189%.
0-error:12.3288%, 1-error:17.1233%, Chinese-precise:21.2329%
总时间:27秒, 平均执行时间:0.10757秒
2016-07-04 17:51:52
总图片数:251, Plates count:290, 未定位车牌:35, 定位率:87.931%
Recall:80.0841%, Precise:68.3041%, Fscore:73.7265%.
0-error:51.4644%, 1-error:59.8326%, Chinese-precise:63.1799%
总时间:115秒, 平均执行时间:0.458167秒
2016-07-04 17:54:25
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:90秒, 平均执行时间:0.358566秒
2016-07-04 17:56:19
总图片数:251, Plates count:290, 未定位车牌:123, 定位率:57.5862%
Recall:55.0799%, Precise:71.648%, Fscore:62.2809%.
0-error:12.3288%, 1-error:17.1233%, Chinese-precise:20.5479%
总时间:27秒, 平均执行时间:0.10757秒
2016-07-04 17:58:02
总图片数:251, Plates count:290, 未定位车牌:123, 定位率:57.5862%
Recall:55.0799%, Precise:71.648%, Fscore:62.2809%.
0-error:61.4379%, 1-error:71.8954%, Chinese-precise:74.5098%
总时间:27秒, 平均执行时间:0.10757秒
2016-07-04 18:37:40
总图片数:251, Plates count:290, 未定位车牌:79, 定位率:72.7586%
Recall:65.8679%, Precise:36.3988%, Fscore:46.8874%.
0-error:48.9474%, 1-error:62.1053%, Chinese-precise:64.2105%
总时间:90秒, 平均执行时间:0.358566秒
2016-07-04 18:49:13
总图片数:251, Plates count:290, 未定位车牌:79, 定位率:72.7586%
Recall:65.8679%, Precise:36.3988%, Fscore:46.8874%.
0-error:48.9474%, 1-error:62.1053%, Chinese-precise:64.2105%
总时间:94秒, 平均执行时间:0.374502秒
2016-07-04 18:55:10
总图片数:251, Plates count:290, 未定位车牌:79, 定位率:72.7586%
Recall:65.8679%, Precise:36.3988%, Fscore:46.8874%.
0-error:48.9474%, 1-error:62.1053%, Chinese-precise:64.2105%
总时间:200秒, 平均执行时间:0.796813秒
2016-07-04 19:00:06
总图片数:251, Plates count:290, 未定位车牌:79, 定位率:72.7586%
Recall:65.8679%, Precise:36.3988%, Fscore:46.8874%.
0-error:48.9474%, 1-error:62.1053%, Chinese-precise:64.2105%
总时间:202秒, 平均执行时间:0.804781秒
2016-07-04 19:02:53
总图片数:251, Plates count:290, 未定位车牌:123, 定位率:57.5862%
Recall:55.0799%, Precise:71.648%, Fscore:62.2809%.
0-error:61.4379%, 1-error:71.8954%, Chinese-precise:74.5098%
总时间:68秒, 平均执行时间:0.270916秒
2016-07-04 20:04:10
总图片数:251, Plates count:290, 未定位车牌:123, 定位率:57.5862%
Recall:55.0799%, Precise:71.648%, Fscore:62.2809%.
0-error:61.4379%, 1-error:71.8954%, Chinese-precise:74.5098%
总时间:70秒, 平均执行时间:0.278884秒
2016-07-04 20:05:50
总图片数:251, Plates count:290, 未定位车牌:123, 定位率:57.5862%
Recall:55.0799%, Precise:71.648%, Fscore:62.2809%.
0-error:61.4379%, 1-error:71.8954%, Chinese-precise:74.5098%
总时间:69秒, 平均执行时间:0.2749秒
2016-07-04 20:07:29
总图片数:251, Plates count:290, 未定位车牌:123, 定位率:57.5862%
Recall:55.0799%, Precise:71.648%, Fscore:62.2809%.
0-error:61.4379%, 1-error:71.8954%, Chinese-precise:74.5098%
总时间:69秒, 平均执行时间:0.2749秒
2016-07-04 20:14:35
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:314秒, 平均执行时间:1.251秒
2016-07-04 20:35:07
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.5919%, Precise:76.6902%, Fscore:75.6265%.
0-error:60.3604%, 1-error:69.3694%, Chinese-precise:72.973%
总时间:312秒, 平均执行时间:1.24303秒
2016-07-04 20:41:00
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.6006%, Precise:76.6991%, Fscore:75.6353%.
0-error:60.3604%, 1-error:68.9189%, Chinese-precise:72.5225%
总时间:304秒, 平均执行时间:1.21116秒
2016-07-04 20:49:41
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.6006%, Precise:76.6991%, Fscore:75.6353%.
0-error:60.3604%, 1-error:68.9189%, Chinese-precise:72.5225%
总时间:303秒, 平均执行时间:1.20717秒

File diff suppressed because it is too large Load Diff

@ -1,5 +1,6 @@
#include "easypr/core/plate_judge.h"
#include "easypr/config.h"
#include "easypr/core/core_func.h"
namespace easypr {
@ -88,10 +89,12 @@ namespace easypr {
for (; itc != inVec.end();) {
CPlate plateComp = *itc;
Rect rectComp = plateComp.getPlatePos().boundingRect();
Rect rectInter = rectSrc & rectComp;
Rect rectUnion = rectSrc | rectComp;
double r = double(rectInter.area()) / double(rectUnion.area());
if (r > overlap) {
//Rect rectInter = rectSrc & rectComp;
//Rect rectUnion = rectSrc | rectComp;
//double r = double(rectInter.area()) / double(rectUnion.area());
float iou = computeIOU(rectSrc, rectComp);
if (iou > overlap) {
itc = inVec.erase(itc);
}
else {
@ -136,6 +139,9 @@ namespace easypr {
if (useCascadeJudge) {
int resultCascade = plateSetScore(plate);
if (plate.getPlateLocateType() != CMSER)
plate.setPlateMat(inMat);
if (resultCascade == 0) {
if (0) {
imshow("tmpDes", tmpDes);

@ -83,10 +83,15 @@ int CPlateLocate::mserSearch(const Mat &src, vector<Mat> &out,
vector<Mat> match_grey;
vector<CPlate> plateVec_blue;
plateVec_blue.reserve(16);
vector<RotatedRect> plateRRect_blue;
plateRRect_blue.reserve(16);
vector<CPlate> plateVec_yellow;
plateVec_yellow.reserve(16);
vector<RotatedRect> plateRRect_yellow;
plateRRect_yellow.reserve(16);
mserCharMatch(src, match_grey, plateVec_blue, plateVec_yellow, usePlateMser, plateRRect_blue, plateRRect_yellow, img_index, showDebug);
@ -708,25 +713,45 @@ void CPlateLocate::affine(const Mat &in, Mat &out, const double slope) {
int CPlateLocate::plateColorLocate(Mat src, vector<CPlate> &candPlates,
int index) {
vector<RotatedRect> rects_color_blue;
rects_color_blue.reserve(64);
vector<RotatedRect> rects_color_yellow;
vector<CPlate> plates;
Mat src_b;
rects_color_yellow.reserve(64);
vector<CPlate> plates_blue;
plates_blue.reserve(64);
vector<CPlate> plates_yellow;
plates_yellow.reserve(64);
#pragma omp parallel sections
{
#pragma omp section
{
Mat src_b_blue;
colorSearch(src, BLUE, src_b_blue, rects_color_blue, index);
deskew(src, src_b_blue, rects_color_blue, plates_blue, true, BLUE);
}
#pragma omp section
{
Mat src_b_yellow;
colorSearch(src, YELLOW, src_b_yellow, rects_color_yellow, index);
deskew(src, src_b_yellow, rects_color_yellow, plates_yellow, true, YELLOW);
}
}
colorSearch(src, BLUE, src_b, rects_color_blue, index);
deskew(src, src_b, rects_color_blue, plates);
candPlates.insert(candPlates.end(), plates_blue.begin(), plates_blue.end());
candPlates.insert(candPlates.end(), plates_yellow.begin(), plates_yellow.end());
colorSearch(src, YELLOW, src_b, rects_color_yellow, index);
deskew(src, src_b, rects_color_yellow, plates);
//for (auto plate : plates_blue)
// candPlates.push_back(plate);
//for (auto plate : plates_yellow)
// candPlates.push_back(plate);
for (size_t i = 0; i < plates.size(); i++) {
candPlates.push_back(plates[i]);
}
return 0;
}
//! MSER plate locate
int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_index) {
std::vector<Mat> channelImages;
std::vector<Color> flags;
@ -770,8 +795,11 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
Color color = flags.at(j);
vector<RotatedRect> rects_mser;
rects_mser.reserve(64);
std::vector<CPlate> deskewPlate;
deskewPlate.reserve(64);
std::vector<CPlate> mserPlate;
mserPlate.reserve(64);
// deskew for rotation and slope image
for (auto plate : plates) {
@ -798,7 +826,8 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
for (auto splate : mserPlate) {
RotatedRect srect = splate.getPlatePos();
bool isSimilar = computeIOU(drect, srect, src, 0.95f);
float iou = 0.f;
bool isSimilar = computeIOU(drect, srect, src.cols, src.rows, 0.95f, iou);
if (isSimilar) {
splate.setPlateMat(dmat);
candPlates.push_back(splate);
@ -806,7 +835,8 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
}
}
}
}
}
}
//if (usePlateMser) {
@ -881,7 +911,6 @@ int CPlateLocate::sobelOperT(const Mat &in, Mat &out, int blurSize, int morphW,
Sobel(mat_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x);
Mat grad;
addWeighted(abs_grad_x, 1, 0, 0, 0, grad);
@ -905,19 +934,21 @@ int CPlateLocate::sobelOperT(const Mat &in, Mat &out, int blurSize, int morphW,
int CPlateLocate::plateSobelLocate(Mat src, vector<CPlate> &candPlates,
int index) {
vector<RotatedRect> rects_sobel;
vector<RotatedRect> rects_sobel_sel;
vector<RotatedRect> rects_sobel_all;
rects_sobel_all.reserve(256);
vector<CPlate> plates;
plates.reserve(32);
vector<Rect_<float>> bound_rects;
bound_rects.reserve(256);
sobelFrtSearch(src, bound_rects);
vector<Rect_<float>> bound_rects_part;
bound_rects_part.reserve(256);
// enlarge area
for (size_t i = 0; i < bound_rects.size(); i++) {
float fRatio = bound_rects[i].width * 1.0f / bound_rects[i].height;
if (fRatio < 3.0 && fRatio > 1.0 && bound_rects[i].height < 120) {
@ -940,8 +971,8 @@ int CPlateLocate::plateSobelLocate(Mat src, vector<CPlate> &candPlates,
}
// second processing to split one
for (size_t i = 0; i < bound_rects_part.size(); i++) {
#pragma omp parallel for
for (int i = 0; i < (int)bound_rects_part.size(); i++) {
Rect_<float> bound_rect = bound_rects_part[i];
Point2f refpoint(bound_rect.x, bound_rect.y);
@ -956,10 +987,18 @@ int CPlateLocate::plateSobelLocate(Mat src, vector<CPlate> &candPlates,
Rect_<float> safe_bound_rect(x, y, width, height);
Mat bound_mat = src(safe_bound_rect);
vector<RotatedRect> rects_sobel;
rects_sobel.reserve(128);
sobelSecSearchPart(bound_mat, refpoint, rects_sobel);
#pragma omp critical
{
rects_sobel_all.insert(rects_sobel_all.end(), rects_sobel.begin(), rects_sobel.end());
}
}
for (size_t i = 0; i < bound_rects.size(); i++) {
#pragma omp parallel for
for (int i = 0; i < (int)bound_rects.size(); i++) {
Rect_<float> bound_rect = bound_rects[i];
Point2f refpoint(bound_rect.x, bound_rect.y);
@ -974,16 +1013,25 @@ int CPlateLocate::plateSobelLocate(Mat src, vector<CPlate> &candPlates,
Rect_<float> safe_bound_rect(x, y, width, height);
Mat bound_mat = src(safe_bound_rect);
vector<RotatedRect> rects_sobel;
rects_sobel.reserve(128);
sobelSecSearch(bound_mat, refpoint, rects_sobel);
// sobelSecSearchPart(bound_mat, refpoint, rects_sobel);
#pragma omp critical
{
rects_sobel_all.insert(rects_sobel_all.end(), rects_sobel.begin(), rects_sobel.end());
}
}
Mat src_b;
sobelOper(src, src_b, 3, 10, 3);
deskew(src, src_b, rects_sobel, plates);
deskew(src, src_b, rects_sobel_all, plates);
//for (size_t i = 0; i < plates.size(); i++)
// candPlates.push_back(plates[i]);
for (size_t i = 0; i < plates.size(); i++) candPlates.push_back(plates[i]);
candPlates.insert(candPlates.end(), plates.begin(), plates.end());
return 0;
}

File diff suppressed because it is too large Load Diff

@ -70,6 +70,18 @@ namespace cv
using std::vector;
Rect mergeRect(const Rect& a, const Rect& b) {
Rect c;
int x1 = a.x < b.x ? a.x : b.x;
int y1 = a.y < b.y ? a.y : b.y;
c.width = (a.x + a.width > b.x + b.width ? a.x + a.width : b.x + b.width) - x1;
c.height = (a.y + a.height > b.y + b.height ? a.y + a.height : b.y + b.height) - y1;
c.x = x1;
c.y = y1;
return c;
}
class MSER_Impl2 : public MSER2
{
public:
@ -422,10 +434,15 @@ namespace cv
int y = pix / step;
int x = pix - y*step;
xmin = std::min(xmin, x);
xmax = std::max(xmax, x);
ymin = std::min(ymin, y);
ymax = std::max(ymax, y);
// modifier for more fast
//xmin = std::min(xmin, x);
//xmax = std::max(xmax, x);
//ymin = std::min(ymin, y);
//ymax = std::max(ymax, y);
xmin = xmin < x ? xmin : x;
xmax = xmax > x ? xmax : x;
ymin = ymin < y ? ymin : y;
ymax = ymax > y ? ymax : y;
region[j] = Point(x, y);
}
@ -513,7 +530,9 @@ namespace cv
history = comp1->history;
// add by liuruoze
rect = comp1->rect;
if (wp.p.useOpt)
rect = comp1->rect;
return;
}
@ -529,7 +548,11 @@ namespace cv
size = comp1->size + comp2->size;
// add by liuruoze
rect = comp1->rect | comp2->rect;
if (wp.p.useOpt) {
//rect = comp1->rect | comp2->rect;
rect = mergeRect(comp1->rect, comp2->rect);
}
bool keep_2nd = h2->size > wp.p.minArea;
growHistory(hptr, wp, -1, false, keep_2nd);
@ -682,7 +705,11 @@ namespace cv
if (comptr->tail)
{
ptr0[comptr->tail].setNext(ptrofs);
comptr->rect |= Rect(x, y, 1, 1);
if (params.useOpt) {
//comptr->rect |= Rect(x, y, 1, 1);
comptr->rect = mergeRect(comptr->rect, Rect(x, y, 1, 1));
}
}
else
{
@ -690,7 +717,8 @@ namespace cv
// printf("y : %i \n", y);
comptr->head = ptrofs;
comptr->rect = Rect(x, y, 1, 1);
if (params.useOpt)
comptr->rect = Rect(x, y, 1, 1);
}
comptr->tail = ptrofs;
@ -803,4 +831,5 @@ namespace cv
_min_margin, _edge_blur_size));
}
}

@ -91,6 +91,7 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(OPENCV)\include;$(SolutionDir)include;$(SolutionDir)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
<OpenMPSupport>false</OpenMPSupport>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

@ -90,6 +90,8 @@
<AdditionalIncludeDirectories>$(OPENCV)\include;$(SolutionDir)include;$(SolutionDir);</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>

Loading…
Cancel
Save