feat: 添加PoseTransformHandler接口 提供结欢过滤方法的功能

添加直接返回和平均过滤两种过滤方法
This commit is contained in:
jackfiled 2023-03-01 22:07:39 +08:00
parent aaba183c48
commit 2d2adefb96
11 changed files with 114 additions and 47 deletions

View File

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Models; using Models;
using UnityEngine; using UnityEngine;
using Utils.PoseTransformHandlers;
public class MainBehaviour : MonoBehaviour public class MainBehaviour : MonoBehaviour
{ {
@ -27,7 +28,7 @@ private void Update()
{ {
for (var i = 0; i < PoseLandmarkType.MaxValue; i++) for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
{ {
_nodes[i].transform.position = _poseTransforms[i].AveragePos * -5; _nodes[i].transform.position = _poseTransforms[i].ResultPosition * -5;
} }
foreach (var bond in _bonds) foreach (var bond in _bonds)
@ -51,7 +52,7 @@ private void OnReceive(List<PoseLandmark> landmarks)
private void CreateNodes() private void CreateNodes()
{ {
for (var i = 0; i < (int)PoseLandmarkType.MaxValue; i++) for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
{ {
var ball = GameObject.CreatePrimitive(PrimitiveType.Sphere); var ball = GameObject.CreatePrimitive(PrimitiveType.Sphere);
@ -71,7 +72,7 @@ private void CreateNodes()
} }
_nodes[i] = ball; _nodes[i] = ball;
_poseTransforms[i] = new PoseTransform(i); _poseTransforms[i] = new PoseTransform(i, new AverageHandler());
} }
} }

View File

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Models; using Models;
using UnityEngine; using UnityEngine;
using Utils.PoseTransformHandlers;
public class ModelBehaviour : MonoBehaviour public class ModelBehaviour : MonoBehaviour
{ {
@ -34,12 +35,12 @@ private void Update()
foreach (var parent in landmark.Parent) foreach (var parent in landmark.Parent)
{ {
parentsum += PoseTransforms[parent.Value].AveragePos; parentsum += PoseTransforms[parent.Value].ResultPosition;
} }
parentsum /= landmark.Parent.Count; parentsum /= landmark.Parent.Count;
transfrom.rotation = Quaternion.FromToRotation(transfrom.rotation.eulerAngles,landmark.AveragePos-parentsum); transfrom.rotation = Quaternion.FromToRotation(transfrom.rotation.eulerAngles,landmark.ResultPosition-parentsum);
} }
} }
@ -71,7 +72,7 @@ private static void RigPoint(List<PoseLandmark> landmarks)
PoseTransform.UpdatePosition(ref PoseTransforms[landmark.Type.Value], landmark); PoseTransform.UpdatePosition(ref PoseTransforms[landmark.Type.Value], landmark);
Debug.Log(PoseTransforms[landmark.Type.Value].UnityName+":"+PoseTransforms[landmark.Type.Value].AveragePos); Debug.Log(PoseTransforms[landmark.Type.Value].UnityName+":"+PoseTransforms[landmark.Type.Value].ResultPosition);
} }
} }
@ -83,7 +84,7 @@ private void InitPoseTransformList()
{ {
for (var type = 0; type <= PoseLandmarkType.RightFootIndex; type++) for (var type = 0; type <= PoseLandmarkType.RightFootIndex; type++)
{ {
var item = new PoseTransform(type); var item = new PoseTransform(type, new NormalHandler());
if (item.UnityName != HumanBodyBones.LastBone) if (item.UnityName != HumanBodyBones.LastBone)
{ {

View File

@ -3,7 +3,7 @@
namespace Models namespace Models
{ {
//名字 //名字
public struct PoseLandmarkType public readonly struct PoseLandmarkType
{ {
public const int Nose = 0; public const int Nose = 0;
public const int LeftEyeInner = 1; public const int LeftEyeInner = 1;

View File

@ -1,7 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using System; using Utils;
using System.Collections;
namespace Models namespace Models
{ {
@ -23,12 +22,12 @@ public struct PoseTransform
/// <summary> /// <summary>
/// 取平均的长度 /// 取平均的长度
/// </summary> /// </summary>
public static int AverageLength; public static int AverageLength = 3;
/// <summary> /// <summary>
/// 取平均之后的结果 /// 取平均之后的结果
/// </summary> /// </summary>
public Vector3 AveragePos; public Vector3 ResultPosition => _transformHandler.GetResultPosition();
/// <summary> /// <summary>
/// 节点的父节点列表 /// 节点的父节点列表
@ -45,55 +44,25 @@ public struct PoseTransform
/// </summary> /// </summary>
public Quaternion CurrentQuaternion; public Quaternion CurrentQuaternion;
private int _count; private readonly IPoseTransformHandler _transformHandler;
private readonly Queue<PoseLandmark> _landmarkQueue;
public PoseTransform( public PoseTransform(
int type, int type,
int averageLength = 5 IPoseTransformHandler handler
) )
{ {
MediaPipeName = new PoseLandmarkType(type); MediaPipeName = new PoseLandmarkType(type);
UnityName = GetRelatedBone(MediaPipeName); UnityName = GetRelatedBone(MediaPipeName);
AveragePos = new Vector3();
Parent = new List<PoseLandmarkType>(); Parent = new List<PoseLandmarkType>();
PreviousQuaternion = new Quaternion(); PreviousQuaternion = new Quaternion();
CurrentQuaternion = new Quaternion(); CurrentQuaternion = new Quaternion();
AverageLength = averageLength;
_count = 0; _transformHandler = handler;
_landmarkQueue = new Queue<PoseLandmark>();
} }
public static void UpdatePosition(ref PoseTransform pose, PoseLandmark landmark) public static void UpdatePosition(ref PoseTransform pose, PoseLandmark landmark)
{ {
if (pose._count < AverageLength) pose._transformHandler.ReceivePoseLandmark(landmark);
{
pose._landmarkQueue.Enqueue(landmark);
pose._count++;
}
else
{
pose._landmarkQueue.Dequeue();
pose._landmarkQueue.Enqueue(landmark);
var sum = new Vector3();
var parentsum = new Vector3(0f,0f,0f);
foreach (var poseLandmark in pose._landmarkQueue)
{
sum += new Vector3(poseLandmark.X, poseLandmark.Y, poseLandmark.Z);
}
pose.AveragePos = sum / AverageLength;
//pose.CurrentQuaternion = Quaternion.LookRotation(pose.AveragePos - parentsum).normalized;
}
} }
public static void CalculateRotation(ref PoseTransform poseTransform, PoseLandmark landmark) public static void CalculateRotation(ref PoseTransform poseTransform, PoseLandmark landmark)

View File

@ -0,0 +1,23 @@
using Models;
using UnityEngine;
namespace Utils
{
/// <summary>
/// 坐标处理接口
/// </summary>
public interface IPoseTransformHandler
{
/// <summary>
/// 传入新收到的坐标点
/// </summary>
/// <param name="landmark"></param>
public void ReceivePoseLandmark(PoseLandmark landmark);
/// <summary>
/// 获得处理之后的坐标点
/// </summary>
/// <returns></returns>
public Vector3 GetResultPosition();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 09e98a9502f0470f827a472058068bc4
timeCreated: 1677676325

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 790fe29ab090465183945d02718de6a9
timeCreated: 1677676888

View File

@ -0,0 +1,41 @@
using Models;
using UnityEngine;
using System.Collections.Concurrent;
namespace Utils.PoseTransformHandlers
{
public class AverageHandler : IPoseTransformHandler
{
public static int AverageLength = 3;
// 线程安全的队列集合
// 据文档描述甚至没有使用锁
private readonly ConcurrentQueue<PoseLandmark> _queue = new ConcurrentQueue<PoseLandmark>();
public void ReceivePoseLandmark(PoseLandmark landmark)
{
if (_queue.Count < AverageLength)
{
_queue.Enqueue(landmark);
}
else
{
if (_queue.TryDequeue(out _))
{
_queue.Enqueue(landmark);
}
}
}
public Vector3 GetResultPosition()
{
var sum = new Vector3();
foreach (var item in _queue)
{
sum += new Vector3(item.X, item.Y, item.Z);
}
return sum / AverageLength;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c02b0d03301d408faf81931a69679f5c
timeCreated: 1677676898

View File

@ -0,0 +1,20 @@
using Models;
using UnityEngine;
namespace Utils.PoseTransformHandlers
{
public class NormalHandler : IPoseTransformHandler
{
private Vector3 _result;
public void ReceivePoseLandmark(PoseLandmark landmark)
{
_result = new Vector3(landmark.X, landmark.Y, landmark.Z);
}
public Vector3 GetResultPosition()
{
return _result;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 93a33f47f3654fd3b27dd18db88fcc55
timeCreated: 1677678654