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
This commit is contained in:
2026-06-12 15:29:01 +02:00
commit d753062c6c
50 changed files with 10100 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include "face_utils.hpp"
#include <iostream>
// ── FaceAlignerFunc ───────────────────────────────────────────────────────────
// KPN node: applies a 5-point similarity transform to each detected face,
// producing a 112×112 BGR crop suitable for ArcFace inference.
//
// Alignment uses cv::estimateAffinePartial2D (RANSAC) to fit the detected
// landmarks to ArcFace canonical positions. Degenerate detections (where the
// affine fit fails) are silently dropped from the output vectors.
struct FaceAlignerFunc {
static constexpr std::string_view label() { return "face_aligner"; }
AlignedSceneFrame operator()(SceneFrame sf) {
if (sf.source.eof || sf.faces.empty())
return {std::move(sf.source), {}, {}};
std::vector<DetectedFace> good_faces;
std::vector<cv::Mat> crops;
good_faces.reserve(sf.faces.size());
crops.reserve(sf.faces.size());
for (auto& face : sf.faces) {
cv::Mat crop = align_face(sf.source.image, face.landmarks);
if (crop.empty()) {
std::cerr << "[face_aligner] degenerate detection skipped\n";
continue;
}
good_faces.push_back(face);
crops.push_back(std::move(crop));
}
return {std::move(sf.source), std::move(good_faces), std::move(crops)};
}
};