From 8b43260ed5f0bbc44498f68aed78a9811e82baaa Mon Sep 17 00:00:00 2001 From: Yu SuiXian <47711102+GengGode@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:31:50 +0800 Subject: [PATCH] Add file write functionality and update cache loading --- .../features/features.serialize.hpp | 22 ++- tests/algorithms_features_build/main.cpp | 162 ++++++++++-------- 2 files changed, 111 insertions(+), 73 deletions(-) diff --git a/source/algorithms/features/features.serialize.hpp b/source/algorithms/features/features.serialize.hpp index a4e7edf..7923af3 100644 --- a/source/algorithms/features/features.serialize.hpp +++ b/source/algorithms/features/features.serialize.hpp @@ -3,6 +3,7 @@ #include "algorithms/algorithms.serialize.hpp" #include +#include #include #include @@ -58,6 +59,25 @@ namespace tianli::algorithms::features_serialize throw e; } } + void write(const std::string& file) + { + std::ofstream ofs(file, std::ios::binary); + if (!ofs.is_open()) + { + throw std::runtime_error("features_block file not found"); + } + try + { + cereal::BinaryOutputArchive ar(ofs); + ar(*this); + ofs.close(); + } + catch (const std::exception& e) + { + ofs.close(); + throw e; + } + } }; struct features_group_config @@ -118,7 +138,7 @@ namespace tianli::algorithms::features_serialize for (auto& name : config.names) { - std::string block_file = blocks_dir + "/" + name; + auto block_file = std::filesystem::path(blocks_dir) / name; std::ifstream file(block_file, std::ios::binary); if (!file.is_open()) { diff --git a/tests/algorithms_features_build/main.cpp b/tests/algorithms_features_build/main.cpp index 0276587..933131c 100644 --- a/tests/algorithms_features_build/main.cpp +++ b/tests/algorithms_features_build/main.cpp @@ -8,11 +8,32 @@ using namespace tianli::algorithms::features_serialize; +std::string get_md5_hash(std::string file) +{ + std::string cmd = fmt::format("powershell $(Get-FileHash -Algorithm MD5 -Path {}).Hash", file); + FILE* pipe = _popen(cmd.c_str(), "r"); + if (!pipe) + { + throw std::runtime_error("popen failed"); + } + char buffer[128]; + std::string result = ""; + while (!feof(pipe)) + { + if (fgets(buffer, 128, pipe) != NULL) + { + result += buffer; + } + } + _pclose(pipe); + return result.substr(0, 32); +} + void init_config(std::string config_file,std::map block_hashs) { features_group_config config; config.version = "1.0.0"; - config.block_count = 2; + config.block_count = block_hashs.size(); config.block_hashs = block_hashs; std::vector names; @@ -42,105 +63,102 @@ void init_config(std::string config_file,std::map block } } -// 生成一张随机图片 -cv::Mat gen_mat() -{ - cv::Mat mat(100, 100, CV_8UC3); - cv::randu(mat, cv::Scalar(0, 0, 0), cv::Scalar(255, 255, 255)); - return mat; -} - -features get_rand() +features get_features(cv::Mat mat) { std::vector keypoints; cv::Mat descriptors; cv::Ptr surf = cv::xfeatures2d::SURF::create(); - cv::Mat mat = gen_mat(); surf->detectAndCompute(mat, cv::noArray(), keypoints, descriptors); return features(keypoints, descriptors); } -void init_fts(std::string fts_file) +features_block build_from_image(std::string image_name, cv::Mat image) { - features_config config; - features fts = get_rand(); features_block block; - block.config = config; - block.feature = fts; - block.rect = cv::Rect2d(0, 0, 100, 100); - block.name = "test"; - std::ofstream ofile(fts_file, std::ios::binary); - if (!ofile.is_open()) - { - throw std::runtime_error("features file not found"); - } - try - { - cereal::BinaryOutputArchive ar(ofile); - ar(block); - ofile.close(); - } - catch (const std::exception& e) - { - ofile.close(); - throw e; - } + block.config = features_config(); + block.feature = get_features(image); + block.rect = cv::Rect2d(cv::Point2d(0, 0), image.size()); + block.name = image_name; + return block; } -std::string get_md5_hash(std::string file) +std::string write_block_and_get_hash(features_block block, std::string file) { - std::string cmd = fmt::format("powershell $(Get-FileHash -Algorithm MD5 -Path {}).Hash", file); - FILE* pipe = _popen(cmd.c_str(), "r"); - if (!pipe) - { - throw std::runtime_error("popen failed"); - } - char buffer[128]; - std::string result = ""; - while (!feof(pipe)) - { - if (fgets(buffer, 128, pipe) != NULL) - { - result += buffer; - } - } - _pclose(pipe); - return result.substr(0, 32); + block.write(file); + return get_md5_hash(file); } -int main() +void gen_cache() { - std::string fts_file = "cvAutoTrack.Cache-1.0.0-fts-test1.block"; - init_fts(fts_file); - - features_block block = features_block::read(fts_file); + std::string images_dir = "./images"; + std::string cache_dir = "./cache"; + std::string version = "1.0.1"; + std::string config_file = fmt::format("cvAutoTrack.Cache-{}.config", version); - auto hash = get_md5_hash(fts_file); - std::cout << "hash: " << hash << std::endl; - - std::string config_file = "cvAutoTrack.Cache-1.0.0-config.cache"; - if(!std::filesystem::exists(config_file)) + std::vector image_fils; + for (const auto& entry : std::filesystem::directory_iterator(images_dir)) { - init_config(config_file,{{fts_file,hash}}); + if (!entry.is_regular_file()) + continue; + if(entry.path().extension() != ".png") + continue; + image_fils.push_back(entry.path().string()); } - try + + std::map block_hashs; + for (auto& image_file : image_fils) { - features_group group(config_file,"./"); - if (!group.is_loaded) + cv::Mat image = cv::imread(image_file); + if (image.empty()) { - throw std::runtime_error("features_group not loaded"); + throw std::runtime_error("image not found"); } - for (auto& [name, block] : group.blocks) + // 获取文件名,不包含扩展名 + auto image_name = std::filesystem::path(image_file).filename().string().substr(0, std::filesystem::path(image_file).filename().string().size() - 4); + + auto block_name = fmt::format("cvAutoTrack.Cache-{}.block", image_name); + + std::string block_file = (std::filesystem::path(cache_dir) / block_name).string(); + auto block = build_from_image(block_name, image); + if(block.feature.empty()) { - std::cout << "name: " << name << " block: " << block.name << std::endl; + continue; } + block_hashs[block_name] = write_block_and_get_hash(block, block_file); + } + + init_config(config_file, block_hashs); +} + +void load_cache() +{ + std::string version = "1.0.1"; + std::string config_file = fmt::format("cvAutoTrack.Cache-{}.config", version); + features_group group; + try + { + group = features_group(config_file, "./cache"); } catch(const std::exception& e) { std::cerr << e.what() << '\n'; } - - return 0; -} \ No newline at end of file + std::cout << group.config.version << std::endl; + std::cout << group.config.block_count << std::endl; + std::cout << group.config.names.size() << std::endl; + + for (auto& [name, block] : group.blocks) + { + std::cout << name << " " << block.feature.size() << std::endl; + } +} + int main() + { + //gen_cache(); + + load_cache(); + return 0; + +}