// 数据预处理的程序,主要做以下两件事 // 1.读取原生数据 rawdata,这可能有数百万张 // 2.随机/选择性地选取部分数据成为learndata,这个根据参数设置,一般设置为1000,10000,或者1百万 #include "easypr/preprocess/mc_data.h" #include <ctime> #include "easypr/core/plate_judge.h" #include "easypr/core/plate_locate.h" #include "easypr/util/util.h" #ifdef OS_WINDOWS #include <io.h> #endif namespace easypr { namespace preprocess { // std::map<std::string, std::string> mc_map = { // {"E00", "未识别"}, // {"A01", "京"}, // {"A02", "津"}, // {"A03", "沪"}, // {"A04", "渝"}, // {"B01", "桂"}, // {"B02", "蒙"}, // {"B03", "宁"}, // {"B04", "新"}, // {"B05", "藏"}, // {"S01", "皖"}, // {"S02", "闽"}, // {"S03", "粤"}, // {"S04", "甘"}, // {"S05", "贵"}, // {"S06", "鄂"}, // {"S07", "冀"}, // {"S08", "黑"}, // {"S09", "湘"}, // {"S10", "豫"}, // {"S11", "琼"}, // {"S12", "吉"}, // {"S13", "苏"}, // {"S14", "赣"}, // {"S15", "辽"}, // {"S16", "青"}, // {"S17", "川"}, // {"S18", "鲁"}, // {"S19", "陕"}, // {"S20", "晋"}, // {"S21", "云"}, // {"S22", "浙"}, // {"J01", "军"}, // {"J02", "海"}, // {"J03", "空"}, // {"J04", "北"}, // {"J05", "成"}, // {"J06", "广"}, // {"J07", "济"}, // {"J08", "兰"}, // {"J09", "南"}, // {"J10", "沈"} //}; // 切去上部与底部干扰的细节 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, int(height * 0.97)); return img(rect); } // std::string code_to_province(const std::string& code) { // return (mc_map.find(code) != mc_map.end()) ? mc_map[code] : "无"; //} //// 通过filepath获取车牌号码 //// 文件名格式:A01_00000 // std::string plate_from_path(const std::string& path) { // auto filename = Utils::getFileName(path); // auto code = filename.substr(0, 3); // return code_to_province(code) + filename.substr(3); //} // 将rawdata截取部分数据到learndata中 void create_learn_data(const char* raw_data_folder, const char* out_data_folder, const int how_many /* = 5000 */) { assert(raw_data_folder); assert(out_data_folder); auto files = Utils::getFiles(raw_data_folder); size_t size = files.size(); if (0 == size) { std::cout << "No file found in " << raw_data_folder << std::endl; return; } // 随机排列rawdata srand(unsigned(time(NULL))); std::random_shuffle(files.begin(), files.end()); int count = 0; for (auto f : files) { // 选取前how_many个rawdata数据作为learndata if (count++ >= how_many) { break; } //读取数据,并对图片进行预处理 cv::Mat img = cv::imread(f); img = cut_top_bottom(img); std::string save_to(out_data_folder); if (*(save_to.end() - 1) != '/') { save_to.push_back('/'); } save_to.append(Utils::getFileName(f, true)); utils::imwrite(save_to, img); std::cout << f << " -> " << save_to << std::endl; } std::cout << "Learn data created successfully!" << std::endl; } // 定位并判断车牌有无,放置在指定位置 void tag_data(const char* source_folder, const char* has_plate_folder, const char* no_plate_folder, const char* svm_model) { assert(source_folder); assert(has_plate_folder); assert(no_plate_folder); assert(svm_model); auto files = Utils::getFiles(source_folder); size_t size = files.size(); if (0 == size) { std::cout << "No file found in " << source_folder << std::endl; return; } CPlateLocate locator; for (auto f : files) { auto filename = Utils::getFileName(f); std::cout << "Tagging: " << f << std::endl; // auto plate_string = plate_from_path(f); cv::Mat image = cv::imread(f); assert(!image.empty()); std::vector<cv::Mat> maybe_plates; locator.plateLocate(image, maybe_plates); int plate_index = 0; for (auto plate : maybe_plates) { char save_to[255] = {0}; int result = 0; PlateJudge::instance()->plateJudge(plate, result); if (result == 1) { // it's a plate sprintf(save_to, "%s/%s_%d.jpg", has_plate_folder, filename.c_str(), plate_index); std::cout << "[Y] -> " << save_to << std::endl; } else { // no plate found sprintf(save_to, "%s/%s_%d.jpg", no_plate_folder, filename.c_str(), plate_index); std::cout << "[N] -> " << save_to << std::endl; } utils::imwrite(save_to, plate); ++plate_index; } } } } // namespace preprocess } // namespace easypr