forked from zakaria/chicken-counting-sukawarna-det
Create C++ version
This commit is contained in:
1 parent
1a3242f611
commit
f34eaa3af4
25 files changed
+3353
-24
No files matched your search
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "chicken_counter/config.hpp"
|
||||
|
||||
namespace cc {
|
||||
|
||||
struct CameraDiscoveryResult {
|
||||
std::unordered_map<std::string, std::string> found;
|
||||
std::unordered_map<std::string, std::string> skipped;
|
||||
};
|
||||
|
||||
inline std::string replace_glob_placeholder(const std::string& pattern, int num) {
|
||||
std::string s = pattern;
|
||||
std::string token = "{num}";
|
||||
size_t pos = s.find(token);
|
||||
if (pos != std::string::npos) {
|
||||
s.replace(pos, token.size(), std::to_string(num));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::vector<std::string> glob_filenames(const std::string& dir, const std::string& pattern) {
|
||||
namespace fs = std::filesystem;
|
||||
std::vector<std::string> matches;
|
||||
std::string regex_str = "^";
|
||||
for (char c : pattern) {
|
||||
if (c == '*') regex_str += ".*";
|
||||
else if (c == '?') regex_str += ".";
|
||||
else if (c == '.' || c == '[' || c == ']' || c == '(' || c == ')' || c == '{' || c == '}')
|
||||
regex_str += std::string("\\") + c;
|
||||
else regex_str += c;
|
||||
}
|
||||
regex_str += "$";
|
||||
std::regex re(regex_str);
|
||||
|
||||
for (auto& entry : fs::directory_iterator(dir)) {
|
||||
if (!entry.is_regular_file()) continue;
|
||||
std::string fname = entry.path().filename().string();
|
||||
if (std::regex_match(fname, re))
|
||||
matches.push_back(entry.path().string());
|
||||
}
|
||||
std::sort(matches.begin(), matches.end());
|
||||
return matches;
|
||||
}
|
||||
|
||||
inline CameraDiscoveryResult discover_camera_videos(
|
||||
const std::string& day_dir,
|
||||
const BatchSettings& settings)
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
if (!fs::is_directory(day_dir))
|
||||
throw std::runtime_error("Daily input folder does not exist: " + day_dir);
|
||||
|
||||
CameraDiscoveryResult result;
|
||||
int total = static_cast<int>(settings.cameras.size());
|
||||
|
||||
using pair_t = std::pair<std::string, CameraPreset>;
|
||||
std::vector<pair_t> sorted_cams(settings.cameras.begin(), settings.cameras.end());
|
||||
std::sort(sorted_cams.begin(), sorted_cams.end(),
|
||||
[](const pair_t& a, const pair_t& b) { return a.second.camera_num < b.second.camera_num; });
|
||||
|
||||
for (const auto& [camera_id, preset] : sorted_cams) {
|
||||
std::string pattern = replace_glob_placeholder(settings.batch.camera_glob, preset.camera_num);
|
||||
auto matches = glob_filenames(day_dir, pattern);
|
||||
if (matches.empty()) {
|
||||
result.skipped[camera_id] = "video_not_found";
|
||||
continue;
|
||||
}
|
||||
if (matches.size() > 1) {
|
||||
result.skipped[camera_id] = "multiple_matches";
|
||||
continue;
|
||||
}
|
||||
result.found[camera_id] = matches[0];
|
||||
}
|
||||
|
||||
if (result.found.empty()) {
|
||||
std::string summary;
|
||||
for (const auto& [id, reason] : result.skipped) summary += id + " (" + reason + "), ";
|
||||
throw std::runtime_error("No camera videos found in " + day_dir + ". Skipped: " + summary);
|
||||
}
|
||||
|
||||
int found_count = static_cast<int>(result.found.size());
|
||||
if (!result.skipped.empty()) {
|
||||
std::string summary;
|
||||
for (const auto& [id, reason] : result.skipped) summary += id + " (" + reason + "), ";
|
||||
std::cerr << "[batch] discovered " << found_count << "/" << total
|
||||
<< " cameras; skipped: " << summary << "\n";
|
||||
} else {
|
||||
std::cerr << "[batch] discovered " << found_count << "/" << total << " cameras\n";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
Reference in new issue
Block a user