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

418 lines
12 KiB

#include "easypr.h"
#include "easypr/util/switch.hpp"
#include "accuracy.hpp"
#include "chars.hpp"
#include "plate.hpp"
// %OPENCV%\x86\vc12\lib opencv_world300d.lib;
namespace easypr {
namespace demo {
// interactions
int accuracyTestMain() {
std::shared_ptr<easypr::Kv> kv(new easypr::Kv);
kv->load("etc/chinese_mapping");
bool isExit = false;
while (!isExit) {
easypr::Utils::print_file_lines("etc/batch_test_menu");
std::cout << kv->get("make_a_choice") << ":";
int select = -1;
bool isRepeat = true;
Result result;
while (isRepeat) {
std::cin >> select;
isRepeat = false;
switch (select) {
case 1:
accuracyTest("resources/image/general_test", result);
break;
case 2:
accuracyTest("resources/image/native_test", result);
break;
case 3:
gridSearchTest("resources/image/general_test");
break;
case 4:
isExit = true;
break;
default:
std::cout << kv->get("input_error") << ":";
isRepeat = true;
break;
}
}
}
return 0;
}
int testMain() {
std::shared_ptr<easypr::Kv> kv(new easypr::Kv);
kv->load("etc/chinese_mapping");
bool isExit = false;
while (!isExit) {
Utils::print_file_lines("etc/test_menu");
std::cout << kv->get("make_a_choice") << ":";
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 << kv->get("input_error") << ":";
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::Result result;
easypr::demo::accuracyTest(folder.c_str(), result);
} 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[]) {
std::shared_ptr<easypr::Kv> kv(new easypr::Kv);
kv->load("etc/chinese_mapping");
if (argc > 1) {
// handle command line execution.
command_line_handler(argc, argv);
return 0;
}
bool isExit = false;
while (!isExit) {
easypr::Utils::print_file_lines("etc/main_menu");
std::cout << kv->get("make_a_choice") << ":";
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();
}
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::AnnChTrain ann("tmp/annCh", "tmp/annCh.xml");
ann.train();
}
break;
case 6: {
easypr::Utils::print_file_lines("etc/dev_team");
break;
}
case 7: {
easypr::Utils::print_file_lines("etc/thanks");
break;
}
case 8:
isExit = true;
break;
default:
std::cout << kv->get("input_error") << ":";
isRepeat = true;
break;
}
}
}
return 0;
}