* use annChinese model to predict and judge chinese, improve the over all accuracy of Chinese recognition rate.

v1.6alpha
liuruoze 9 years ago
parent 79de3be046
commit 657c96289c

@ -2007,3 +2007,58 @@ Recall:65.5408%, Precise:74.0896%, Fscore:69.5535%.
Recall:65.9247%, Precise:76.1797%, Fscore:70.6822%.
0-error:34.2105%, 1-error:39.4737%, Chinese-precise:42.1053%
总时间:211秒, 平均执行时间:4.22秒
2016-06-29 20:06:11
总图片数:50, Plates count:52, 未识出图片:17, 定位率:67.3077%
Recall:60.6032%, Precise:75.0326%, Fscore:67.0504%.
0-error:25.7143%, 1-error:31.4286%, Chinese-precise:34.2857%
总时间:219秒, 平均执行时间:4.38秒
2016-06-29 20:16:39
总图片数:50, Plates count:52, 未识出图片:14, 定位率:73.0769%
Recall:65.9247%, Precise:76.1797%, Fscore:70.6822%.
0-error:34.2105%, 1-error:39.4737%, Chinese-precise:42.1053%
总时间:173秒, 平均执行时间:3.46秒
2016-06-29 20:54:03
总图片数:50, Plates count:52, 未识出图片:15, 定位率:71.1538%
Recall:64.2817%, Precise:75.9692%, Fscore:69.6385%.
0-error:45.9459%, 1-error:51.3513%, Chinese-precise:54.0541%
总时间:173秒, 平均执行时间:3.46秒
2016-06-29 21:03:43
总图片数:50, Plates count:52, 未识出图片:15, 定位率:71.1538%
Recall:64.2817%, Precise:75.9692%, Fscore:69.6385%.
0-error:45.9459%, 1-error:51.3513%, Chinese-precise:54.0541%
总时间:172秒, 平均执行时间:3.44秒
2016-06-29 21:09:46
总图片数:50, Plates count:52, 未识出图片:15, 定位率:71.1538%
Recall:64.2817%, Precise:75.9692%, Fscore:69.6385%.
0-error:48.6487%, 1-error:54.0541%, Chinese-precise:56.7568%
总时间:179秒, 平均执行时间:3.58秒
2016-06-29 21:17:50
总图片数:50, Plates count:52, 未识出图片:15, 定位率:71.1538%
Recall:64.2817%, Precise:75.9692%, Fscore:69.6385%.
0-error:48.6487%, 1-error:56.7568%, Chinese-precise:62.1622%
总时间:174秒, 平均执行时间:3.48秒
2016-06-29 22:07:46
总图片数:50, Plates count:52, 未识出图片:15, 定位率:71.1538%
Recall:64.2817%, Precise:75.9692%, Fscore:69.6385%.
0-error:56.7568%, 1-error:67.5676%, Chinese-precise:70.2703%
总时间:173秒, 平均执行时间:3.46秒
2016-06-30 07:58:41
总图片数:200, Plates count:238, 未识出图片:51, 定位率:78.5714%
Recall:70.293%, Precise:81.8988%, Fscore:75.6534%.
0-error:63.6364%, 1-error:73.7968%, Chinese-precise:74.3316%
总时间:715秒, 平均执行时间:3.575秒
2016-06-30 08:16:14
总图片数:200, Plates count:238, 未识出图片:51, 定位率:78.5714%
Recall:70.293%, Precise:81.8988%, Fscore:75.6534%.
0-error:35.2941%, 1-error:41.7112%, Chinese-precise:41.7112%
总时间:707秒, 平均执行时间:3.535秒
2016-06-30 08:30:44
总图片数:200, Plates count:238, 未识出图片:51, 定位率:78.5714%
Recall:70.293%, Precise:81.8988%, Fscore:75.6534%.
0-error:60.9626%, 1-error:69.5187%, Chinese-precise:69.5187%
总时间:701秒, 平均执行时间:3.505秒
2016-06-30 09:07:11
总图片数: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%
总时间:174秒, 平均执行时间:3.48秒

