更新动作检测逻辑
This commit is contained in:
parent
f6c45303ad
commit
d2bf122e56
|
@ -74,98 +74,6 @@ Animator:
|
|||
m_AllowConstantClipSamplingOptimization: 1
|
||||
m_KeepAnimatorStateOnDisable: 0
|
||||
m_WriteDefaultValuesOnDisable: 0
|
||||
--- !u!1 &1655379611402516801
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2246865126792962373}
|
||||
- component: {fileID: 8261163955276643325}
|
||||
- component: {fileID: 7348735772167593676}
|
||||
- component: {fileID: 4493683514322913532}
|
||||
m_Layer: 5
|
||||
m_Name: ShowText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2246865126792962373
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1655379611402516801}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 4, y: 4, z: 4}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 38199016232350786}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: -1329, y: -444}
|
||||
m_SizeDelta: {x: 200, y: 40}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &8261163955276643325
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1655379611402516801}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &7348735772167593676
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1655379611402516801}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 0, b: 0, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 28
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "\u6D4B\u8BD5\u6587\u672C"
|
||||
--- !u!114 &4493683514322913532
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1655379611402516801}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 7e87e8c67a3599740822141fa1e8a73f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &2305242494350081140
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -197,8 +105,6 @@ RectTransform:
|
|||
- {fileID: 8475079236000353301}
|
||||
- {fileID: 18963948842239410}
|
||||
- {fileID: 5076069559660177782}
|
||||
- {fileID: 2246865126792962373}
|
||||
- {fileID: 913300150706249764}
|
||||
m_Father: {fileID: 475269767089658797}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
|
@ -291,114 +197,6 @@ CanvasGroup:
|
|||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 1
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!1 &4494414620026654833
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 913300150706249764}
|
||||
- component: {fileID: 3765446309826417366}
|
||||
- component: {fileID: 2254883025463725799}
|
||||
- component: {fileID: 1639543910360457363}
|
||||
- component: {fileID: 4220982582391514376}
|
||||
m_Layer: 5
|
||||
m_Name: ShowHint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &913300150706249764
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4494414620026654833}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 4, y: 4, z: 4}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 38199016232350786}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 1}
|
||||
m_AnchorMax: {x: 0.5, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -50}
|
||||
m_SizeDelta: {x: 400, y: 40}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!222 &3765446309826417366
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4494414620026654833}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &2254883025463725799
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4494414620026654833}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 28
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 2
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: "\u6D4B\u8BD5\u6587\u672C"
|
||||
--- !u!114 &1639543910360457363
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4494414620026654833}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
m_EffectDistance: {x: 3, y: -1}
|
||||
m_UseGraphicAlpha: 1
|
||||
--- !u!114 &4220982582391514376
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4494414620026654833}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 8d1cb71f907bfec429b9020e43438c62, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &4557793384850939514
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
@ -6,8 +6,6 @@ using UnityEngine;
|
|||
|
||||
public class BodyBendLeft : PoseBase
|
||||
{
|
||||
public BodyBendLeft(ModelType name) : base(name) { }
|
||||
|
||||
public override bool CheckPose(List<Point> points)
|
||||
{
|
||||
if (!CheckPoint(points, "LHip") &&
|
||||
|
@ -21,16 +19,4 @@ public class BodyBendLeft : PoseBase
|
|||
|
||||
return false;
|
||||
}
|
||||
public override void ShowHint()
|
||||
{
|
||||
}
|
||||
public override void ProcessFailCallBack()
|
||||
{
|
||||
//YogaManager.Instance.UpdateStatus?.Invoke(string.Empty);
|
||||
}
|
||||
|
||||
public override void ProcessSuccessCallBack(Action callback)
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("左弯腰");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ using UnityEngine;
|
|||
|
||||
public class BodyBendRight : PoseBase
|
||||
{
|
||||
public BodyBendRight(ModelType name) : base(name) { }
|
||||
|
||||
public override bool CheckPose(List<Point> points)
|
||||
{
|
||||
if (!CheckPoint(points, "RHip") &&
|
||||
|
@ -20,18 +18,4 @@ public class BodyBendRight : PoseBase
|
|||
}
|
||||
return false;
|
||||
}
|
||||
public override void ShowHint()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void ProcessFailCallBack()
|
||||
{
|
||||
//YogaManager.Instance.UpdateStatus?.Invoke(string.Empty);
|
||||
}
|
||||
|
||||
public override void ProcessSuccessCallBack(Action callback)
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("右弯腰");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ using UnityEngine;
|
|||
|
||||
public class BodyTurnLeft : PoseBase
|
||||
{
|
||||
public BodyTurnLeft(ModelType name) : base(name) { }
|
||||
|
||||
public override bool CheckPose(List<Point> points)
|
||||
{
|
||||
if (!CheckPoint(points, "LShoulder") &&
|
||||
|
@ -21,23 +19,4 @@ public class BodyTurnLeft : PoseBase
|
|||
|
||||
return false;
|
||||
}
|
||||
public override void ShowHint()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void ProcessFailCallBack()
|
||||
{
|
||||
//YogaManager.Instance.UpdateStatus?.Invoke(string.Empty);
|
||||
}
|
||||
|
||||
public override void ProcessSuccessCallBack(Action callback)
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("左转身");
|
||||
}
|
||||
}
|
||||
|
||||
//public class NodCheck : PoseBase
|
||||
//{
|
||||
|
||||
//}
|
|
@ -6,8 +6,6 @@ using UnityEngine;
|
|||
|
||||
public class BodyTurnRight : PoseBase
|
||||
{
|
||||
public BodyTurnRight(ModelType name) : base(name) { }
|
||||
|
||||
public override bool CheckPose(List<Point> points)
|
||||
{
|
||||
if (!CheckPoint(points, "RShoulder") &&
|
||||
|
@ -21,18 +19,4 @@ public class BodyTurnRight : PoseBase
|
|||
|
||||
return false;
|
||||
}
|
||||
public override void ShowHint()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void ProcessFailCallBack()
|
||||
{
|
||||
//YogaManager.Instance.UpdateStatus?.Invoke(string.Empty);
|
||||
}
|
||||
|
||||
public override void ProcessSuccessCallBack(Action callback)
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("右转身");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class CheckStatusUIController : MonoBehaviour
|
||||
{
|
||||
private void OnEnable()
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus -= UpdateStatus;
|
||||
YogaManager.Instance.UpdateStatus += UpdateStatus;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus -= UpdateStatus;
|
||||
}
|
||||
|
||||
private void UpdateStatus(string status)
|
||||
{
|
||||
this.GetComponent<Text>().text = status;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7e87e8c67a3599740822141fa1e8a73f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -8,8 +8,6 @@ public class HeadTurnLeft : PoseBase
|
|||
{
|
||||
private bool _isRunning = false;
|
||||
|
||||
public HeadTurnLeft(ModelType name) : base(name) { }
|
||||
|
||||
public override bool CheckPose(List<Point> points)
|
||||
{
|
||||
if (!CheckPoint(points, "Nose"))
|
||||
|
@ -28,40 +26,4 @@ public class HeadTurnLeft : PoseBase
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ShowHint()
|
||||
{
|
||||
YogaManager.Instance.ShowHint?.Invoke("请左转头");
|
||||
EventManager.Instance.Dispatch("PlayAnimation", AvatarAction.HeadTurnLeft);
|
||||
}
|
||||
|
||||
public override void ProcessSuccessCallBack(Action callback)
|
||||
{
|
||||
if (_isRunning)
|
||||
return;
|
||||
YogaManager.Instance.StartCoroutine(SuccessAction(callback));
|
||||
}
|
||||
|
||||
public override void ProcessFailCallBack()
|
||||
{
|
||||
//YogaManager.Instance.UpdateStatus?.Invoke(string.Empty);
|
||||
}
|
||||
|
||||
private IEnumerator SuccessAction(Action callback)
|
||||
{
|
||||
_isRunning = true;
|
||||
yield return new WaitForSeconds(3f);
|
||||
|
||||
if (!CheckPose(YogaManager.Instance.Points))
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("请左转头");
|
||||
_isRunning = false;
|
||||
yield break;
|
||||
}
|
||||
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("很好,你已经左转头了!");
|
||||
yield return new WaitForSeconds(1f);
|
||||
_isRunning = true;
|
||||
callback?.Invoke();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,6 @@ using UnityEngine;
|
|||
|
||||
public class HeadTurnRight : PoseBase
|
||||
{
|
||||
private bool _isRunning = false;
|
||||
|
||||
public HeadTurnRight(ModelType name) : base(name) { }
|
||||
|
||||
public override bool CheckPose(List<Point> points)
|
||||
{
|
||||
if (!CheckPoint(points, "Nose"))
|
||||
|
@ -26,39 +22,4 @@ public class HeadTurnRight : PoseBase
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ShowHint()
|
||||
{
|
||||
YogaManager.Instance.ShowHint?.Invoke("请右转头");
|
||||
EventManager.Instance.Dispatch("PlayAnimation", AvatarAction.HeadTurnRight);
|
||||
}
|
||||
|
||||
public override void ProcessFailCallBack()
|
||||
{
|
||||
//YogaManager.Instance.UpdateStatus?.Invoke(string.Empty);
|
||||
}
|
||||
|
||||
public override void ProcessSuccessCallBack(Action callback)
|
||||
{
|
||||
if (_isRunning)
|
||||
return;
|
||||
YogaManager.Instance.StartCoroutine(SuccessAction(callback));
|
||||
}
|
||||
|
||||
private IEnumerator SuccessAction(Action callback)
|
||||
{
|
||||
_isRunning = true;
|
||||
yield return new WaitForSeconds(3f);
|
||||
if (!CheckPose(YogaManager.Instance.Points))
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("请右转头");
|
||||
_isRunning = false;
|
||||
yield break;
|
||||
}
|
||||
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("很好,你已经右转头了!");
|
||||
yield return new WaitForSeconds(1f);
|
||||
_isRunning = true;
|
||||
callback?.Invoke();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ public class IsReady : PoseBase
|
|||
{
|
||||
private bool _isRunning = false;
|
||||
|
||||
public IsReady(ModelType name) : base(name) { }
|
||||
|
||||
public override bool CheckPose(List<Point> points)
|
||||
{
|
||||
|
@ -24,39 +23,4 @@ public class IsReady : PoseBase
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void ProcessFailCallBack()
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus?.Invoke(string.Empty);
|
||||
}
|
||||
|
||||
public override void ProcessSuccessCallBack(Action callback)
|
||||
{
|
||||
if (_isRunning)
|
||||
return;
|
||||
YogaManager.Instance.StartCoroutine(SuccessAction(callback));
|
||||
}
|
||||
|
||||
public override void ShowHint()
|
||||
{
|
||||
YogaManager.Instance.ShowHint?.Invoke("请摆正姿势");
|
||||
}
|
||||
|
||||
private IEnumerator SuccessAction(Action callback)
|
||||
{
|
||||
_isRunning = true;
|
||||
yield return new WaitForSeconds(3f);
|
||||
|
||||
if (!CheckPose(YogaManager.Instance.Points))
|
||||
{
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("请摆正姿势");
|
||||
_isRunning = false;
|
||||
yield break;
|
||||
}
|
||||
|
||||
YogaManager.Instance.UpdateStatus?.Invoke("很好,你已经摆正了姿态!");
|
||||
yield return new WaitForSeconds(1f);
|
||||
_isRunning = true;
|
||||
callback?.Invoke();
|
||||
}
|
||||
}
|
|
@ -51,11 +51,7 @@ namespace Yoga
|
|||
|
||||
private double threshold = 0.5;
|
||||
|
||||
private float _involkCDTime = 0;
|
||||
private Coroutine _objEstimation;
|
||||
private Coroutine _actionEstimation;
|
||||
private bool _isOnCamCapture = false;
|
||||
|
||||
public bool IsOnCamCapture { get => _isOnCamCapture; internal set => _isOnCamCapture = value; }
|
||||
|
||||
private void OnEnable()
|
||||
|
@ -72,11 +68,6 @@ namespace Yoga
|
|||
EventManager.Instance.RemoveEventListener("ScoreUpdate", ScoreUpdate);
|
||||
}
|
||||
|
||||
private void EstimateAction()
|
||||
{
|
||||
//检测动作
|
||||
}
|
||||
|
||||
private void OnStartMotionCapture()
|
||||
{
|
||||
this.enabled = true;
|
||||
|
@ -147,62 +138,75 @@ namespace Yoga
|
|||
{
|
||||
Mat img = _webCamTextureToMatHelper.GetMat();
|
||||
Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2RGB);
|
||||
|
||||
_involkCDTime += Time.deltaTime;
|
||||
if (_involkCDTime > SamplingRate)
|
||||
{
|
||||
if (_objEstimation != null)
|
||||
StopCoroutine(_objEstimation);
|
||||
|
||||
_objEstimation = StartCoroutine(ObjectEstimation(img));
|
||||
_involkCDTime = 0;
|
||||
}
|
||||
|
||||
//#if DEBUG_MODE && UNITY_EDITOR
|
||||
_rgbaMat = img.clone();
|
||||
if (_net == null)
|
||||
{
|
||||
Imgproc.putText(img, "model file is not loaded.", new Point(5, img.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
Imgproc.putText(img, "Please read console message.", new Point(5, img.rows() - 10), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false);
|
||||
}
|
||||
|
||||
DebugPrintObjectLayout(img, _voloResult[0], _voloResult[1], _voloResult[2]);
|
||||
if (_voloResult.Count >= 2)
|
||||
DebugPrintObjectLayout(img, _voloResult[0], _voloResult[1], _voloResult[2]);
|
||||
|
||||
List<Point> points = _personPoints;
|
||||
|
||||
for (int i = 0; i < YogaConfig.POSE_PAIRS.GetLength(0); i++)
|
||||
if (_personPoints.Count > 0)
|
||||
{
|
||||
string partFrom = YogaConfig.POSE_PAIRS[i, 0];
|
||||
string partTo = YogaConfig.POSE_PAIRS[i, 1];
|
||||
List<Point> points = _personPoints;
|
||||
|
||||
int idFrom = YogaConfig.BODY_PARTS[partFrom];
|
||||
int idTo = YogaConfig.BODY_PARTS[partTo];
|
||||
|
||||
if (points[idFrom] == new Point(-1, -1) || points[idTo] == new Point(-1, -1))
|
||||
continue;
|
||||
|
||||
if (points[idFrom] != null && points[idTo] != null)
|
||||
for (int i = 0; i < YogaConfig.POSE_PAIRS.GetLength(0); i++)
|
||||
{
|
||||
Imgproc.line(img, points[idFrom], points[idTo], new Scalar(0, 255, 0), 3);
|
||||
Imgproc.ellipse(img, points[idFrom], new Size(3, 3), 0, 0, 360, new Scalar(0, 0, 255), Core.FILLED);
|
||||
Imgproc.ellipse(img, points[idTo], new Size(3, 3), 0, 0, 360, new Scalar(0, 0, 255), Core.FILLED);
|
||||
string partFrom = YogaConfig.POSE_PAIRS[i, 0];
|
||||
string partTo = YogaConfig.POSE_PAIRS[i, 1];
|
||||
|
||||
int idFrom = YogaConfig.BODY_PARTS[partFrom];
|
||||
int idTo = YogaConfig.BODY_PARTS[partTo];
|
||||
|
||||
if (points[idFrom] == new Point(-1, -1) || points[idTo] == new Point(-1, -1))
|
||||
continue;
|
||||
|
||||
if (points[idFrom] != null && points[idTo] != null)
|
||||
{
|
||||
Imgproc.line(img, points[idFrom], points[idTo], new Scalar(0, 255, 0), 3);
|
||||
Imgproc.ellipse(img, points[idFrom], new Size(3, 3), 0, 0, 360, new Scalar(0, 0, 255), Core.FILLED);
|
||||
Imgproc.ellipse(img, points[idTo], new Size(3, 3), 0, 0, 360, new Scalar(0, 0, 255), Core.FILLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#endif
|
||||
Utils.matToTexture2D(img, texture);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator ObjectEstimation(Mat rgbaMat)
|
||||
private void EstimateAction(params object[] args)
|
||||
{
|
||||
if (!_webCamTextureToMatHelper.IsPlaying() || !_webCamTextureToMatHelper.DidUpdateThisFrame())
|
||||
yield break;
|
||||
//开启动作检测
|
||||
var type = args.FirstOrDefault();
|
||||
if (type == null)
|
||||
{
|
||||
Debug.LogError("EstimateAction type is null");
|
||||
return;
|
||||
}
|
||||
AvatarAction actionType = (AvatarAction)args.FirstOrDefault();
|
||||
ObjectEstimation(actionType);
|
||||
}
|
||||
private void ObjectEstimation(AvatarAction actionType)
|
||||
{
|
||||
Debug.LogWarning("Start Estimation");
|
||||
Mat rgbaMat = _rgbaMat;
|
||||
if (rgbaMat == null)
|
||||
{
|
||||
Debug.LogWarning("WebCamTexture is null. ");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_objectDetector == null)
|
||||
yield break;
|
||||
{
|
||||
Debug.LogWarning("ObjectDetector is not ready. ");
|
||||
return;
|
||||
}
|
||||
|
||||
Imgproc.cvtColor(rgbaMat, _bgrMat, Imgproc.COLOR_RGBA2BGR);
|
||||
Mat results = _objectDetector.infer(_bgrMat);
|
||||
|
||||
var voloResultBox = new List<float[]>();
|
||||
|
||||
for (int i = results.rows() - 1; i >= 0; --i)
|
||||
{
|
||||
|
@ -213,34 +217,20 @@ namespace Yoga
|
|||
float[] cls = new float[1];
|
||||
results.get(i, 5, cls); //类别
|
||||
|
||||
var rectResult = new List<float[]>() { box, conf, cls };
|
||||
|
||||
if (CheckResults(box, conf, cls, rgbaMat))
|
||||
if (IsObjectValid(box, conf, cls, rgbaMat))
|
||||
{
|
||||
_voloResult.Clear();
|
||||
_voloResult.Add(box);
|
||||
_voloResult.Add(conf);
|
||||
_voloResult.Add(cls);
|
||||
voloResultBox.Clear();
|
||||
voloResultBox.Add(box);
|
||||
voloResultBox.Add(conf);
|
||||
voloResultBox.Add(cls);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_actionEstimation != null)
|
||||
StopCoroutine(_actionEstimation);
|
||||
_actionEstimation = StartCoroutine(ActionEstimation(rgbaMat));
|
||||
}
|
||||
|
||||
private IEnumerator ActionEstimation(Mat rgbaMat)
|
||||
{
|
||||
if (!_webCamTextureToMatHelper.IsPlaying() || !_webCamTextureToMatHelper.DidUpdateThisFrame())
|
||||
yield break;
|
||||
|
||||
if (_voloResult == null)
|
||||
yield break;
|
||||
|
||||
var box = _voloResult[0];
|
||||
//对人体进行姿态检测
|
||||
OpenCVForUnity.CoreModule.Rect rect = new OpenCVForUnity.CoreModule.Rect((int)box[0], (int)box[1], (int)(box[2] - box[0]), (int)(box[3] - box[1]));
|
||||
//对人体进行姿态检测
|
||||
Debug.LogWarning("Start Body Estimation");
|
||||
_voloResult = voloResultBox;
|
||||
OpenCVForUnity.CoreModule.Rect rect = new OpenCVForUnity.CoreModule.Rect((int)voloResultBox[0][0], (int)voloResultBox[0][1], (int)(voloResultBox[0][2] - voloResultBox[0][0]), (int)(voloResultBox[0][3] - voloResultBox[0][1]));
|
||||
Mat personRectImg = new Mat(_bgrMat, rect);//获取人体区域
|
||||
|
||||
_personPoints = _openPoseModel.estimate(personRectImg, (float)threshold).toList();
|
||||
|
@ -256,12 +246,17 @@ namespace Yoga
|
|||
_personPoints[j].y += rect.y;
|
||||
}
|
||||
|
||||
//打印所有点
|
||||
for (int i = 0; i < _personPoints.Count; i++)
|
||||
{
|
||||
Debug.LogWarning("point " + i + " " + _personPoints[i]);
|
||||
}
|
||||
|
||||
//检测动作
|
||||
//YogaManager.Instance.ProcessPoints(_personPoints);
|
||||
_isCorrectAction = (_isCorrectAction || YogaManager.Instance.IsCorrectAction(_personPoints, actionType));
|
||||
}
|
||||
|
||||
|
||||
private bool CheckResults(float[] box, float[] confidence, float[] classID, Mat rgbaMat)
|
||||
private bool IsObjectValid(float[] box, float[] confidence, float[] classID, Mat rgbaMat)
|
||||
{
|
||||
if ((int)classID[0] != 0 || confidence[0] < 0.8f) //只检测人体,且置信度大于80%
|
||||
return false;
|
||||
|
@ -315,15 +310,11 @@ namespace Yoga
|
|||
{
|
||||
_webCamTextureToMatHelper.Dispose();
|
||||
|
||||
|
||||
if (_net != null)
|
||||
_net.Dispose();
|
||||
|
||||
_bgrMat.Dispose();
|
||||
|
||||
//删除已加载的各种模型
|
||||
_models.Clear();
|
||||
//YogaManager.Instance.Dispose();
|
||||
}
|
||||
|
||||
public void OnWebCamTextureToMatHelperInitialized()
|
||||
|
@ -381,6 +372,7 @@ namespace Yoga
|
|||
|
||||
private bool _isCorrectAction = false;
|
||||
private int _maxActionCount = 3;
|
||||
private Mat _rgbaMat;
|
||||
|
||||
public void ScoreUpdate()
|
||||
{
|
||||
|
@ -403,6 +395,8 @@ namespace Yoga
|
|||
{
|
||||
EventManager.Instance.Dispatch("ActionFailed");
|
||||
}
|
||||
|
||||
_isCorrectAction = false;//重置
|
||||
YogaManager.Instance.CurrentActionCount++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,18 +6,7 @@ using UnityEngine;
|
|||
|
||||
public abstract class PoseBase
|
||||
{
|
||||
public ModelType ModelName { get; internal set; }
|
||||
|
||||
public abstract bool CheckPose(List<Point> points);
|
||||
public abstract void ProcessSuccessCallBack(Action callback);
|
||||
public abstract void ProcessFailCallBack();
|
||||
|
||||
public abstract void ShowHint();
|
||||
|
||||
public PoseBase(ModelType name)
|
||||
{
|
||||
ModelName = name;
|
||||
}
|
||||
|
||||
public Dictionary<string, Point> GetVaildPoints(List<Point> points, List<string> pointName)
|
||||
{
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ShowHintUIController : MonoBehaviour
|
||||
{
|
||||
private void OnEnable()
|
||||
{
|
||||
YogaManager.Instance.ShowHint -= ShowHint;
|
||||
YogaManager.Instance.ShowHint += ShowHint;
|
||||
}
|
||||
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
YogaManager.Instance.ShowHint -= ShowHint;
|
||||
}
|
||||
private void ShowHint(string hintText)
|
||||
{
|
||||
this.GetComponent<Text>().text = hintText;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8d1cb71f907bfec429b9020e43438c62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -84,6 +84,7 @@ public class GuideUI : UIPanelBase
|
|||
{
|
||||
base.OnEnter();
|
||||
_guide.SetActive(true);
|
||||
EventManager.Instance.Dispatch("StartMotionCapture");
|
||||
EventManager.Instance.Dispatch("PlayAnimation", AvatarAction.HeadTurnLeft);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,100 +12,40 @@ using UnityEngine;
|
|||
|
||||
public class YogaManager : MonoSingleton<YogaManager>
|
||||
{
|
||||
private bool _isInited = false;
|
||||
private LinkedList<PoseBase> _poseChecks = new LinkedList<PoseBase>();
|
||||
private PoseBase _currPose = null;
|
||||
|
||||
private double threshold = 0.1;
|
||||
private List<Point> _points = new List<Point>();
|
||||
|
||||
|
||||
|
||||
public List<Point> Points { get => _points; private set => _points = value; }
|
||||
|
||||
public Action<string> UpdateStatus { get; internal set; }
|
||||
|
||||
public Action<string> ShowHint { get; internal set; }
|
||||
public int ActionIndex { get; internal set; }
|
||||
private int _currentActionCount; //当前动作计数
|
||||
public int CurrentActionCount { get => _currentActionCount; internal set => _currentActionCount = value; }
|
||||
public int CurrentSuccessActionCount { get => _currentSuccessActionCount; internal set => _currentSuccessActionCount = value; }
|
||||
|
||||
//创建帧数据缓存
|
||||
private Dictionary<int, List<List<Point>>> _framePoints = new (); // actionID, frameID, points
|
||||
private int _currActionID;
|
||||
private int _currentActionCount;
|
||||
private int _currentSuccessActionCount;
|
||||
private int _currentSuccessActionCount; //当前成功动作计数
|
||||
public int CurrentSuccessActionCount { get => _currentSuccessActionCount; internal set => _currentSuccessActionCount = value; }
|
||||
|
||||
private int _actionIndex; //用户选择界面选择的动作索引
|
||||
public int ActionIndex { get => _actionIndex; internal set => _actionIndex = value; }
|
||||
|
||||
private Dictionary<AvatarAction, PoseBase> _actions = new Dictionary<AvatarAction, PoseBase>();
|
||||
|
||||
|
||||
public void InitData()
|
||||
{
|
||||
_poseChecks.AddFirst(new IsReady(ModelType.OpenPose));
|
||||
_poseChecks.AddLast(new HeadTurnLeft(ModelType.OpenPose));
|
||||
_poseChecks.AddLast(new HeadTurnRight(ModelType.OpenPose));
|
||||
_actions[AvatarAction.HeadTurnLeft] = new HeadTurnLeft();
|
||||
_actions[AvatarAction.HeadTurnRight] = new HeadTurnRight();
|
||||
|
||||
ShowHint?.Invoke(string.Empty);
|
||||
UpdateStatus?.Invoke(string.Empty);
|
||||
_currPose = _poseChecks.First.Value;
|
||||
_currPose.ShowHint();
|
||||
_currActionID = 0;
|
||||
_isInited = true;
|
||||
_currentActionCount = 0;
|
||||
_currentSuccessActionCount = 0;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public bool IsCorrectAction(List<Point> personPoints, AvatarAction actionType)
|
||||
{
|
||||
_currPose = null;
|
||||
|
||||
UpdateStatus = null;
|
||||
_isInited = false;
|
||||
_poseChecks.Clear();
|
||||
}
|
||||
|
||||
|
||||
public List<Point> Process(Mat img, Dictionary<ModelType, KeypointsModel> models)
|
||||
{
|
||||
List<Point> points = models[_currPose.ModelName].estimate(img, (float)threshold).toList();
|
||||
//_framePoints[_currActionID].Add(points);
|
||||
ProcessPoints(points);
|
||||
return points;
|
||||
}
|
||||
|
||||
public void ProcessPoints(List<Point> points)
|
||||
{
|
||||
if (!_isInited)
|
||||
if (!_actions.ContainsKey(actionType))
|
||||
{
|
||||
InitData();
|
||||
Debug.LogError("ActionType is not exist");
|
||||
return false;
|
||||
}
|
||||
Points = points;
|
||||
|
||||
if (_currPose == null)
|
||||
{
|
||||
_currPose = _poseChecks.First.Value;
|
||||
_currPose.ShowHint();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currPose.CheckPose(points))
|
||||
{
|
||||
_currPose.ProcessSuccessCallBack(() =>
|
||||
{
|
||||
SwitchNextPost();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_currPose.ProcessFailCallBack();
|
||||
}
|
||||
}
|
||||
|
||||
private void SwitchNextPost()
|
||||
{
|
||||
if (_currPose == _poseChecks.Last.Value)
|
||||
{
|
||||
Dispose();
|
||||
return;
|
||||
}
|
||||
_currPose = _poseChecks.Find(_currPose).Next.Value;
|
||||
_currPose.ShowHint();
|
||||
var result = _actions[actionType].CheckPose(personPoints);
|
||||
Debug.LogWarning("ActionType: " + actionType + " result: " + result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue