style: add an util "class Kv" to deal with chinese chars in the source files

All chinese are stored in etc/, including menu. This is a temporary solution to visual studio's problem. Consider to use English in the future.
v1.6alpha
Micooz 9 years ago
parent 5d3cd897f0
commit 5dd7319481

@ -40,6 +40,7 @@ set(SOURCE_FILES
src/preprocess/mc_data.cpp
src/util/util.cpp
src/util/program_options.cpp
src/util/kv.cpp
)
add_library(easypr STATIC ${SOURCE_FILES})

@ -0,0 +1,6 @@
////////////////////////////////////
BatchTest Option:
1. general_test;
2. native_test;
3. 返回;
////////////////////////////////////

@ -0,0 +1,17 @@
make_a_choice 请选择一项操作
input_error 输入错误,请重新输入
original_plate 原牌
empty_plate 无车牌
diff 差距
char 字符
error_code 错误码
summaries 统计参数
sum_pictures 总图片数
unrecognized 未识出图片
locate_rate 定位率
diff_average 平均字符差距
full_match 完全匹配数
full_rate 完全匹配率
seconds 总时间
seconds_average 平均执行时间

@ -0,0 +1,3 @@
我们EasyPR团队目前有一个5人左右的小组在进行EasyPR后续版本的开发工作。
人数已满,暂时不接受应聘信息,谢谢!

@ -0,0 +1,11 @@
////////////////////////////////////
EasyPR Option:
1. 测试;
2. 批量测试;
3. SVM训练;
4. ANN训练;
5. GDTS生成;
6. 开发团队;
7. 感谢名单;
8. 退出;
////////////////////////////////////

@ -0,0 +1,31 @@
zh_cuan 川
zh_gan1 甘
zh_hei 黑
zh_jin 津
zh_liao 辽
zh_min 闽
zh_qiong 琼
zh_sx 晋
zh_xin 新
zh_yue 粤
zh_zhe 浙
zh_e 鄂
zh_gui 贵
zh_hu 沪
zh_jing 京
zh_lu 鲁
zh_ning 宁
zh_shan 陕
zh_wan 皖
zh_yu 豫
zh_yun 云
zh_gan 赣
zh_gui1 桂
zh_ji 冀
zh_jl 吉
zh_meng 蒙
zh_qing 青
zh_su 苏
zh_xiang 湘
zh_yu1 渝
zh_zang 藏

@ -0,0 +1,12 @@
////////////////////////////////////
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. 返回;
////////////////////////////////////

@ -0,0 +1,7 @@
本项目在建设过程中,受到了很多人的帮助,其中以下是对本项目做出突出贡献的
(贡献包括有益建议,代码调优,数据提供等等,排名按时间顺序)
taotao1233邱锦山唐大侠jsxyhelu如果有一天(zhoushiwei)
学习奋斗袁承志圣城小石匠goldriverMicooz梦里时光
Rain Wangahccoms星夜落尘海豚嘎嘎
还有很多的同学对本项目也给予了鼓励与支持,在此也一并表示真诚的谢意!

@ -1,6 +1,8 @@
#ifndef EASYPR_CORE_CHARSIDENTIFY_H_
#define EASYPR_CORE_CHARSIDENTIFY_H_
#include "easypr/util/kv.h"
#include <memory>
#include <opencv2/opencv.hpp>
namespace easypr {
@ -16,6 +18,7 @@ class CharsIdentify {
static CharsIdentify* instance_;
cv::Ptr<cv::ml::ANN_MLP> ann_;
std::shared_ptr<Kv> kv_;
};
}

@ -0,0 +1,27 @@
#ifndef EASYPR_UTIL_KV_H_
#define EASYPR_UTIL_KV_H_
#include <map>
#include <string>
namespace easypr {
class Kv {
public:
Kv();
void load(const std::string &file);
std::string get(const std::string &key);
void remove(const std::string &key);
void clear();
private:
std::map<std::string, std::string> data_;
};
}
#endif // EASYPR_UTIL_KV_H_

@ -1,6 +1,7 @@
#ifndef EASYPR_UTIL_UTIL_H_
#define EASYPR_UTIL_UTIL_H_
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
@ -31,20 +32,20 @@ class Utils {
* Get file name from a given path
* bool postfix: including the postfix
*/
static std::string getFileName(const std::string& path,
static std::string getFileName(const std::string &path,
const bool postfix = false);
/*
* Split the given string into segements by a delimiter
*/
static std::vector<std::string> splitString(const std::string& str,
static std::vector<std::string> splitString(const std::string &str,
const char delimiter);
/*
* returns the smaller of the two numbers
*/
template <typename T>
static T min(const T& v1, const T& v2) {
template<typename T>
static T min(const T &v1, const T &v2) {
return (v1 < v2) ? v1 : v2;
}
@ -52,7 +53,7 @@ class Utils {
* Get files from a given folder
* all: including all sub-folders
*/
static std::vector<std::string> getFiles(const std::string& folder,
static std::vector<std::string> getFiles(const std::string &folder,
const bool all = true);
/*
@ -71,14 +72,31 @@ class Utils {
* Print string lines using {"string1", "string2"},
* this is a easier way benefit from C++11.
*/
static void print_str_lines(const std::initializer_list<const char*>& lines) {
static void print_str_lines(const std::initializer_list<const char*> &lines) {
for (auto line : lines) {
std::cout << line << std::endl;
}
}
template <class T>
static unsigned int levenshtein_distance(const T& s1, const T& s2) {
/*
* Read and print by line.
*/
static void print_file_lines(const std::string &file) {
std::ifstream fs(file);
if (fs.good()) {
while (!fs.eof()) {
std::string line;
std::getline(fs, line);
std::cout << line << std::endl;
}
fs.close();
} else {
std::cerr << "cannot open file: " << file << std::endl;
}
}
template<class T>
static unsigned int levenshtein_distance(const T &s1, const T &s2) {
const size_t len1 = s1.size(), len2 = s2.size();
std::vector<unsigned int> col(len2 + 1), prevCol(len2 + 1);
@ -103,13 +121,13 @@ class Utils {
* Make sure the destination folder exists,
* if not, create it, then call cv::imwrite.
*/
static bool imwrite(const std::string& file, const cv::Mat& image);
static bool imwrite(const std::string &file, const cv::Mat &image);
private:
/*
* Get the last slash from a path, compatible with Windows and *unix.
*/
static std::size_t get_last_slash(const std::string& path);
static std::size_t get_last_slash(const std::string &path);
};
typedef Utils utils;

@ -15,6 +15,8 @@ CharsIdentify* CharsIdentify::instance() {
CharsIdentify::CharsIdentify() {
ann_ = ml::ANN_MLP::load<ml::ANN_MLP>(kDefaultAnnPath);
kv_ = std::shared_ptr<Kv>(new Kv);
kv_->load("etc/province_mapping");
}
std::pair<std::string, std::string> CharsIdentify::identify(cv::Mat input) {
@ -25,9 +27,7 @@ std::pair<std::string, std::string> CharsIdentify::identify(cv::Mat input) {
} else {
const char* key = kChars[index];
std::string s = key;
//std::cout << s << std::endl;
std::string province = kCharsMap.at(s);
//std::cout << province << std::endl;
std::string province = kv_->get(s);
return std::make_pair(s, province);
}
}

@ -0,0 +1,70 @@
#include "easypr/util/kv.h"
#include <fstream>
#include <iostream>
namespace easypr {
Kv::Kv() { }
void Kv::load(const std::string &file) {
this->clear();
std::ifstream reader(file);
while (!reader.eof()) {
std::string line;
std::getline(reader, line);
if (line.empty()) continue;
const auto parse = [](const std::string &str) {
std::string tmp, key, value;
for (size_t i = 0, len = str.length(); i < len; ++i) {
const char ch = str[i];
if (ch == ' ') {
if (i > 0 && str[i - 1] != ' ' && key.empty()) {
key = tmp;
tmp.clear();
}
} else {
tmp.push_back(ch);
}
if (i == len - 1) {
value = tmp;
}
}
return std::make_pair(key, value);
};
auto kv = parse(line);
if (data_.find(kv.first) != data_.end()) {
fprintf(stderr,
"[Kv] find duplicate: %s = %s , ignore\n",
kv.first.c_str(),
kv.second.c_str());
} else {
data_.insert(parse(line));
}
}
reader.close();
}
std::string Kv::get(const std::string &key) {
if (data_.find(key) == data_.end()) {
std::cerr << "[Kv] cannot find " << key << std::endl;
return "";
}
return data_.at(key);
}
void Kv::remove(const std::string &key) {
if (data_.find(key) == data_.end()) {
std::cerr << "[Kv] cannot find " << key << std::endl;
return;
}
data_.erase(key);
}
void Kv::clear() {
data_.clear();
}
}

@ -36,7 +36,7 @@ namespace easypr {
long Utils::getTimestamp() {
#ifdef OS_WINDOWS
return GetTickCount();
return static_cast<long>(cv::getTickCount());
#endif
#ifdef OS_LINUX
@ -57,7 +57,7 @@ long Utils::getTimestamp() {
#endif
}
std::string Utils::getFileName(const std::string& path,
std::string Utils::getFileName(const std::string &path,
const bool postfix /* = false */) {
if (!path.empty()) {
size_t last_slash = utils::get_last_slash(path);
@ -80,7 +80,7 @@ std::string Utils::getFileName(const std::string& path,
return "";
}
std::vector<std::string> Utils::splitString(const std::string& str,
std::vector<std::string> Utils::splitString(const std::string &str,
const char delimiter) {
std::vector<std::string> splited;
std::string s(str);
@ -101,7 +101,7 @@ std::vector<std::string> Utils::splitString(const std::string& str,
return splited;
}
std::vector<std::string> Utils::getFiles(const std::string& folder,
std::vector<std::string> Utils::getFiles(const std::string &folder,
const bool all /* = true */) {
std::vector<std::string> files;
std::list<std::string> subfolders;
@ -228,7 +228,7 @@ bool Utils::mkdir(const std::string folder) {
#else
if (0 != ::access(folder_builder.c_str(), 0)) {
#endif
// this folder not exist
// this folder not exist
#ifdef OS_WINDOWS
if (0 != ::_mkdir(folder_builder.c_str())) {
#else
@ -244,13 +244,13 @@ bool Utils::mkdir(const std::string folder) {
return true;
}
bool Utils::imwrite(const std::string& file, const cv::Mat& image) {
bool Utils::imwrite(const std::string &file, const cv::Mat &image) {
auto folder = file.substr(0, utils::get_last_slash(file));
Utils::mkdir(folder);
return cv::imwrite(file, image);
}
std::size_t Utils::get_last_slash(const std::string& path) {
std::size_t Utils::get_last_slash(const std::string &path) {
#ifdef OS_WINDOWS
size_t last_slash_1 = path.find_last_of("\\");
size_t last_slash_2 = path.find_last_of("/");

Loading…
Cancel
Save