111 lines
3.9 KiB
C#
111 lines
3.9 KiB
C#
using OpenCVForUnity.CoreModule;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
public abstract class PoseBase
|
|
{
|
|
public Dictionary<string, Point> GetVaildPoints(List<Point> points, List<string> pointName)
|
|
{
|
|
var retVal = new Dictionary<string, Point>();
|
|
|
|
foreach (var name in pointName)
|
|
{
|
|
if (points[YogaConfig.BODY_PARTS[name]] != new Point(-1, -1))
|
|
{
|
|
retVal.Add(name, points[YogaConfig.BODY_PARTS[name]]);
|
|
}
|
|
}
|
|
return retVal;
|
|
}
|
|
public abstract Vector2 GetBasicVectorDirection(List<Point> startPoint, List<Point> endPoint);
|
|
//public abstract void SpeedCheck(double v);
|
|
public abstract void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level);
|
|
public abstract void ExcellenceEstimate(List<(TimeSpan, Vector2)> frameData, Vector2 distance, TimeSpan totalTimeSpan);
|
|
|
|
protected Vector2 GetAverageVector(List<Point> startPoint, List<Point> endPoint, string movePoint)
|
|
{
|
|
List<Vector2> vectors = new List<Vector2>();
|
|
for (int i = 0; i < endPoint.Count; i++)
|
|
{
|
|
string tagName = i.tagName();
|
|
|
|
//自身不计算
|
|
if (movePoint.Equals(tagName) || movePoint.Equals(tagName))
|
|
continue;
|
|
//动点位不计算
|
|
if (IsMovePoint(tagName))
|
|
continue;
|
|
|
|
if (!tagName.IsValid(startPoint) || !tagName.IsValid(endPoint))
|
|
continue;
|
|
//动点-静点
|
|
Vector2 startEyeV = new Vector2((float)movePoint.p(startPoint).x - (float)tagName.p(startPoint).x, (float)movePoint.p(startPoint).y - (float)tagName.p(startPoint).y);
|
|
Vector2 endEyeV = new Vector2((float)movePoint.p(endPoint).x - (float)tagName.p(endPoint).x, (float)movePoint.p(endPoint).y - (float)tagName.p(endPoint).y);
|
|
vectors.Add(endEyeV - startEyeV);
|
|
}
|
|
//计算平均矢量
|
|
Vector2 averageV = new Vector2(0, 0);
|
|
foreach (var v in vectors)
|
|
{
|
|
averageV += v;
|
|
}
|
|
averageV /= vectors.Count;
|
|
|
|
return averageV;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 确定该点位是否为运动时会跟着动的点位
|
|
/// 内部重写,写明该动作的所有动点
|
|
/// </summary>
|
|
/// <param name="tagName">点位名称</param>
|
|
/// <returns>是否为动点</returns>
|
|
protected abstract bool IsMovePoint(string tagName);
|
|
|
|
/// <summary>
|
|
/// 动作检测
|
|
/// </summary>
|
|
/// <param name="points"></param>
|
|
/// <param name="isDataReGather"></param>
|
|
public virtual void AnalyzingAction(List<(DateTime, List<Point>)> points, bool isDataReGather = false)
|
|
{
|
|
if (points.Count < 2) // 0级实现逻辑 不做操作
|
|
return;
|
|
|
|
var distance = Vector2.zero;
|
|
TimeSpan totalTimeSpan = TimeSpan.MinValue;
|
|
for (int i = 0; i < points.Count - 1; i++)
|
|
{
|
|
var p1 = points[i].Item2;
|
|
var p2 = points[i + 1].Item2;
|
|
|
|
var vector = GetAverageVector(p1, p2, "Nose"); //关键点Nose
|
|
distance += vector;
|
|
if (vector.magnitude > 0.1f) //如果矢量长度大于0.1f,说明有运动
|
|
{
|
|
TimeSpan timeSpan = points[i + 1].Item1 - points[i].Item1;
|
|
|
|
if (totalTimeSpan == TimeSpan.MinValue)
|
|
totalTimeSpan = timeSpan;
|
|
else
|
|
totalTimeSpan += timeSpan;
|
|
}
|
|
}
|
|
LogPrint.Log($"distance: {distance}, totalTimeSpan: {totalTimeSpan}", PrintLevel.Normal);
|
|
|
|
int level = 0;
|
|
if (points.Count > 3 && !isDataReGather) //1级实现逻辑
|
|
{
|
|
level = 1;
|
|
}
|
|
if (points.Count > 10 && !isDataReGather) //2级实现逻辑
|
|
{
|
|
level = 2;
|
|
}
|
|
|
|
//动作方位是否正确
|
|
ValidationMovement(distance, totalTimeSpan, level);
|
|
}
|
|
} |