@ -18,6 +18,7 @@ namespace easypr {
static const char* kDefaultSvmPath = "resources/model/svm.xml";
static const char* kDefaultAnnPath = "resources/model/ann.xml";
static const char* kChineseAnnPath = "resources/model/ann_chinese.xml";
typedef enum {
kForward = 1, // correspond to "has plate"

@ -16,13 +16,13 @@ class CharsIdentify {
void classify(cv::Mat featureRows, std::vector<int>& out_maxIndexs,
std::vector<float>& out_maxVals, std::vector<bool> isChineseVec);
void classify(std::vector<CCharacter>& charVec);
void classifyChinese(std::vector<CCharacter>& charVec);
std::pair<std::string, std::string> identify(cv::Mat input, bool isChinese = false);
int identify(std::vector<cv::Mat> inputs, std::vector<std::pair<std::string, std::string>>& outputs,
std::vector<bool> isChineseVec);
std::pair<std::string, std::string> identifyChinese(cv::Mat input);
std::pair<std::string, std::string> identifyChinese(cv::Mat input, float& result, bool& isChinese);
bool isCharacter(cv::Mat input, std::string& label, float& maxVal, bool isChinese = false);
@ -32,6 +32,7 @@ class CharsIdentify {
static CharsIdentify* instance_;
cv::Ptr<cv::ml::ANN_MLP> ann_;
cv::Ptr<cv::ml::ANN_MLP> annChinese_;
std::shared_ptr<Kv> kv_;
};
}

@ -17,6 +17,9 @@ class CCharsSegment {
bool verifyCharSizes(Mat r);
// find the best chinese binaranzation method
void judgeChinese(Mat in, Mat& out, Color plateType);
//! 字符预处理
Mat preprocessChar(Mat in);

@ -47,7 +47,7 @@ class CPlateLocate {
int deskew(const Mat& src, const Mat& src_b,
std::vector<RotatedRect>& inRects, std::vector<CPlate>& outPlates,
bool useDeteleArea = true);
bool useDeteleArea = true, Color color = UNKNOWN);
//! 是否偏斜
//! 输入二值化图像,输出判断结果

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 KiB

After

Width:  |  Height:  |  Size: 296 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -2,7 +2,9 @@
<tagset>
<image>
<imageName>¾©FK5358</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="846" y="276" width="153" height="45" rotation="2" locateType="2">蓝牌:辽FK5358</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨A095Q5</imageName>
@ -13,25 +15,25 @@
<image>
<imageName>´¨A105LR</imageName>
<taggedRectangles>
<taggedRectangle x="340" y="312" width="144" height="37" rotation="2" locateType="2">蓝牌:川A105LR</taggedRectangle>
<taggedRectangle x="339" y="312" width="146" height="37" rotation="2" locateType="2">蓝牌:陕AY05LR</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨A113YP</imageName>
<taggedRectangles>
<taggedRectangle x="346" y="207" width="138" height="33" rotation="0" locateType="2">蓝牌:A113YP</taggedRectangle>
<taggedRectangle x="346" y="207" width="138" height="33" rotation="0" locateType="2">蓝牌:A113YP</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨A561WP</imageName>
<taggedRectangles>
<taggedRectangle x="519" y="180" width="109" height="33" rotation="0" locateType="2">蓝牌:蒙1A561W</taggedRectangle>
<taggedRectangle x="512" y="180" width="126" height="33" rotation="0" locateType="2">蓝牌:川A561WP</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨A572F4</imageName>
<taggedRectangles>
<taggedRectangle x="129" y="316" width="185" height="55" rotation="3" locateType="2">蓝牌:川A572FA</taggedRectangle>
<taggedRectangle x="123" y="316" width="200" height="55" rotation="3" locateType="2">蓝牌:川A572F4</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -55,7 +57,7 @@
<image>
<imageName>´¨AGU801</imageName>
<taggedRectangles>
<taggedRectangle x="422" y="235" width="70" height="25" rotation="2" locateType="2">蓝牌:DHU801</taggedRectangle>
<taggedRectangle x="422" y="235" width="70" height="25" rotation="2" locateType="2">蓝牌:DHU801</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -67,7 +69,7 @@
<image>
<imageName>´¨AKQ291</imageName>
<taggedRectangles>
<taggedRectangle x="401" y="156" width="98" height="27" rotation="0" locateType="2">蓝牌:川AKQ291</taggedRectangle>
<taggedRectangle x="400" y="156" width="100" height="27" rotation="0" locateType="2">蓝牌:川AKQ291</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -77,13 +79,13 @@
<image>
<imageName>´¨AN4E10</imageName>
<taggedRectangles>
<taggedRectangle x="452" y="186" width="140" height="35" rotation="1" locateType="2">蓝牌:辽AM4E1M</taggedRectangle>
<taggedRectangle x="452" y="186" width="139" height="35" rotation="1" locateType="2">蓝牌:青AN4E1M</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨AR9X49</imageName>
<taggedRectangles>
<taggedRectangle x="154" y="359" width="188" height="51" rotation="3" locateType="2">蓝牌:浙AR9X49</taggedRectangle>
<taggedRectangle x="154" y="359" width="188" height="51" rotation="3" locateType="2">蓝牌:川AR9D49</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -93,19 +95,19 @@
<image>
<imageName>´¨AUU093</imageName>
<taggedRectangles>
<taggedRectangle x="406" y="200" width="121" height="32" rotation="1" locateType="2">蓝牌:AUU093</taggedRectangle>
<taggedRectangle x="406" y="200" width="121" height="32" rotation="1" locateType="2">蓝牌:AUU093</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨AY116F</imageName>
<taggedRectangles>
<taggedRectangle x="427" y="189" width="117" height="32" rotation="1" locateType="2">蓝牌:AY116F</taggedRectangle>
<taggedRectangle x="427" y="189" width="117" height="32" rotation="1" locateType="2">蓝牌:AY116F</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨AZ408T</imageName>
<taggedRectangles>
<taggedRectangle x="300" y="319" width="133" height="40" rotation="-1" locateType="2">蓝牌:A7408</taggedRectangle>
<taggedRectangle x="298" y="319" width="138" height="40" rotation="-1" locateType="2">蓝牌:陕MA7408</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -119,31 +121,31 @@
<image>
<imageName>»¦ALB022</imageName>
<taggedRectangles>
<taggedRectangle x="392" y="390" width="126" height="31" rotation="-3" locateType="2">蓝牌:琼7ZTRDD</taggedRectangle>
<taggedRectangle x="392" y="390" width="126" height="31" rotation="-3" locateType="2">蓝牌:沪ALB022</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>»¦B683J8</imageName>
<taggedRectangles>
<taggedRectangle x="376" y="227" width="103" height="37" rotation="5" locateType="2">蓝牌:683J8</taggedRectangle>
<taggedRectangle x="365" y="226" width="129" height="37" rotation="5" locateType="2">蓝牌:鄂R683J8</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>»¦D71603</imageName>
<taggedRectangles>
<taggedRectangle x="435" y="418" width="585" height="139" rotation="3" locateType="2">蓝牌:沪D71603</taggedRectangle>
<taggedRectangle x="425" y="417" width="608" height="139" rotation="3" locateType="2">蓝牌:沪D71603</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>ÕãA26M71</imageName>
<taggedRectangles>
<taggedRectangle x="1018" y="689" width="123" height="32" rotation="0" locateType="2">蓝牌:A26M71</taggedRectangle>
<taggedRectangle x="1018" y="689" width="123" height="32" rotation="0" locateType="2">蓝牌:A26M71</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>ÕãC01701</imageName>
<taggedRectangles>
<taggedRectangle x="418" y="639" width="104" height="27" rotation="0" locateType="2">蓝牌:C01701</taggedRectangle>
<taggedRectangle x="416" y="639" width="107" height="27" rotation="0" locateType="2">蓝牌:C01701</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -161,7 +163,7 @@
<image>
<imageName>ÕãL66736</imageName>
<taggedRectangles>
<taggedRectangle x="345" y="769" width="150" height="35" rotation="0" locateType="2">黄牌:L66736</taggedRectangle>
<taggedRectangle x="346" y="769" width="149" height="35" rotation="0" locateType="2">黄牌:L66736</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -175,15 +177,15 @@
<image>
<imageName>ÔÁA2HQ34</imageName>
<taggedRectangles>
<taggedRectangle x="1443" y="804" width="241" height="58" rotation="-1" locateType="2">蓝牌:A2HQ34</taggedRectangle>
<taggedRectangle x="1699" y="894" width="243" height="49" rotation="0" locateType="2">蓝牌:38CZC</taggedRectangle>
<taggedRectangle x="1443" y="804" width="241" height="58" rotation="-1" locateType="2">蓝牌:A2HQ34</taggedRectangle>
<taggedRectangle x="1699" y="894" width="243" height="49" rotation="0" locateType="2">蓝牌:38CZC</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>ÔÁA5DP12</imageName>
<taggedRectangles>
<taggedRectangle x="1692" y="894" width="226" height="51" rotation="0" locateType="2">蓝牌:川80002</taggedRectangle>
<taggedRectangle x="1121" y="748" width="181" height="46" rotation="-4" locateType="2">蓝牌:琼A5UP12</taggedRectangle>
<taggedRectangle x="1121" y="748" width="181" height="46" rotation="-4" locateType="2">蓝牌:粤A5DP11</taggedRectangle>
<taggedRectangle x="1692" y="894" width="226" height="51" rotation="0" locateType="2">蓝牌:赣80002</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -195,20 +197,18 @@
<image>
<imageName>ÔÁA961F3</imageName>
<taggedRectangles>
<taggedRectangle x="1177" y="683" width="131" height="32" rotation="1" locateType="2">蓝牌:A961F3</taggedRectangle>
<taggedRectangle x="1177" y="683" width="131" height="32" rotation="1" locateType="2">蓝牌:A961F3</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>ÔÁAB2893</imageName>
<taggedRectangles>
<taggedRectangle x="1692" y="895" width="226" height="49" rotation="0" locateType="2">蓝牌:82304</taggedRectangle>
<taggedRectangle x="1692" y="895" width="226" height="49" rotation="0" locateType="2">蓝牌:82304</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>ÔÁBA103N</imageName>
<taggedRectangles>
<taggedRectangle x="321" y="178" width="87" height="32" rotation="7" locateType="2">蓝牌:贵5A1C3N</taggedRectangle>
</taggedRectangles>
<taggedRectangles/>
</image>
<image>
<imageName>ÔÁBDB720</imageName>
@ -223,15 +223,14 @@
<image>
<imageName>ÔÁSK903B</imageName>
<taggedRectangles>
<taggedRectangle x="1700" y="894" width="245" height="49" rotation="0" locateType="2">蓝牌:75G2Z</taggedRectangle>
<taggedRectangle x="1700" y="894" width="245" height="49" rotation="0" locateType="2">蓝牌:75G2Z</taggedRectangle>
<taggedRectangle x="1355" y="769" width="241" height="58" rotation="0" locateType="2">À¶ÅÆ:ÔÁSK903B</taggedRectangle>
</taggedRectangles>
</image>
<image>
<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">黄牌:新X30479</taggedRectangle>
<taggedRectangle x="1692" y="895" width="226" height="49" rotation="0" locateType="2">蓝牌:新QF5224</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -245,19 +244,19 @@
<image>
<imageName>ËÕA66U71</imageName>
<taggedRectangles>
<taggedRectangle x="500" y="483" width="281" height="47" rotation="5" locateType="2">蓝牌:A66U61</taggedRectangle>
<taggedRectangle x="500" y="483" width="282" height="47" rotation="5" locateType="2">蓝牌:A66U61</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>ËÕAD6A99</imageName>
<taggedRectangles>
<taggedRectangle x="487" y="395" width="255" height="51" rotation="-2" locateType="2">蓝牌:AD6A99</taggedRectangle>
<taggedRectangle x="487" y="395" width="255" height="51" rotation="-2" locateType="2">蓝牌:AD6A99</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>ËÕAP0966</imageName>
<taggedRectangles>
<taggedRectangle x="520" y="364" width="286" height="63" rotation="1" locateType="2">蓝牌:AP0966</taggedRectangle>
<taggedRectangle x="524" y="364" width="278" height="63" rotation="1" locateType="2">蓝牌:AP0966</taggedRectangle>
</taggedRectangles>
</image>
<image>
@ -268,16 +267,13 @@
</image>
<image>
<imageName>ËÕAVW997</imageName>
<taggedRectangles>
<taggedRectangle x="363" y="414" width="89" height="32" rotation="-15" locateType="2">蓝牌:鄂UW99Z7</taggedRectangle>
</taggedRectangles>
<taggedRectangles/>
</image>
<image>
<imageName>Ô¥U00000</imageName>
<taggedRectangles>
<taggedRectangle x="888" y="650" width="112" height="28" rotation="0" locateType="2">蓝牌:蒙1DQPQU</taggedRectangle>
<taggedRectangle x="1281" y="83" width="213" height="51" rotation="15" locateType="2">黄牌:陕Q1Q1QY</taggedRectangle>
<taggedRectangle x="211" y="28" width="125" height="28" rotation="0" locateType="2">蓝牌:京0T507</taggedRectangle>
<taggedRectangle x="888" y="650" width="112" height="28" rotation="0" locateType="2">蓝牌:豫1DQPQU</taggedRectangle>
<taggedRectangle x="211" y="28" width="125" height="28" rotation="0" locateType="2">蓝牌:辽0T507</taggedRectangle>
</taggedRectangles>
</image>
<image>

@ -17,6 +17,7 @@ namespace easypr {
CharsIdentify::CharsIdentify() {
ann_ = ml::ANN_MLP::load<ml::ANN_MLP>(kDefaultAnnPath);
annChinese_ = ml::ANN_MLP::load<ml::ANN_MLP>(kChineseAnnPath);
kv_ = std::shared_ptr<Kv>(new Kv);
kv_->load("etc/province_mapping");
}
@ -125,6 +126,61 @@ namespace easypr {
}
}
void CharsIdentify::classifyChinese(std::vector<CCharacter>& charVec){
size_t charVecSize = charVec.size();
if (charVecSize == 0)
return;
Mat featureRows;
for (size_t index = 0; index < charVecSize; index++) {
Mat charInput = charVec[index].getCharacterMat();
Mat feature = charFeatures(charInput, kChineseSize);
featureRows.push_back(feature);
}
cv::Mat output(charVecSize, kChineseNumber, CV_32FC1);
annChinese_->predict(featureRows, output);
for (size_t output_index = 0; output_index < charVecSize; output_index++) {
CCharacter& character = charVec[output_index];
Mat output_row = output.row(output_index);
bool isChinese = true;
float maxVal = -2;
int result = -1;
for (int j = 0; j < kChineseNumber; j++) {
float val = output_row.at<float>(j);
//std::cout << "j:" << j << "val:" << val << std::endl;
if (val > maxVal) {
maxVal = val;
result = j;
}
}
// no match
if (-1 == result) {
result = 0;
maxVal = 0;
isChinese = false;
}
auto index = result + kCharsTotalNumber - kChineseNumber;
const char* key = kChars[index];
std::string s = key;
std::string province = kv_->get(s);
/*std::cout << "result:" << result << std::endl;
std::cout << "maxVal:" << maxVal << std::endl;*/
character.setCharacterScore(maxVal);
character.setCharacterStr(province);
character.setIsChinese(isChinese);
}
}
int CharsIdentify::classify(cv::Mat f, float& maxVal, bool isChinses){
int result = -1;
@ -205,29 +261,41 @@ namespace easypr {
return false;
}*/
std::pair<std::string, std::string> CharsIdentify::identifyChinese(cv::Mat input) {
cv::Mat feature = charFeatures(input, kPredictSize);
std::pair<std::string, std::string> CharsIdentify::identifyChinese(cv::Mat input, float& out, bool& isChinese) {
cv::Mat feature = charFeatures(input, kChineseSize);
float maxVal = -2;
int result = -1;
cv::Mat output(1, kChineseNumber, CV_32FC1);
ann_->predict(feature, output);
annChinese_->predict(feature, output);
for (int j = 0; j < kChineseNumber; j++) {
float val = output.at<float>(j);
// std::cout << "j:" << j << "val:" << val << std::endl;
//std::cout << "j:" << j << "val:" << val << std::endl;
if (val > maxVal) {
maxVal = val;
result = j;
}
}
// no match
if (-1 == result) {
result = 0;
maxVal = 0;
isChinese = false;
}
else if (maxVal > 0.9){
isChinese = true;
}
auto index = result + kCharsTotalNumber - kChineseNumber;
const char* key = kChars[index];
std::string s = key;
std::string province = kv_->get(s);
out = maxVal;
return std::make_pair(s, province);
}

@ -25,10 +25,18 @@ int CCharsRecognise::charsRecognise(Mat plate, std::string& plateLicense) {
{
Mat charMat = matChars.at(j);
bool isChinses = false;
if (j == 0)
float maxVal = 0;
if (j == 0) {
bool judge = true;
isChinses = true;
auto character = CharsIdentify::instance()->identify(charMat, isChinses);
plateLicense.append(character.second);
auto character = CharsIdentify::instance()->identifyChinese(charMat, maxVal, judge);
plateLicense.append(character.second);
}
else {
isChinses = false;
auto character = CharsIdentify::instance()->identify(charMat, isChinses);
plateLicense.append(character.second);
}
}
}
@ -67,11 +75,24 @@ int CCharsRecognise::charsRecognise(CPlate& plate, std::string& plateLicense) {
for (int j = 0; j < num; j++)
{
Mat charMat = matChars.at(j);
bool isChinses = false;
if (j == 0)
bool isChinses = false;
//if (j == 0)
// isChinses = true;
//auto character = CharsIdentify::instance()->identify(charMat, isChinses);
//plateLicense.append(character.second);
std::pair<std::string, std::string> character;
float maxVal;
if (j == 0) {
isChinses = true;
auto character = CharsIdentify::instance()->identify(charMat, isChinses);
plateLicense.append(character.second);
bool judge = true;
character = CharsIdentify::instance()->identifyChinese(charMat, maxVal, judge);
plateLicense.append(character.second);
}
else {
isChinses = false;
character = CharsIdentify::instance()->identify(charMat, isChinses);
plateLicense.append(character.second);
}
CCharacter charResult;
charResult.setCharacterMat(charMat);

@ -1,4 +1,5 @@
#include "easypr/core/chars_segment.h"
#include "easypr/core/chars_identify.h"
#include "easypr/config.h"
using namespace std;
@ -75,8 +76,66 @@ Mat CCharsSegment::preprocessChar(Mat in) {
return out;
}
//! 字符分割与排序
//! choose the bese threshold method for chinese
void CCharsSegment::judgeChinese(Mat in, Mat& out, Color plateType) {
Mat auxRoi = in;
float valOstu = -1.f, valAdap = -1.f;
Mat roiOstu, roiAdap;
bool isChinese = true;
if (1) {
if (BLUE == plateType) {
threshold(auxRoi, roiOstu, 0, 255, CV_THRESH_BINARY + CV_THRESH_OTSU);
}
else if (YELLOW == plateType) {
threshold(auxRoi, roiOstu, 0, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU);
}
else if (WHITE == plateType) {
threshold(auxRoi, roiOstu, 0, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU);
}
else {
threshold(auxRoi, roiOstu, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
}
roiOstu = preprocessChar(roiOstu);
if (0) {
imshow("roiOstu", roiOstu);
waitKey(0);
destroyWindow("roiOstu");
}
auto character = CharsIdentify::instance()->identifyChinese(roiOstu, valOstu, isChinese);
}
if (1) {
if (BLUE == plateType) {
adaptiveThreshold(auxRoi, roiAdap, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, 0);
}
else if (YELLOW == plateType) {
adaptiveThreshold(auxRoi, roiAdap, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV, 3, 0);
}
else if (WHITE == plateType) {
adaptiveThreshold(auxRoi, roiAdap, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV, 3, 0);
}
else {
adaptiveThreshold(auxRoi, roiAdap, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, 0);
}
roiAdap = preprocessChar(roiAdap);
auto character = CharsIdentify::instance()->identifyChinese(roiAdap, valAdap, isChinese);
}
std::cout << "valOstu: " << valOstu << std::endl;
std::cout << "valAdap: " << valAdap << std::endl;
if (valOstu >= valAdap) {
out = roiOstu;
}
else {
out = roiAdap;
}
}
//! 字符分割与排序
int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color) {
if (!input.data) return 0x01;
@ -227,26 +286,35 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec, Color color)
Mat auxRoi(input_grey, mr);
Mat newRoi;
if (BLUE == plateType) {
//newRoi = auxRoi.clone();
//spatial_ostu(newRoi, 5, 5, plateType);
if (i != 0)
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_BINARY + CV_THRESH_OTSU);
else
adaptiveThreshold(auxRoi, newRoi, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, 0);
} else if (YELLOW == plateType) {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU);
} else if (WHITE == plateType) {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV);
} else {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
if (i == 0) {
judgeChinese(auxRoi, newRoi, plateType);
}
else {
if (BLUE == plateType) {
//newRoi = auxRoi.clone();
//spatial_ostu(newRoi, 5, 5, plateType);
if (i != 0) {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_BINARY + CV_THRESH_OTSU);
}
else {
adaptiveThreshold(auxRoi, newRoi, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, 0);
}
}
else if (YELLOW == plateType) {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU);
// 归一化大小
newRoi = preprocessChar(newRoi);
}
else if (WHITE == plateType) {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV);
}
else {
threshold(auxRoi, newRoi, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
}
// 归一化大小
newRoi = preprocessChar(newRoi);
}
if (0) {
if (i == 0) {
imshow("chinese", newRoi);

@ -1254,7 +1254,13 @@ void slideWindowSearch(const Mat &image, std::vector<CCharacter>& slideCharacter
charCandidateVec.push_back(charCandidate);
}
CharsIdentify::instance()->classify(charCandidateVec);
if (isChinese) {
CharsIdentify::instance()->classifyChinese(charCandidateVec);
}
else {
CharsIdentify::instance()->classify(charCandidateVec);
}
double overlapThresh = 0.1;
NMStoCharacter(charCandidateVec, overlapThresh);
@ -1884,7 +1890,7 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& out_plateVec,
//plate.setOstuLevel(ostu_level);
Mat charInput = preprocessChar(binary_region, 20);
if (0 && showDebug) {
if (0 /*&& showDebug*/) {
imshow("charInput", charInput);
waitKey(0);
destroyWindow("charInput");
@ -1893,7 +1899,9 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& out_plateVec,
std::string label = "";
float maxVal = -2.f;
leftIsChinese = CharsIdentify::instance()->isCharacter(charInput, label, maxVal, true);
if (1 && showDebug) {
//auto character = CharsIdentify::instance()->identifyChinese(charInput, maxVal, leftIsChinese);
//label = character.second;
if (0 /* && showDebug*/) {
std::cout << "isChinese:" << leftIsChinese << std::endl;
std::cout << "chinese:" << label;
std::cout << "__score:" << maxVal << std::endl;

@ -106,9 +106,6 @@ void getLBPFeatures(const Mat& image, Mat& features) {
features = lbp_hist;
}
Mat charFeatures(Mat in, int sizeData) {
const int VERTICAL = 0;
const int HORIZONTAL = 1;

@ -178,9 +178,9 @@ namespace easypr {
result_resize.cols, result_resize.rows));
addWeighted(imageRoi, 0, result_resize, 1, 0, imageRoi);
if (0) {
if (1) {
imshow("EasyPR", img_window);
waitKey(1000);
waitKey(500);
destroyWindow("EasyPR");
}

@ -160,10 +160,10 @@ int CPlateLocate::mserSearch(const Mat &src, const Color color, Mat &out,
}
}
for (auto plate : plateVec){
RotatedRect rrect = plate.getPlatePos();
rotatedRectangle(match_grey, rrect, Scalar(255));
}
//for (auto plate : plateVec){
// RotatedRect rrect = plate.getPlatePos();
// rotatedRectangle(match_grey, rrect, Scalar(255));
//}
if (0) {
imshow("match", match_grey);
@ -683,7 +683,7 @@ int CPlateLocate::sobelOper(const Mat &in, Mat &out, int blurSize, int morphW,
return 0;
}
void DeleteNotArea(Mat &inmat) {
void deleteNotArea(Mat &inmat, Color color = UNKNOWN) {
Mat input_grey;
cvtColor(inmat, input_grey, CV_BGR2GRAY);
@ -693,9 +693,16 @@ void DeleteNotArea(Mat &inmat) {
Mat tmpMat = inmat(Rect_<double>(w * 0.15, h * 0.1, w * 0.7, h * 0.7));
//判断车牌颜色以此确认threshold方法
Color plateType;
if (UNKNOWN == color) {
plateType = getPlateType(tmpMat, true);
}
else {
plateType = color;
}
Color plateType = getPlateType(tmpMat, true);
Mat img_threshold;
// Remain
if (BLUE == plateType) {
img_threshold = input_grey.clone();
Mat tmp = input_grey(Rect_<double>(w * 0.15, h * 0.15, w * 0.7, h * 0.7));
@ -723,14 +730,29 @@ void DeleteNotArea(Mat &inmat) {
threshold(input_grey, img_threshold, 10, 255,
CV_THRESH_OTSU + CV_THRESH_BINARY);
//img_threshold = input_grey.clone();
//spatial_ostu(img_threshold, 8, 2, plateType);
int posLeft = 0;
int posRight = 0;
int top = 0;
int bottom = img_threshold.rows - 1;
clearLiuDing(img_threshold, top, bottom);
if (0) {
imshow("inmat", inmat);
waitKey(0);
destroyWindow("inmat");
}
if (bFindLeftRightBound1(img_threshold, posLeft, posRight)) {
inmat = inmat(Rect(posLeft, top, w - posLeft, bottom - top));
if (0) {
imshow("inmat", inmat);
waitKey(0);
destroyWindow("inmat");
}
}
}
@ -738,7 +760,7 @@ void DeleteNotArea(Mat &inmat) {
int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
vector<RotatedRect> &inRects,
vector<CPlate> &outPlates, bool useDeteleArea) {
vector<CPlate> &outPlates, bool useDeteleArea, Color color) {
Mat mat_debug;
src.copyTo(mat_debug);
@ -775,10 +797,18 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
Mat bound_mat = src(safeBoundRect);
Mat bound_mat_b = src_b(safeBoundRect);
if (0) {
imshow("bound_mat_b", bound_mat_b);
waitKey(0);
destroyWindow("bound_mat_b");
}
//std::cout << "roi_angle:" << roi_angle << std::endl;
Point2f roi_ref_center = roi_rect.center - safeBoundRect.tl();
Mat deskew_mat;
if ((roi_angle - 3 < 0 && roi_angle + 3 > 0) || 90.0 == roi_angle ||
if ((roi_angle - 5 < 0 && roi_angle + 5 > 0) || 90.0 == roi_angle ||
-90.0 == roi_angle) {
deskew_mat = bound_mat;
} else {
@ -807,12 +837,13 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
deskew_mat = rotated_mat;
}
Mat plate_mat;
plate_mat.create(HEIGHT, WIDTH, TYPE);
// haitungaga添加删除非区域这个函数影响了25%的完整定位率
if (useDeteleArea)
DeleteNotArea(deskew_mat);
deleteNotArea(deskew_mat, color);
// 这里对deskew_mat进行了一个筛选
// 使用了经验数值2.3和6
@ -830,13 +861,7 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
CPlate plate;
plate.setPlatePos(roi_rect);
plate.setPlateMat(plate_mat);
if (0) {
imshow("plate_mat", plate_mat);
waitKey(0);
destroyWindow("plate_mat");
}
outPlates.push_back(plate);
}
}
@ -849,6 +874,12 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
bool CPlateLocate::rotation(Mat &in, Mat &out, const Size rect_size,
const Point2f center, const double angle) {
if (0) {
imshow("in", in);
waitKey(0);
destroyWindow("in");
}
Mat in_large;
in_large.create(int(in.rows * 1.5), int(in.cols * 1.5), in.type());
@ -887,6 +918,12 @@ bool CPlateLocate::rotation(Mat &in, Mat &out, const Size rect_size,
out = img_crop;
if (0) {
imshow("out", out);
waitKey(0);
destroyWindow("out");
}
/*imshow("img_crop", img_crop);
waitKey(0);*/
@ -899,6 +936,12 @@ bool CPlateLocate::rotation(Mat &in, Mat &out, const Size rect_size,
bool CPlateLocate::isdeflection(const Mat &in, const double angle,
double &slope) { /*imshow("in",in);
waitKey(0);*/
if (0) {
imshow("in", in);
waitKey(0);
destroyWindow("in");
}
int nRows = in.rows;
int nCols = in.cols;
@ -1111,7 +1154,7 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
Mat resize_src_b;
resize(src_b, resize_src_b, Size(channelImage.cols, channelImage.rows));
deskew(src, resize_src_b, rects_mser, deskewPlate, false);
deskew(src, resize_src_b, rects_mser, deskewPlate, false, color);
for (auto dplate : deskewPlate) {
RotatedRect drect = dplate.getPlatePos();
@ -1128,7 +1171,7 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_i
Rect urect = safe_dRect | safe_sRect;
float iou = (float)inter.area() / (float)urect.area();
std::cout << "iou" << iou << std::endl;
//std::cout << "iou" << iou << std::endl;
if (iou > 0.95) {
splate.setPlateMat(dmat);

Loading…
Cancel
Save