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

450 lines
14 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/util/switch.hpp"
#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 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:");
{
/* ------------------------------------------
| SVM Training operations
| ------------------------------------------
|
| $ demo svm --plates=path/to/plates/ [--test] --svm=save/to/svm.xml
|
| ------------------------------------------
*/
options("h,help", "show help information");
options(",plates", "",
"a folder contains both forward data and inverse data in the "
"separated subfolders");
options(",svm", easypr::kDefaultSvmPath, "the svm model file");
options("t,test", "run tests in --plates");
}
options.add_subroutine("ann", "ann operation").make_usage("Usages:");
{
/* ------------------------------------------
| ANN_MLP Training operations
| ------------------------------------------
|
| $ demo ann --zh-chars=zhchars/ --en-chars=enchars/ --ann=save/to/ann.xml
|
| ------------------------------------------
*/
options("h,help", "show help information");
options(",chars", "",
"the folder contains character sub-folders, with each folder"
"named by label defined in include/easypr/config.h");
options(",ann", easypr::kDefaultAnnPath,
"the ann model file you want to save");
options("t,test", "run test in --chars");
}
options.add_subroutine("locate", "locate plates in an image")
.make_usage("Usage:");
{
/* ------------------------------------------
| Plate locating operations
| ------------------------------------------
|
| $ demo locate -f file
|
| ------------------------------------------
*/
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:");
{
/* ------------------------------------------
| Plate judge operations
| ------------------------------------------
|
| $ demo judge -f file --svm resources/model/svm.xml
|
| ------------------------------------------
*/
options("h,help", "show help information");
options("f,file", "the target image block");
options(",svm", easypr::kDefaultSvmPath, "the svm model file");
}
options.add_subroutine("recognize", "plate recognition").make_usage("Usage:");
{
/* ------------------------------------------
| Plate recognize operations
| ------------------------------------------
|
| $ demo recognize -p file --svm resources/model/svm.xml
| --ann resources/model/ann.xml
| $ demo recognize -pb dir/ --svm resources/model/svm.xml
| --ann resources/model/ann.xml
|
| ------------------------------------------
*/
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", easypr::kDefaultSvmPath, "the svm model file");
options(",ann", easypr::kDefaultAnnPath, "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();
program_options::select(subname)
.found("svm",
[&]() {
if (parser->has("help") || argc <= 2) {
std::cout << options("svm");
return;
}
easypr::SvmTrain svm(parser->get("plates")->c_str(),
parser->get("svm")->c_str());
if (parser->has("test")) {
svm.test();
} else {
svm.train();
}
})
.found("ann",
[&]() {
if (parser->has("help") || argc <= 2) {
std::cout << options("ann");
return;
}
assert(parser->has("chars"));
assert(parser->has("ann"));
easypr::AnnTrain ann(parser->get("chars")->c_str(),
parser->get("ann")->c_str());
if (parser->has("test")) {
ann.test();
} else {
ann.train();
}
})
.found("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;
}
})
.found("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;
}
})
.found("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;
}
})
.others([&]() {
// 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:
std::cout << "Run \"demo svm\" for more usage." << std::endl;
{
easypr::SvmTrain svm("tmp/svm", "tmp/svm.xml");
svm.train();
//easypr::svmTrain(true, false);
}
break;
case 4:
std::cout << "Run \"demo ann\" for more usage." << std::endl;
{
easypr::AnnTrain ann("tmp/ann", "tmp/ann.xml");
ann.train();
}
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;
}