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,139 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "chicken_counter/types.hpp"
|
||||
|
||||
namespace cc {
|
||||
|
||||
inline std::string now_iso() {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto t = std::chrono::system_clock::to_time_t(now);
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(std::gmtime(&t), "%FT%TZ");
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
inline std::string relative_output_path(const std::string& path,
|
||||
const std::string& base_dir) {
|
||||
if (path.empty()) return "";
|
||||
if (base_dir.empty()) return std::filesystem::path(path).filename().string();
|
||||
try {
|
||||
auto rel = std::filesystem::relative(path, base_dir);
|
||||
return rel.string();
|
||||
} catch (...) {
|
||||
return std::filesystem::path(path).filename().string();
|
||||
}
|
||||
}
|
||||
|
||||
inline nlohmann::json build_camera_report_entry(
|
||||
const CameraBatchResult& item,
|
||||
const std::string& output_dir = "")
|
||||
{
|
||||
if (item.skipped) {
|
||||
return {{"skipped", true},
|
||||
{"skip_reason", item.skip_reason},
|
||||
{"total_entered", 0}};
|
||||
}
|
||||
|
||||
return {
|
||||
{"total_entered", item.pipeline.total_entered_count},
|
||||
{"source_video", std::filesystem::path(item.pipeline.source_video).filename().string()},
|
||||
{"vis_video", relative_output_path(item.pipeline.vis_video_path, output_dir)},
|
||||
{"compressed_video", relative_output_path(item.compressed_video_path, output_dir)},
|
||||
{"compressed_size_mb", item.compressed_size_mb},
|
||||
{"frames_processed", item.pipeline.frames_processed},
|
||||
{"stopped_reason", item.pipeline.stopped_reason},
|
||||
{"elapsed_seconds", std::round(item.pipeline.elapsed_seconds * 10.0) / 10.0}
|
||||
};
|
||||
}
|
||||
|
||||
struct BatchReport {
|
||||
std::string date;
|
||||
std::string generated_at;
|
||||
nlohmann::json cameras;
|
||||
int total_entered_sum;
|
||||
};
|
||||
|
||||
inline BatchReport build_batch_report(
|
||||
const std::string& date,
|
||||
const std::vector<CameraBatchResult>& results,
|
||||
const std::string& output_dir = "")
|
||||
{
|
||||
BatchReport report;
|
||||
report.date = date;
|
||||
report.generated_at = now_iso();
|
||||
report.total_entered_sum = 0;
|
||||
|
||||
for (const auto& item : results) {
|
||||
auto entry = build_camera_report_entry(item, output_dir);
|
||||
if (entry.empty()) continue;
|
||||
report.cameras[item.camera_id] = entry;
|
||||
if (!item.skipped)
|
||||
report.total_entered_sum += entry.value("total_entered", 0);
|
||||
}
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
inline std::string write_json_file(const std::string& path, const nlohmann::json& j) {
|
||||
namespace fs = std::filesystem;
|
||||
fs::create_directories(fs::path(path).parent_path());
|
||||
std::ofstream f(path);
|
||||
f << j.dump(2);
|
||||
std::cerr << "[report] wrote " << path << "\n";
|
||||
return path;
|
||||
}
|
||||
|
||||
inline std::string write_batch_report(const BatchReport& report,
|
||||
const std::string& output_path) {
|
||||
nlohmann::json j = {
|
||||
{"date", report.date},
|
||||
{"generated_at", report.generated_at},
|
||||
{"cameras", report.cameras},
|
||||
{"total_entered_sum", report.total_entered_sum}
|
||||
};
|
||||
return write_json_file(output_path, j);
|
||||
}
|
||||
|
||||
inline std::string write_camera_report(
|
||||
const std::string& date,
|
||||
const CameraBatchResult& item,
|
||||
const std::string& output_dir)
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
fs::create_directories(output_dir);
|
||||
auto entry = build_camera_report_entry(item, output_dir);
|
||||
nlohmann::json payload = {
|
||||
{"date", date},
|
||||
{"camera_id", item.camera_id},
|
||||
{"generated_at", now_iso()}
|
||||
};
|
||||
for (auto& [k, v] : entry.items()) payload[k] = v;
|
||||
std::string path = output_dir + "/" + item.camera_id + "_counts_" + date + ".json";
|
||||
return write_json_file(path, payload);
|
||||
}
|
||||
|
||||
inline std::string persist_batch_reports(
|
||||
const std::string& date,
|
||||
const std::vector<CameraBatchResult>& results,
|
||||
const std::string& output_dir)
|
||||
{
|
||||
const auto& latest = results.back();
|
||||
write_camera_report(date, latest, output_dir);
|
||||
std::string aggregate_path = output_dir + "/counts_" + date + ".json";
|
||||
auto report = build_batch_report(date, results, output_dir);
|
||||
write_batch_report(report, aggregate_path);
|
||||
return aggregate_path;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
Reference in new issue
Block a user