Skip to content

Commit

Permalink
* change readme.
Browse files Browse the repository at this point in the history
* add more data to svm.
* change the svm train process, fix train data size, add new test data.
* close the svm train menu.
  • Loading branch information
liuruoze committed Jul 6, 2016
1 parent a1045d1 commit aa05f7d
Show file tree
Hide file tree
Showing 37 changed files with 107 additions and 62,524 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ EasyPR是一个开源的中文车牌识别系统,其目标是成为一个简

关于本次改动的具体内容可以看博客中的[介绍](http://www.cnblogs.com/subconscious/p/5637735.html)

注意,目前1.4和1.5版的SVM训练好的文件在使用时会有问题,这个原因可能跟opencv3的实现改变有关。建议要训练SVM的话使用基于opencv2的1.3版。

### 跨平台

目前除了windows平台以外,还有以下其他平台的EasyPR版本。一些平台的版本可能会暂时落后于主平台。
Expand Down Expand Up @@ -160,6 +162,18 @@ CPlate类包含了车牌的各种信息,其中重要的如下:

plateMat代表车牌图像,rrect代表车牌的可旋转矩形位置,license代表车牌字符串,例如“蓝牌:苏EUK722”。

这里说下如何去阅读如下图的识别结果。

![EasyPR DetectResults](resources/doc/res/one_image_detect.jpg)

第1行代表的是图片的文件名。

第2行代表GroundTruth车牌,用后缀(g)表示。第3行代表EasyPR检测车牌,用后缀(d)表示。两者形成一个配对,第4行代表两者的字符差距。

下面同上。本图片中有3个车牌,所有共有三个配对。最后的Recall等指标代表的是整幅图片的定位评价,考虑了三个配对的结果。

有时检测车牌的部分会用“无车牌”与“No string”替代。“无车牌”代表“定位不成功”,“No string”代表“定位成功但字符分割失败”。

### 版权

EasyPR的源代码与训练数据遵循Apache v2.0协议开源。
Expand Down
2 changes: 1 addition & 1 deletion etc/main_menu
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
EasyPR Option:
1. 测试;
2. 批量测试;
3. SVM训练;
3. SVM训练(暂时关闭,请用1.3版的);
4. ANN训练;
5. GDTS生成;
6. 开发团队;
Expand Down
Binary file removed resources/image/extreme_test/Germen/MIE6907.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/Germen/MIN2931.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/Germen/MIN3479.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/Germen/MIN6791.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/Germen/MIN8233.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/Germen/MIZ5977.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/Germen/TAZ5910.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/Germen/TAZ5920.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/Germen/ZYM2325.JPG
Binary file not shown.
Binary file removed resources/image/extreme_test/大角度/川A18K80.jpg
Binary file not shown.
Binary file not shown.
Binary file removed resources/image/extreme_test/大角度/川AA0787.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/大角度/川W13930.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川A1D590.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川A2S801.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川A35D98.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川A39J64.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川A57237.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川AF058Y.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川ALT336.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川AN6S39.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川APL835.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川AUE022.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川AUJ860.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川AUV250.jpg
Binary file not shown.
Binary file removed resources/image/extreme_test/污损/川M62845.jpg
Diff not rendered.
23,029 changes: 0 additions & 23,029 deletions resources/model/svm_hisotm.xml

This file was deleted.

39,452 changes: 0 additions & 39,452 deletions resources/model/svm_lbp_final.xml

This file was deleted.

Binary file modified resources/train/ann.7z
Binary file not shown.
Binary file modified resources/train/svm.7z
Binary file not shown.
45 changes: 45 additions & 0 deletions result/accuracy.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2008,3 +2008,48 @@ Recall:84.2263%, Precise:70.6573%, Fscore:76.8474%.
Recall:84.2263%, Precise:70.6573%, Fscore:76.8474%.
0-error:60.4%, 1-error:71.6%, Chinese-precise:73.2%
��ʱ��:114��, ƽ��ִ��ʱ��:0.445313��
2016-07-05 21:37:51
��ͼƬ��:256, Plates count:297, δ��λ����:40, ��λ��:86.532%
Recall:78.8339%, Precise:53.3124%, Fscore:63.6086%.
0-error:55.3571%, 1-error:64.2857%, Chinese-precise:67.8571%
��ʱ��:114��, ƽ��ִ��ʱ��:0.445313��
2016-07-06 07:38:55
��ͼƬ��:256, Plates count:297, δ��λ����:29, ��λ��:90.2357%
Recall:84.2263%, Precise:70.6573%, Fscore:76.8474%.
0-error:60.4%, 1-error:71.6%, Chinese-precise:73.2%
��ʱ��:114��, ƽ��ִ��ʱ��:0.445313��
2016-07-06 07:46:53
��ͼƬ��:256, Plates count:297, δ��λ����:29, ��λ��:90.2357%
Recall:84.2263%, Precise:70.6573%, Fscore:76.8474%.
0-error:60.4%, 1-error:71.6%, Chinese-precise:73.2%
��ʱ��:122��, ƽ��ִ��ʱ��:0.476563��
2016-07-06 07:55:13
��ͼƬ��:3, Plates count:0, δ��λ����:0, ��λ��:-1.#IND%
Recall:0%, Precise:0%, Fscore:0%.
0-error:0%, 1-error:0%, Chinese-precise:100%
��ʱ��:3��, ƽ��ִ��ʱ��:1��
2016-07-06 07:55:42
��ͼƬ��:3, Plates count:0, δ��λ����:0, ��λ��:-1.#IND%
Recall:0%, Precise:0%, Fscore:0%.
0-error:0%, 1-error:0%, Chinese-precise:100%
��ʱ��:6��, ƽ��ִ��ʱ��:2��
2016-07-06 07:57:02
��ͼƬ��:2, Plates count:0, δ��λ����:0, ��λ��:-1.#IND%
Recall:0%, Precise:0%, Fscore:0%.
0-error:0%, 1-error:0%, Chinese-precise:100%
��ʱ��:1��, ƽ��ִ��ʱ��:0.5��
2016-07-06 07:57:45
��ͼƬ��:4, Plates count:0, δ��λ����:0, ��λ��:-1.#IND%
Recall:0%, Precise:0%, Fscore:0%.
0-error:0%, 1-error:0%, Chinese-precise:100%
��ʱ��:1��, ƽ��ִ��ʱ��:0.25��
2016-07-06 08:00:06
��ͼƬ��:256, Plates count:297, δ��λ����:29, ��λ��:90.2357%
Recall:84.2263%, Precise:70.6573%, Fscore:76.8474%.
0-error:60.4%, 1-error:71.6%, Chinese-precise:73.2%
��ʱ��:118��, ƽ��ִ��ʱ��:0.460938��
2016-07-06 08:27:36
��ͼƬ��:256, Plates count:297, δ��λ����:29, ��λ��:90.2357%
Recall:84.2263%, Precise:70.6573%, Fscore:76.8474%.
0-error:60.4%, 1-error:71.6%, Chinese-precise:73.2%
��ʱ��:123��, ƽ��ִ��ʱ��:0.480469��
7 changes: 7 additions & 0 deletions src/core/plate_judge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ namespace easypr {
extractFeature(inMat, features);

float response = svm_->predict(features);
/*std::cout << "response:" << response << std::endl;
float score = svm_->predict(features, noArray(), cv::ml::StatModel::Flags::RAW_OUTPUT);
std::cout << "score:" << score << std::endl;*/

result = (int)response;

return 0;
Expand Down Expand Up @@ -64,6 +69,8 @@ namespace easypr {

float score = svm_->predict(features, noArray(), cv::ml::StatModel::Flags::RAW_OUTPUT);

//std::cout << "score:" << score << std::endl;

// score is the distance of margin,below zero is plate, up is not
// when score is below zero, the samll the value, the more possibliy to be a plate.
plate.setPlateScore(score);
Expand Down
7 changes: 1 addition & 6 deletions src/core/plate_locate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,12 +743,6 @@ int CPlateLocate::plateColorLocate(Mat src, vector<CPlate> &candPlates,
candPlates.insert(candPlates.end(), plates_blue.begin(), plates_blue.end());
candPlates.insert(candPlates.end(), plates_yellow.begin(), plates_yellow.end());

//for (auto plate : plates_blue)
// candPlates.push_back(plate);

//for (auto plate : plates_yellow)
// candPlates.push_back(plate);

return 0;
}

Expand Down Expand Up @@ -1044,6 +1038,7 @@ int CPlateLocate::plateLocate(Mat src, vector<Mat> &resultVec, int index) {

plateColorLocate(src, all_result_Plates, index);
plateSobelLocate(src, all_result_Plates, index);
plateMserLocate(src, all_result_Plates, index);

for (size_t i = 0; i < all_result_Plates.size(); i++) {
CPlate plate = all_result_Plates[i];
Expand Down
63 changes: 27 additions & 36 deletions src/train/svm_train.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void SvmTrain::train() {
svm_->setC(1);
svm_->setNu(0.1);
svm_->setP(0.1);
svm_->setTermCriteria(cvTermCriteria(CV_TERMCRIT_ITER, 100000, 0.00001));
svm_->setTermCriteria(cvTermCriteria(CV_TERMCRIT_ITER, 20000, 0.0001));

auto train_data = tdata();

Expand All @@ -43,6 +43,7 @@ void SvmTrain::train() {
fprintf(stdout, ">> Training done. Time elapse: %ldms\n", end - start);
fprintf(stdout, ">> Saving model file...\n");
svm_->save(svm_xml_);

fprintf(stdout, ">> Your SVM Model was saved to %s\n", svm_xml_);
fprintf(stdout, ">> Testing...\n");
this->test();
Expand Down Expand Up @@ -72,11 +73,11 @@ void SvmTrain::test() {
continue;
}
cv::Mat feature;
getHistogramFeatures(image, feature);

//std::cout << "predict: " << result << std::endl;
getLBPFeatures(image, feature);

auto predict = int(svm_->predict(feature));
std::cout << "predict: " << predict << std::endl;

auto real = item.label;
if (predict == kForward && real == kForward) ptrue_rtrue++;
if (predict == kForward && real == kInverse) ptrue_rfalse++;
Expand Down Expand Up @@ -123,47 +124,37 @@ void SvmTrain::prepare() {

char buffer[260] = {0};

sprintf(buffer, "%s/has", plates_folder_);
auto has_file_list = utils::getFiles(buffer);
std::random_shuffle(has_file_list.begin(), has_file_list.end());
sprintf(buffer, "%s/has/train", plates_folder_);
auto has_file_train_list = utils::getFiles(buffer);
std::random_shuffle(has_file_train_list.begin(), has_file_train_list.end());

sprintf(buffer, "%s/no", plates_folder_);
auto no_file_list = utils::getFiles(buffer);
std::random_shuffle(no_file_list.begin(), no_file_list.end());
sprintf(buffer, "%s/has/test", plates_folder_);
auto has_file_test_list = utils::getFiles(buffer);
std::random_shuffle(has_file_test_list.begin(), has_file_test_list.end());

auto has_num = has_file_list.size();
auto no_num = no_file_list.size();
sprintf(buffer, "%s/no/train", plates_folder_);
auto no_file_train_list = utils::getFiles(buffer);
std::random_shuffle(no_file_train_list.begin(), no_file_train_list.end());

sprintf(buffer, "%s/no/test", plates_folder_);
auto no_file_test_list = utils::getFiles(buffer);
std::random_shuffle(no_file_test_list.begin(), no_file_test_list.end());

fprintf(stdout, ">> Collecting train data...\n");

auto has_for_train = static_cast<int>(has_num * kSvmPercentage);
auto no_for_train = static_cast<int>(no_num * kSvmPercentage);
for (auto file : has_file_train_list)
train_file_list_.push_back({ file, kForward });

// copy kSvmPercentage of has_file_list to train_file_list_
train_file_list_.reserve(has_for_train + no_for_train);
for (auto i = 0; i < has_for_train; i++) {
train_file_list_.push_back({has_file_list[i], kForward});
}
// copy kSvmPercentage of no_file_list to the end of train_file_list_
for (auto i = 0; i < no_for_train; i++) {
train_file_list_.push_back({no_file_list[i], kInverse});
}
for (auto file : no_file_train_list)
train_file_list_.push_back({ file, kInverse });

fprintf(stdout, ">> Collecting test data...\n");

auto has_for_test = has_num - has_for_train;
auto no_for_test = no_num - no_for_train;

// copy the rest of has_file_list to the test_file_list_
test_file_list_.reserve(has_for_test + no_for_test);
for (size_t i = has_for_train; i < has_num; i++) {
test_file_list_.push_back({has_file_list[i], kForward});
}
for (auto file : has_file_test_list)
test_file_list_.push_back({ file, kForward });

// copy the rest of no_file_list to the end of the test_file_list_
for (size_t i = no_for_train; i < no_num; i++) {
test_file_list_.push_back({no_file_list[i], kInverse});
}
for (auto file : no_file_test_list)
test_file_list_.push_back({ file, kInverse });
}

cv::Ptr<cv::ml::TrainData> SvmTrain::tdata() {
Expand All @@ -179,7 +170,7 @@ cv::Ptr<cv::ml::TrainData> SvmTrain::tdata() {
continue;
}
cv::Mat feature;
getHistogramFeatures(image, feature);
getLBPFeatures(image, feature);
feature = feature.reshape(1, 1);

samples.push_back(feature);
Expand Down
12 changes: 12 additions & 0 deletions test/accuracy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ namespace easypr {

// get the ground truth and compare it with the detect list;
vector<CPlate> plateVecGT;
bool hasGroundTruth = true;
#pragma omp critical
{
map<string, vector<CPlate>>::iterator it;
Expand All @@ -173,6 +174,7 @@ namespace easypr {
plateVecGT = it->second;
}
else {
hasGroundTruth = false;
img_ss << "No ground truth found!" << endl;
}
}
Expand Down Expand Up @@ -268,6 +270,16 @@ namespace easypr {
Rect_<float> plateRect_d;
calcSafeRect(platePos_d, src, plateRect_d);

if (!hasGroundTruth) {
string detectPlateLicense = plate_d.getPlateStr();
vector<string> spilt_plate = Utils::splitString(detectPlateLicense, ':');

size_t size = spilt_plate.size();
if (size == 2 && spilt_plate.at(1) != "") {
img_ss << detectPlateLicense << " (d)" << endl;
}
}

// remain
//XMLNode rectangleNode = rectangleNodes.addChild("taggedRectangle");
//RotatedRect rr = platePos_d;
Expand Down

0 comments on commit aa05f7d

Please sign in to comment.