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
86 lines
3.0 KiB
C++
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;
|
|
}
|