Skip to content

Commit

Permalink
Add file write functionality and update cache
Browse files Browse the repository at this point in the history
loading
  • Loading branch information
GengGode committed Feb 21, 2024
1 parent 0fb3ff6 commit 8b43260
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 73 deletions.
22 changes: 21 additions & 1 deletion source/algorithms/features/features.serialize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "algorithms/algorithms.serialize.hpp"

#include <fstream>
#include <filesystem>

#include <cereal/archives/binary.hpp>
#include <cereal/types/map.hpp>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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())
{
Expand Down
162 changes: 90 additions & 72 deletions tests/algorithms_features_build/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string,std::string> 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<std::string> names;
Expand Down Expand Up @@ -42,105 +63,102 @@ void init_config(std::string config_file,std::map<std::string,std::string> 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<cv::KeyPoint> keypoints;
cv::Mat descriptors;
cv::Ptr<cv::xfeatures2d::SURF> 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<std::string> 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<std::string, std::string> 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;

}
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;

}

0 comments on commit 8b43260

Please sign in to comment.