У меня есть 3D-точки измерения, которые я использовал для расчета на Python и экспортировал их в json. Эти 3D-точки на самом деле получены из измерений SMPL Mesh. Как показано здесь.
Поэтому я пытаюсь сопоставить эти точки с вашей оценкой позы медиапайпа и визуализировать их.
Сначала я получаю точки медиапайпа из обратного вызова,
изображение
затем я выполняю разложение по сингулярным значениям между 3D-позой MediaPipe и точками измерения SMPL.
Но я не могу, по крайней мере, для первого испытания, получить визуализацию точек MediaPipe на Видео Правильно, как первый шаг для выравнивания.
Точки медиапайпа представляют собой красные сферы
[img]https: //i.sstatic.net/itAoWx0j.png[/img]
У меня есть 3D-точки измерения, которые я использовал для расчета на Python и экспортировал их в json. Эти 3D-точки на самом деле получены из измерений SMPL Mesh. Как показано здесь. [img]https://i.sstatic.net/UmSSwHME.png[/img]
Поэтому я пытаюсь сопоставить эти точки с вашей оценкой позы медиапайпа и визуализировать их. Сначала я получаю точки медиапайпа из обратного вызова, изображение затем я выполняю разложение по сингулярным значениям между 3D-позой MediaPipe и точками измерения SMPL. Но я не могу, по крайней мере, для первого испытания, получить визуализацию точек MediaPipe на Видео Правильно, как первый шаг для выравнивания. Точки медиапайпа представляют собой красные сферы [img]https: //i.sstatic.net/itAoWx0j.png[/img]
Весь код: [code]using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using UnityEngine; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json.Linq; using Accord.Math; using Vector3 = Accord.Math.Vector3;
public class SMPLMediaPipeMapper : MonoBehaviour { public TextAsset smplDataJson; private JObject smplData; private Vector3[] smplJoints; private Dictionary smplToMediaPipeMapping; private Dictionary measurementPoints; public Camera mainCamera; public Vector3[] mediaPipeKeypoints; public float mediaPipeToSMPLScale = 1f; public GameObject smplSphere; public GameObject mediaSphere; public GameObject alignedSphere;
public static Vector3[] AlignPoints(Vector3[] mediaPipeKeypoints, Dictionary measurementPoints) { // Mapping the MediaPipe landmarks to measurement points Dictionary mediaPipeToMeasurements = new Dictionary { { 11, "LEFT_SHOULDER" }, { 12, "RIGHT_SHOULDER" }, { 15, "LEFT_WRIST" }, { 16, "RIGHT_WRIST" }, { 23, "LOW_LEFT_HIP" }, { 24, "INSEAM_POINT" }, // Approximation for right hip { 25, "LEFT_THIGH" }, // Approximation for left knee { 27, "LEFT_ANKLE" }, { 28, "RIGHT_ANKLE" }, { 29, "LEFT_HEEL" }, { 30, "RIGHT_HEEL" } };
// Prepare lists for aligned points List pointsA = new List(); // MediaPipe points List pointsB = new List(); // Measurement points
// Align the measurement points to the corresponding MediaPipe landmarks foreach (var map in mediaPipeToMeasurements) { int mediaPipeIndex = map.Key; string measurementKey = map.Value;
// Make sure the measurement exists in the dictionary if (measurementPoints.ContainsKey(measurementKey) && mediaPipeIndex < mediaPipeKeypoints.Length) { pointsA.Add(mediaPipeKeypoints[mediaPipeIndex]); // MediaPipe point pointsB.Add(measurementPoints[measurementKey]); // Corresponding measurement point } }
// Convert the matched points to arrays Vector3[] setA = pointsA.ToArray(); Vector3[] setB = pointsB.ToArray();
// Perform alignment using Procrustes or similar alignment method return AlignPointsUsingProcrustes(setA, setB, mediaPipeKeypoints, measurementPoints); }
public static Vector3[] AlignPointsUsingProcrustes(Vector3[] setA, Vector3[] setB, Vector3[] fullMediaPipeKeypoints, Dictionary fullMeasurementPoints) { // Compute centroids for both sets Vector3 centroidA = ComputeCentroid(setA); Vector3 centroidB = ComputeCentroid(setB);
// Center the points by subtracting centroids var centeredA = setA.Select(p => p - centroidA).ToArray(); var centeredB = setB.Select(p => p - centroidB).ToArray();
// Compute the rotation matrix using the centered points var rotationMatrix = ComputeRotationMatrix(centeredA, centeredB);
// Apply the rotation to all measurement points (even those that were not mapped) return fullMeasurementPoints.Values .Select(p => ApplyRotation(p - centroidB, rotationMatrix) + centroidA) .ToArray(); }
public void UpdateMediaPipeKeypoints(Vector3[] newKeypoints) { if (measurementPointsInstantiated) return;
public static Vector3 ComputeCentroid(Vector3[] points) { Vector3 sum = new Vector3(0, 0, 0); foreach (var point in points) { sum += point; } return sum / points.Length; }
// Perform SVD on the covariance matrix var svd = new Accord.Math.Decompositions.SingularValueDecomposition(covarianceMatrix); var u = svd.LeftSingularVectors; var vt = svd.RightSingularVectors;
// Compute the rotation matrix as U * Vt var rotationMatrix = Accord.Math.Matrix.Dot(u, vt.Transpose());