Files
scene-actor-extraction/src/build_gallery.cpp
T
dtourolle d753062c6c Initial commit: scene-actor-extraction pipeline
Source (KPN++ pipeline nodes, ArcFace embedders, SCRFD/YuNet detectors,
gallery builder), build scripts, and eval artifacts.

- external/KPN as a git submodule (gitea.tourolle.paris/dtourolle/KPN)
- ONNX models tracked via Git LFS (models/*.onnx)
- generated outputs, TensorRT engines, reference repos, and media ignored
2026-06-12 15:29:01 +02:00

86 lines
3.0 KiB
C++

// build_gallery — build an actor embedding gallery from a directory of images
//
// Gallery directory layout:
// gallery_root/
// nm0000093_Brad_Pitt/
// img1.jpg
// img2.jpg
// nm0000129_Cate_Blanchett/
// ...
//
// Usage:
// build_gallery --root <gallery_root> --output <gallery.json> [options]
//
// Options:
// --detector <path> SCRFD detector model (default: models/scrfd_500m_bnkps.onnx)
// --arcface <path> ArcFace model (default: models/arcface_w600k_r50.onnx)
// --conf <f> face detection confidence threshold (default: 0.5)
// --nms <f> NMS IoU threshold (default: 0.4)
#include "gallery/gallery_builder.hpp"
#include "gallery/gallery_store.hpp"
#include "config.hpp"
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
int main(int argc, char** argv) {
std::string root_path, output_path;
std::string detector_model = kDefaultDetectorModel;
std::string arcface_model = kDefaultArcfaceModel;
float conf = 0.5f, nms_thr = 0.4f;
int max_side = 500;
for (int i = 1; i < argc; ++i) {
auto arg = [&](const char* f) { return std::strcmp(argv[i], f) == 0; };
auto next = [&]() -> std::string {
if (++i >= argc)
throw std::runtime_error(std::string("missing arg after ") + argv[i-1]);
return argv[i];
};
try {
if (arg("--root")) root_path = next();
else if (arg("--output")) output_path = next();
else if (arg("--detector")) detector_model = next();
else if (arg("--arcface")) arcface_model = next();
else if (arg("--conf")) conf = std::stof(next());
else if (arg("--nms")) nms_thr = std::stof(next());
else if (arg("--max-side")) max_side = std::stoi(next());
else { std::cerr << "[warn] unknown flag: " << argv[i] << "\n"; }
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << "\n";
return 1;
}
}
if (root_path.empty() || output_path.empty()) {
std::cerr << "Usage: build_gallery --root <dir> --output <gallery.json> "
"[--detector <path>] [--arcface <path>] [--max-side <N>]\n";
return 1;
}
BuildConfig cfg;
cfg.gallery_root = root_path;
cfg.detector_model = detector_model;
cfg.arcface_model = arcface_model;
cfg.detector_conf = conf;
cfg.detector_nms = nms_thr;
cfg.max_side = max_side;
try {
ActorGallery gallery = build_gallery(cfg);
if (gallery.actors.empty()) {
std::cerr << "No actors built — check your gallery directory.\n";
return 1;
}
save_gallery(output_path, gallery);
std::cerr << "Gallery saved to: " << output_path << "\n";
} catch (const std::exception& e) {
std::cerr << "Fatal: " << e.what() << "\n";
return 1;
}
return 0;
}