Make triangulation a zero-copy pure function

This commit is contained in:
2026-03-11 22:29:21 +08:00
parent 5bed0f0aaf
commit 24f74c87f1
10 changed files with 596 additions and 947 deletions
+42 -53
View File
@@ -1,7 +1,7 @@
#pragma once
#include <array>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
@@ -14,6 +14,17 @@ using NestedPoses3D = std::vector<std::vector<std::array<float, 4>>>;
// =================================================================================================
struct PoseBatch2DView
{
const float *data = nullptr;
const uint32_t *person_counts = nullptr;
size_t num_views = 0;
size_t max_persons = 0;
size_t num_joints = 0;
const float &at(size_t view, size_t person, size_t joint, size_t coord) const;
};
struct PoseBatch2D
{
std::vector<float> data;
@@ -24,8 +35,8 @@ struct PoseBatch2D
float &at(size_t view, size_t person, size_t joint, size_t coord);
const float &at(size_t view, size_t person, size_t joint, size_t coord) const;
PoseBatch2DView view() const;
RaggedPoses2D to_nested() const;
static PoseBatch2D from_nested(const RaggedPoses2D &poses_2d);
};
@@ -44,56 +55,34 @@ struct PoseBatch3D
// =================================================================================================
class TriangulatorInternal;
/**
* Calculate a triangulation using a padded pose tensor.
*
* @param poses_2d Padded poses of shape [views, max_persons, joints, 3].
* @param cameras List of cameras.
* @param roomparams Room parameters (room size, room center).
* @param joint_names List of 2D joint names.
* @param min_match_score Minimum score to consider a triangulated joint as valid.
* @param min_group_size Minimum number of camera pairs that need to see a person.
*
* @return Pose tensor of shape [persons, joints, 4].
*/
PoseBatch3D triangulate_poses(
const PoseBatch2DView &poses_2d,
const std::vector<Camera> &cameras,
const std::array<std::array<float, 3>, 2> &roomparams,
const std::vector<std::string> &joint_names,
float min_match_score = 0.95f,
size_t min_group_size = 1);
// =================================================================================================
class Triangulator
inline PoseBatch3D triangulate_poses(
const PoseBatch2D &poses_2d,
const std::vector<Camera> &cameras,
const std::array<std::array<float, 3>, 2> &roomparams,
const std::vector<std::string> &joint_names,
float min_match_score = 0.95f,
size_t min_group_size = 1)
{
public:
/**
* Triangulator to predict poses from multiple views.
*
* @param min_match_score Minimum score to consider a triangulated joint as valid.
* @param min_group_size Minimum number of camera pairs that need to see a person.
*/
Triangulator(
float min_match_score = 0.95,
size_t min_group_size = 1);
~Triangulator();
/**
* Calculate a triangulation using a padded pose tensor.
*
* @param poses_2d Padded poses of shape [views, max_persons, joints, 3].
* @param cameras List of cameras.
* @param roomparams Room parameters (room size, room center).
* @param joint_names List of 2D joint names.
*
* @return Pose tensor of shape [persons, joints, 4].
*/
PoseBatch3D triangulate_poses(
const PoseBatch2D &poses_2d,
const std::vector<Camera> &cameras,
const std::array<std::array<float, 3>, 2> &roomparams,
const std::vector<std::string> &joint_names);
/**
* Compatibility overload for callers that still produce ragged nested vectors.
*/
NestedPoses3D triangulate_poses(
const RaggedPoses2D &poses_2d,
const std::vector<Camera> &cameras,
const std::array<std::array<float, 3>, 2> &roomparams,
const std::vector<std::string> &joint_names);
/** Reset the triangulator. */
void reset();
/** Print triangulation statistics. */
void print_stats();
private:
std::unique_ptr<TriangulatorInternal> triangulator;
};
return triangulate_poses(
poses_2d.view(), cameras, roomparams, joint_names, min_match_score, min_group_size);
}