You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
EasyPR/test/main.cpp

475 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "easypr.h"
#include "easypr/program_options.h"
#include "accuracy.hpp"
#include "chars.hpp"
#include "plate.hpp"
namespace easypr {
namespace demo {
// interactions
int accuracyTestMain() {
bool isExit = false;
while (!isExit) {
std::cout << "////////////////////////////////////" << std::endl;
const char* options[] = {"BatchTest Option:", "1. general_test;",
"2. native_test;", "3. 返回;", NULL};
Utils::print_str_lines(options);
std::cout << "////////////////////////////////////" << std::endl;
std::cout << "请选择一项操作:";
int select = -1;
bool isRepeat = true;
while (isRepeat) {
std::cin >> select;
isRepeat = false;
switch (select) {
case 1:
accuracyTest("resources/image/general_test");
break;
case 2:
accuracyTest("resources/image/native_test");
break;
case 3:
isExit = true;
break;
default:
std::cout << "输入错误,请重新输入:";
isRepeat = true;
break;
}
}
}
return 0;
}
// int svmMain() {
// bool isExit = false;
// while (!isExit) {
// std::cout << "////////////////////////////////////" << std::endl;
// const char* options[] = {
// "SvmTrain Option:",
// "1. 生成learndata(调整代码到你的环境后再用);",
// "2. 标签learndata;",
// "3. 车牌检测(not divide and train);",
// "4. 车牌检测(not train);",
// "5. 车牌检测(not divide);",
// "6. 车牌检测;",
// "7. 返回;",
// NULL
// };
// Utils::print_str_lines(options);
// std::cout << "////////////////////////////////////" << std::endl;
// std::cout << "请选择一项操作:";
//
// int select = -1;
// bool isRepeat = true;
// while (isRepeat) {
// std::cin >> select;
// isRepeat = false;
//
// //Svm svm;
//
// switch (select) {
// case 1:
// // easypr::preprocess::getLearnData();
// break;
// case 2:
// // easypr::preprocess::label_data();
// break;
// case 3:
// svm.train(false, false);
// break;
// case 4:
// svm.train(true, false);
// break;
// case 5:
// svm.train(false, true);
// break;
// case 6:
// svm.train();
// break;
// case 7:
// isExit = true;
// break;
// default:
// std::cout << "输入错误,请重新输入:";
// isRepeat = true;
// break;
// }
// }
// }
// return 0;
//}
int testMain() {
bool isExit = false;
while (!isExit) {
std::cout << "////////////////////////////////////" << std::endl;
const char* options[] = {
"EasyPR Test:", "1. test plate_locate(车牌定位);" /* 车牌定位 */,
"2. test plate_judge(车牌判断);" /* 车牌判断 */,
"3. test plate_detect(车牌检测);" /* 车牌检测(包含车牌定位与车牌判断) */,
"4. test chars_segment(字符分隔);" /* 字符分隔 */,
"5. test chars_identify(字符鉴别);" /* 字符鉴别 */,
"6. test chars_recognise(字符识别);" /* 字符识别(包含字符分隔与字符鉴别) */,
"7. test plate_recognize(车牌识别);" /* 车牌识别 */,
"8. test all(测试全部);" /* 以上全部 */, "9. 返回;" /* 退出 */, NULL};
Utils::print_str_lines(options);
std::cout << "////////////////////////////////////" << std::endl;
std::cout << "请选择一项操作:";
int select = -1;
bool isRepeat = true;
while (isRepeat) {
std::cin >> select;
isRepeat = false;
switch (select) {
case 1:
assert(test_plate_locate() == 0);
break;
case 2:
assert(test_plate_judge() == 0);
break;
case 3:
assert(test_plate_detect() == 0);
break;
case 4:
assert(test_chars_segment() == 0);
break;
case 5:
assert(test_chars_identify() == 0);
break;
case 6:
assert(test_chars_recognise() == 0);
break;
case 7:
assert(test_plate_recognize() == 0);
break;
case 8:
assert(test_plate_locate() == 0);
assert(test_plate_judge() == 0);
assert(test_plate_detect() == 0);
assert(test_chars_segment() == 0);
assert(test_chars_identify() == 0);
assert(test_chars_recognise() == 0);
assert(test_plate_recognize() == 0);
break;
case 9:
isExit = true;
break;
default:
std::cout << "输入错误,请重新输入:";
isRepeat = true;
break;
}
}
}
return 0;
}
} // namespace demo
} // namespace easypr
void command_line_handler(int argc, const char* argv[]) {
program_options::Generator options;
options.add_subroutine("svm", "svm operations").make_usage("Usage:");
options("h,help", "show help information");
options(",svm", "resources/model/svm.xml",
"the svm model file,"
" this option is used for '--tag'(required)"
" and '--train'(save svm model to) functions");
// create
options(
",create",
"create learn data, this function "
"will intercept (--max) raw images (--in) and preprocess into (--out)");
options("i,in", "", "where is the raw images");
options("o,out", "", "where to put the preprocessed images");
options("m,max", "5000", "how many learn data would you want to create");
// tag
options(",tag",
"tag learn data, this function "
"will find plate blocks in your images(--source) "
"as well as classify them into (--has) and (--no)");
options("s,source", "", "where is your images to be classified");
options(",has", "", "put plates in this folder");
options(",no", "", "put images without plate in this folder");
// train
options(",train",
"train given data, "
"including the forward(has plate) and the inverse(no plate).");
options(",has-plate", "", "where is the forward data");
options(",no-plate", "", "where is the inverse data");
options(",divide",
"whether divide train data into two parts by --percentage or not");
options(",percentage", "0.7",
"70% train data will be used for training,"
" others will be used for testing");
options(",not-train", "don't train again, run testing directly");
options.add_subroutine("locate", "locate plates in an image")
.make_usage("Usage:");
options("h,help", "show help information");
options("f,file", "", "the target picture which contains one or more plates");
options.add_subroutine(
"judge", "determine whether an image block is the license plate")
.make_usage("Usage:");
options("h,help", "show help information");
options("f,file", "the target image block");
options(",svm", "resources/model/svm.xml", "the svm model file");
options.add_subroutine("recognize", "plate recognition").make_usage("Usage:");
options("h,help", "show help information");
options("p,path", "", "where is the target picture or target folder");
options("b,batch", "do batch recognition, if set, --path means a folder");
options("c,color", "returns the plate color, blue or yellow");
options(",svm", "resources/model/svm.xml", "the svm model file");
options(",ann", "resources/model/ann.xml", "the ann model file");
auto parser = options.make_parser();
try {
parser->parse(argc, argv);
} catch (const std::exception& err) {
std::cout << err.what() << std::endl;
return;
}
auto subname = parser->get_subroutine_name();
if (subname == "svm") {
if (parser->has("help") || argc <= 2) {
std::cout << options("svm");
return;
}
if (parser->has("create")) {
assert(parser->has("in"));
assert(parser->has("out"));
assert(parser->has("max"));
auto in = parser->get("in")->val();
auto out = parser->get("out")->val();
auto max = parser->get("max")->as<int>();
easypr::preprocess::create_learn_data(in.c_str(), out.c_str(), max);
}
if (parser->has("tag")) {
assert(parser->has("source"));
assert(parser->has("has"));
assert(parser->has("no"));
assert(parser->has("svm"));
auto source = parser->get("source")->val();
auto has_path = parser->get("has")->val();
auto no_path = parser->get("no")->val();
auto svm = parser->get("svm")->val();
easypr::preprocess::tag_data(source.c_str(), has_path.c_str(),
no_path.c_str(), svm.c_str());
std::cout << "Tagging finished, check out output images "
<< "and classify the wrong images manually." << std::endl;
}
if (parser->has("train")) {
assert(parser->has("has-plate"));
assert(parser->has("no-plate"));
assert(parser->has("percentage"));
assert(parser->has("svm"));
auto forward_data_path = parser->get("has-plate")->val();
auto inverse_data_path = parser->get("no-plate")->val();
bool divide = parser->has("divide");
auto percentage = parser->get("percentage")->as<float>();
auto svm_model = parser->get("svm")->val();
bool not_train = parser->has("not-train");
easypr::Svm svm(forward_data_path.c_str(), inverse_data_path.c_str());
svm.train(divide, percentage, !not_train, svm_model.c_str());
}
return;
} else if (subname == "locate") {
if (parser->has("help") || argc <= 2) {
std::cout << options("locate");
return;
}
if (parser->has("file")) {
easypr::api::plate_locate(parser->get("file")->val().c_str());
std::cout << "finished, results can be found in tmp/" << std::endl;
}
return;
} else if (subname == "judge") {
if (parser->has("help") || argc <= 2) {
std::cout << options("judge");
std::cout << "Note that the input image's size should "
<< "be the same as the one you gived to svm train."
<< std::endl;
return;
}
if (parser->has("file")) {
assert(parser->has("file"));
assert(parser->has("svm"));
auto image = parser->get("file")->val();
auto svm = parser->get("svm")->val();
const char* true_or_false[2] = {"false", "true"};
std::cout
<< true_or_false[easypr::api::plate_judge(image.c_str(), svm.c_str())]
<< std::endl;
}
return;
} else if (subname == "recognize") {
if (parser->has("help") || argc <= 2) {
std::cout << options("recognize");
return;
}
if (parser->has("path")) {
if (parser->has("batch")) {
// batch testing
auto folder = parser->get("path")->val();
easypr::demo::accuracyTest(folder.c_str());
} else {
// single testing
auto image = parser->get("path")->val();
if (parser->has("color")) {
// return plate color
const char* colors[2] = {"blue", "yellow"};
std::cout << colors[easypr::api::get_plate_color(image.c_str())]
<< std::endl;
} else {
// return strings
auto svm = parser->get("svm")->val();
auto ann = parser->get("ann")->val();
auto results = easypr::api::plate_recognize(image.c_str(),
svm.c_str(), ann.c_str());
for (auto s : results) {
std::cout << s << std::endl;
}
}
}
} else {
std::cout << "option 'file' cannot be empty." << std::endl;
}
return;
}
// no case matched, print all commands.
std::cout << "There are several sub commands listed below, "
<< "choose one by typing:\n\n"
<< " " << easypr::Utils::getFileName(argv[0])
<< " command [options]\n\n"
<< "The commands are:\n" << std::endl;
auto subs = options.get_subroutine_list();
for (auto sub : subs) {
fprintf(stdout, "%s %s\n", sub.first.c_str(), sub.second.c_str());
}
std::cout << std::endl;
}
int main(int argc, const char* argv[]) {
if (argc > 1) {
// handle command line execution.
command_line_handler(argc, argv);
return 0;
}
bool isExit = false;
while (!isExit) {
std::cout << "////////////////////////////////////" << std::endl;
const char* options[] = {"EasyPR Option:", "1. 测试;", "2. 批量测试;",
"3. SVM训练;", "4. ANN训练(未开放);",
"5. GDTS生成;", "6. 开发团队;", "7. 感谢名单;",
"8. 退出;", NULL};
easypr::Utils::print_str_lines(options);
std::cout << "////////////////////////////////////" << std::endl;
std::cout << "请选择一项操作:";
int select = -1;
bool isRepeat = true;
while (isRepeat) {
std::cin >> select;
isRepeat = false;
switch (select) {
case 1:
easypr::demo::testMain();
break;
case 2:
easypr::demo::accuracyTestMain();
break;
case 3:
// easypr::demo::svmMain();
std::cout << "Run \"easypr_test svm\" for more usage." << std::endl;
break;
case 4:
// TODO
break;
case 5:
easypr::preprocess::generate_gdts();
break;
case 6: {
// 开发团队;
std::cout << std::endl;
const char* recruitment[] = {
"我们EasyPR团队目前有一个5人左右的小组在进行EasyPR后续版本的开发"
"工作。",
"如果你对本项目感兴趣,并且愿意为开源贡献一份力量,我们很欢迎你的"
"加入。",
"目前招聘的主要人才是:车牌定位,图像识别,深度学习,网站建设相关"
"方面的牛人。",
"如果你觉得自己符合条件,请发邮件到地址(easypr_dev@163.com)"
",期待你的加入!",
NULL};
easypr::Utils::print_str_lines(recruitment);
std::cout << std::endl;
break;
}
case 7: {
// 感谢名单
std::cout << std::endl;
const char* thanks[] = {
"本项目在建设过程中,受到了很多人的帮助,其中以下是对本项目做出突"
"出贡献的",
"(贡献包括有益建议,代码调优,数据提供等等,排名按时间顺序)",
"taotao1233邱锦山唐大侠jsxyhelu如果有一天(zhoushiwei)",
"学习奋斗袁承志圣城小石匠goldriverMicooz梦里时光",
"Rain Wangahccoms星夜落尘海豚嘎嘎",
"还有很多的同学对本项目也给予了鼓励与支持,在此也一并表示真诚的谢"
"意!",
NULL};
easypr::Utils::print_str_lines(thanks);
std::cout << std::endl;
break;
}
case 8:
isExit = true;
break;
default:
std::cout << "输入错误,请重新输入:";
isRepeat = true;
break;
}
}
}
return 0;
}