Improved SVM Training CLI.

1.3
Micooz 10 years ago
parent ddaa31aaa0
commit 4cec8b1f49

@ -23,7 +23,6 @@ set(SOURCE_FILES
src/train/ann_train.cpp
src/train/svm_train.cpp
src/preprocess/deface.cpp
src/preprocess/general_test_prepare.cpp
src/preprocess/gdts.cpp
src/preprocess/mc_data.cpp
src/util/util.cpp

@ -3,13 +3,11 @@
#include <vector>
#include <opencv2/opencv.hpp>
#include "easypr/feature.h"
namespace easypr {
class Svm {
public:
typedef enum {
kForward = 1, // correspond to "has plate"
kInverse = 0 // correspond to "no plate"
@ -17,23 +15,8 @@ class Svm {
Svm(const char* forward_data_folder, const char* inverse_data_folder);
void train(bool divide = true, bool train = true,
float divide_percentage = 0.7,
svmCallback getFeatures = getHistogramFeatures);
// void getNoPlateTest(std::vector<cv::Mat>& testingImages,
// std::vector<int>& testingLabels);
//
// void getHasPlateTest(std::vector<cv::Mat>& testingImages,
// std::vector<int>& testingLabels);
//
// void getNoPlateTrain(cv::Mat& trainingImages,
// std::vector<int>& trainingLabels,
// svmCallback getFeatures = getHisteqFeatures);
//
// void getHasPlateTrain(cv::Mat& trainingImages,
// std::vector<int>& trainingLabels,
// svmCallback getFeatures = getHisteqFeatures);
void train(bool divide = true, float divide_percentage = 0.7,
bool train = true, const char* out_svm_folder = NULL);
private:
/*

@ -1,74 +0,0 @@
// 辅助生成general_test中的图片
// 通用做法是使用easypr依次读取图片并用其中的一个车牌识别文字给图片重命名
// easypr识别的文字不一定准确因此需要人再次确认与手工调整下
#include "easypr/plate_recognize.h"
#include "easypr/util.h"
#include "easypr/feature.h"
using namespace easypr;
using namespace std;
using namespace cv;
extern const string GENERAL_TEST_PATH;
// TODO 将下面的路径改成你的
const string src_path = "F:/data/easypr-data/tmp-5";
// TODO 将下面的路径改成你的
const string dst_path = "F:/data/easypr-data/tmp-6";
int general_test() {
auto files = Utils::getFiles(src_path);
CPlateRecognize pr;
pr.LoadANN("resources/model/ann.xml");
pr.LoadSVM("resources/model/svm.xml");
pr.setLifemode(true);
size_t size = files.size();
if (0 == size) {
cout << "No File Found!" << endl;
return 0;
}
cout << "Begin to prepare general_test!" << endl;
for (int i = 0; i < size; i++) {
string filepath = files[i].c_str();
cout << "------------------" << endl;
// EasyPR开始判断车牌
Mat src = imread(filepath);
vector<string> plateVec;
int result = pr.plateRecognize(src, plateVec);
if (result == 0) {
size_t num = plateVec.size();
if (num == 0) {
cout << "" << "无车牌" << endl;
}
else {
cout << plateVec[0] << endl;
string colorplate = plateVec[0];
// 输出"蓝牌:苏E7KU22"中冒号后面的车牌
vector<string> spilt_plate = Utils::splitString(colorplate, ':');
if (spilt_plate.size() == 2) {
stringstream ss(stringstream::in | stringstream::out);
ss << dst_path << "/" << spilt_plate[size - 1] << ".jpg";
imwrite(ss.str(), src);
}
}
}
else {
cout << "错误码:" << result << endl;
}
}
return 0;
}

@ -9,7 +9,6 @@
#include <io.h>
#endif
#include <opencv2/opencv.hpp>
#include "easypr/util.h"
namespace easypr {
@ -66,7 +65,7 @@ cv::Mat cut_top_bottom(const cv::Mat& img) {
int width = img.size().width;
int height = img.size().height;
// TODO: it seems not correctly.
cv::Rect rect(0, 0, width, height * 0.97);
cv::Rect rect(0, 0, width, int(height * 0.97));
return img(rect);
}

File diff suppressed because it is too large Load Diff

@ -6,43 +6,43 @@ namespace easypr {
namespace demo {
int test_chars_segment() {
cout << "test_chars_segment" << endl;
std::cout << "test_chars_segment" << std::endl;
Mat src = imread("resources/image/chars_segment.jpg");
cv::Mat src = cv::imread("resources/image/chars_segment.jpg");
vector <Mat> resultVec;
std::vector<cv::Mat> resultVec;
CCharsSegment plate;
int result = plate.charsSegment(src, resultVec);
if (result == 0) {
size_t num = resultVec.size();
for (int j = 0; j < num; j++) {
Mat resultMat = resultVec[j];
imshow("chars_segment", resultMat);
waitKey(0);
cv::Mat resultMat = resultVec[j];
cv::imshow("chars_segment", resultMat);
cv::waitKey(0);
}
destroyWindow("chars_segment");
cv::destroyWindow("chars_segment");
}
return result;
}
int test_chars_identify() {
cout << "test_chars_identify" << endl;
std::cout << "test_chars_identify" << std::endl;
Mat src = imread("resources/image/chars_identify.jpg");
cv::Mat src = cv::imread("resources/image/chars_identify.jpg");
vector <Mat> resultVec;
std::vector<cv::Mat> resultVec;
CCharsSegment cs;
CCharsIdentify ci;
string plateIdentify = "";
std::string plateIdentify = "";
int result = cs.charsSegment(src, resultVec);
if (result == 0) {
size_t num = resultVec.size();
for (int j = 0; j < num; j++) {
Mat resultMat = resultVec[j];
cv::Mat resultMat = resultVec[j];
bool isChinses = false;
bool isSpec = false;
@ -53,36 +53,36 @@ int test_chars_identify() {
if (j == 1)
isSpec = true;
string charcater = ci.charsIdentify(resultMat, isChinses, isSpec);
std::string charcater = ci.charsIdentify(resultMat, isChinses, isSpec);
plateIdentify = plateIdentify + charcater;
}
}
const string plateLicense = "苏E771H6";
const std::string plateLicense = "苏E771H6";
cout << "plateLicense: " << plateLicense << endl;
cout << "plateIdentify: " << plateIdentify << endl;
std::cout << "plateLicense: " << plateLicense << std::endl;
std::cout << "plateIdentify: " << plateIdentify << std::endl;
if (plateLicense != plateIdentify) {
cout << "Identify Not Correct!" << endl;
std::cout << "Identify Not Correct!" << std::endl;
return -1;
}
cout << "Identify Correct!" << endl;
std::cout << "Identify Correct!" << std::endl;
return result;
}
int test_chars_recognise() {
cout << "test_chars_recognise" << endl;
std::cout << "test_chars_recognise" << std::endl;
Mat src = imread("resources/image/chars_recognise.jpg");
cv::Mat src = cv::imread("resources/image/chars_recognise.jpg");
CCharsRecognise cr;
string charsRecognise = "";
std::string charsRecognise = "";
int result = cr.charsRecognise(src, charsRecognise);
if (result == 0) {
cout << "charsRecognise: " << charsRecognise << endl;
std::cout << "charsRecognise: " << charsRecognise << std::endl;
}
return result;

@ -1,8 +1,9 @@
#include "easypr.h"
#include "easypr/program_options.h"
#include "accuracy.hpp"
#include "plate.hpp"
#include "chars.hpp"
#include "plate.hpp"
namespace easypr {
@ -193,18 +194,32 @@ void command_line_handler(int argc, const char* argv[]) {
options.add_subroutine("svm", "svm operations")
.make_usage("Usage:");
options("h,help", "show help information");
options("c,create", "create learn data, this function " \
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");
options("t,tag", "tag learn data, this function " \
// 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");
options(",svm", "resources/model/svm.xml", "the svm model file");
// 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:");
@ -245,6 +260,10 @@ void command_line_handler(int argc, const char* argv[]) {
}
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>();
@ -252,6 +271,11 @@ void command_line_handler(int argc, const char* argv[]) {
}
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();
@ -262,6 +286,24 @@ void command_line_handler(int argc, const char* argv[]) {
<< "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) {
@ -284,6 +326,9 @@ void command_line_handler(int argc, const char* argv[]) {
}
if (parser->has("file")) {
assert(parser->has("file"));
assert(parser->has("svm"));
auto image = parser->get("file")->val();
auto svm = parser->get("svm")->val();

Loading…
Cancel
Save