Skip to content

Commit 2c1fd5e

Browse files
committed
face blendhapes support
1 parent f811ad3 commit 2c1fd5e

File tree

13 files changed

+2331
-6
lines changed

13 files changed

+2331
-6
lines changed

Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/Face Blendshapes.unity

Lines changed: 1351 additions & 0 deletions
Large diffs are not rendered by default.

Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/Face Blendshapes.unity.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshGraph.cs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class FaceMeshGraph : GraphRunner
1717
{
1818
public int maxNumFaces = 1;
1919
public bool refineLandmarks = true;
20+
public bool blenshapes = false;
2021

2122
private float _minDetectionConfidence = 0.5f;
2223
public float minDetectionConfidence
@@ -56,17 +57,26 @@ public event EventHandler<OutputEventArgs<List<NormalizedRect>>> OnFaceRectsFrom
5657
remove => _faceRectsFromDetectionsStream.RemoveListener(value);
5758
}
5859

60+
public event EventHandler<OutputEventArgs<ClassificationList>> OnFaceClassificationsFromBlendShapesOutput
61+
{
62+
add => _faceBlendShapesStream?.AddListener(value);
63+
remove => _faceBlendShapesStream?.RemoveListener(value);
64+
}
65+
5966
private const string _InputStreamName = "input_video";
6067

6168
private const string _FaceDetectionsStreamName = "face_detections";
6269
private const string _MultiFaceLandmarksStreamName = "multi_face_landmarks";
6370
private const string _FaceRectsFromLandmarksStreamName = "face_rects_from_landmarks";
6471
private const string _FaceRectsFromDetectionsStreamName = "face_rects_from_detections";
72+
private const string _FaceBlendShapesStreamName = "blendshapes";
6573

6674
private OutputStream<DetectionVectorPacket, List<Detection>> _faceDetectionsStream;
6775
private OutputStream<NormalizedLandmarkListVectorPacket, List<NormalizedLandmarkList>> _multiFaceLandmarksStream;
6876
private OutputStream<NormalizedRectVectorPacket, List<NormalizedRect>> _faceRectsFromLandmarksStream;
6977
private OutputStream<NormalizedRectVectorPacket, List<NormalizedRect>> _faceRectsFromDetectionsStream;
78+
private OutputStream<ClassificationListPacket, ClassificationList> _faceBlendShapesStream;
79+
7080

7181
public override void StartRun(ImageSource imageSource)
7282
{
@@ -76,6 +86,8 @@ public override void StartRun(ImageSource imageSource)
7686
_multiFaceLandmarksStream.StartPolling().AssertOk();
7787
_faceRectsFromLandmarksStream.StartPolling().AssertOk();
7888
_faceRectsFromDetectionsStream.StartPolling().AssertOk();
89+
if (blenshapes)
90+
_faceBlendShapesStream.StartPolling().AssertOk();
7991
}
8092
StartRun(BuildSidePacket(imageSource));
8193
}
@@ -90,6 +102,8 @@ public override void Stop()
90102
_faceRectsFromLandmarksStream = null;
91103
_faceRectsFromDetectionsStream?.Close();
92104
_faceRectsFromDetectionsStream = null;
105+
_faceBlendShapesStream?.Close();
106+
_faceBlendShapesStream = null;
93107
base.Stop();
94108
}
95109

@@ -99,15 +113,23 @@ public void AddTextureFrameToInputStream(TextureFrame textureFrame)
99113
}
100114

101115
public bool TryGetNext(out List<Detection> faceDetections, out List<NormalizedLandmarkList> multiFaceLandmarks,
102-
out List<NormalizedRect> faceRectsFromLandmarks, out List<NormalizedRect> faceRectsFromDetections, bool allowBlock = true)
116+
out List<NormalizedRect> faceRectsFromLandmarks, out List<NormalizedRect> faceRectsFromDetections, out ClassificationList faceBlendShapes, bool allowBlock = true)
103117
{
104118
var currentTimestampMicrosec = GetCurrentTimestampMicrosec();
105119
var r1 = TryGetNext(_faceDetectionsStream, out faceDetections, allowBlock, currentTimestampMicrosec);
106120
var r2 = TryGetNext(_multiFaceLandmarksStream, out multiFaceLandmarks, allowBlock, currentTimestampMicrosec);
107121
var r3 = TryGetNext(_faceRectsFromLandmarksStream, out faceRectsFromLandmarks, allowBlock, currentTimestampMicrosec);
108122
var r4 = TryGetNext(_faceRectsFromDetectionsStream, out faceRectsFromDetections, allowBlock, currentTimestampMicrosec);
109-
110-
return r1 || r2 || r3 || r4;
123+
if (blenshapes)
124+
{
125+
var r5 = TryGetNext(_faceBlendShapesStream, out faceBlendShapes, allowBlock, currentTimestampMicrosec);
126+
return r1 || r2 || r3 || r4 || r5;
127+
}
128+
else
129+
{
130+
faceBlendShapes = null;
131+
return r1 || r2 || r3 || r4;
132+
}
111133
}
112134

113135
protected override Status ConfigureCalculatorGraph(CalculatorGraphConfig config)
@@ -122,13 +144,18 @@ protected override Status ConfigureCalculatorGraph(CalculatorGraphConfig config)
122144
calculatorGraph, _FaceRectsFromLandmarksStreamName, config.AddPacketPresenceCalculator(_FaceRectsFromLandmarksStreamName), timeoutMicrosec);
123145
_faceRectsFromDetectionsStream = new OutputStream<NormalizedRectVectorPacket, List<NormalizedRect>>(
124146
calculatorGraph, _FaceRectsFromDetectionsStreamName, config.AddPacketPresenceCalculator(_FaceDetectionsStreamName), timeoutMicrosec);
147+
if (blenshapes)
148+
_faceBlendShapesStream = new OutputStream<ClassificationListPacket, ClassificationList>(
149+
calculatorGraph, _FaceBlendShapesStreamName, config.AddPacketPresenceCalculator(_FaceBlendShapesStreamName), timeoutMicrosec);
125150
}
126151
else
127152
{
128153
_faceDetectionsStream = new OutputStream<DetectionVectorPacket, List<Detection>>(calculatorGraph, _FaceDetectionsStreamName, true, timeoutMicrosec);
129154
_multiFaceLandmarksStream = new OutputStream<NormalizedLandmarkListVectorPacket, List<NormalizedLandmarkList>>(calculatorGraph, _MultiFaceLandmarksStreamName, true, timeoutMicrosec);
130155
_faceRectsFromLandmarksStream = new OutputStream<NormalizedRectVectorPacket, List<NormalizedRect>>(calculatorGraph, _FaceRectsFromLandmarksStreamName, true, timeoutMicrosec);
131156
_faceRectsFromDetectionsStream = new OutputStream<NormalizedRectVectorPacket, List<NormalizedRect>>(calculatorGraph, _FaceRectsFromDetectionsStreamName, true, timeoutMicrosec);
157+
if (blenshapes)
158+
_faceBlendShapesStream = new OutputStream<ClassificationListPacket, ClassificationList>(calculatorGraph, _FaceBlendShapesStreamName, true, timeoutMicrosec);
132159
}
133160

134161
using (var validatedGraphConfig = new ValidatedGraphConfig())
@@ -174,10 +201,13 @@ protected override Status ConfigureCalculatorGraph(CalculatorGraphConfig config)
174201

175202
protected override IList<WaitForResult> RequestDependentAssets()
176203
{
177-
return new List<WaitForResult> {
204+
var ret = new List<WaitForResult> {
178205
WaitForAsset("face_detection_short_range.bytes"),
179206
WaitForAsset(refineLandmarks ? "face_landmark_with_attention.bytes" : "face_landmark.bytes"),
180207
};
208+
if (blenshapes)
209+
ret.Add(WaitForAsset("face_blendshapes.bytes"));
210+
return ret;
181211
}
182212

183213
private SidePacket BuildSidePacket(ImageSource imageSource)

Assets/MediaPipeUnity/Samples/Scenes/Face Mesh/FaceMeshSolution.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ protected override void OnStartRun()
4949
graphRunner.OnMultiFaceLandmarksOutput += OnMultiFaceLandmarksOutput;
5050
graphRunner.OnFaceRectsFromLandmarksOutput += OnFaceRectsFromLandmarksOutput;
5151
graphRunner.OnFaceRectsFromDetectionsOutput += OnFaceRectsFromDetectionsOutput;
52+
graphRunner.OnFaceClassificationsFromBlendShapesOutput += OnFaceClassificationsFromBlendShapesOutput;
5253
}
5354

5455
var imageSource = ImageSourceProvider.ImageSource;
@@ -69,20 +70,23 @@ protected override IEnumerator WaitForNextValue()
6970
List<NormalizedLandmarkList> multiFaceLandmarks = null;
7071
List<NormalizedRect> faceRectsFromLandmarks = null;
7172
List<NormalizedRect> faceRectsFromDetections = null;
73+
ClassificationList faceBlendShapes = null;
7274

7375
if (runningMode == RunningMode.Sync)
7476
{
75-
var _ = graphRunner.TryGetNext(out faceDetections, out multiFaceLandmarks, out faceRectsFromLandmarks, out faceRectsFromDetections, true);
77+
var _ = graphRunner.TryGetNext(out faceDetections, out multiFaceLandmarks, out faceRectsFromLandmarks, out faceRectsFromDetections, out faceBlendShapes, true);
7678
}
7779
else if (runningMode == RunningMode.NonBlockingSync)
7880
{
79-
yield return new WaitUntil(() => graphRunner.TryGetNext(out faceDetections, out multiFaceLandmarks, out faceRectsFromLandmarks, out faceRectsFromDetections, false));
81+
yield return new WaitUntil(() => graphRunner.TryGetNext(out faceDetections, out multiFaceLandmarks, out faceRectsFromLandmarks, out faceRectsFromDetections, out faceBlendShapes, false));
8082
}
8183

8284
_faceDetectionsAnnotationController.DrawNow(faceDetections);
8385
_multiFaceLandmarksAnnotationController.DrawNow(multiFaceLandmarks);
8486
_faceRectsFromLandmarksAnnotationController.DrawNow(faceRectsFromLandmarks);
8587
_faceRectsFromDetectionsAnnotationController.DrawNow(faceRectsFromDetections);
88+
if (faceBlendShapes != null)
89+
Debug.Log($"Blendshapes count {faceBlendShapes.Classification.Count}");
8690
}
8791

8892
private void OnFaceDetectionsOutput(object stream, OutputEventArgs<List<Detection>> eventArgs)
@@ -104,5 +108,10 @@ private void OnFaceRectsFromDetectionsOutput(object stream, OutputEventArgs<List
104108
{
105109
_faceRectsFromDetectionsAnnotationController.DrawLater(eventArgs.value);
106110
}
111+
112+
private void OnFaceClassificationsFromBlendShapesOutput(object stream, OutputEventArgs<ClassificationList> eventArgs)
113+
{
114+
Debug.Log($"Blendshapes count {eventArgs.value?.Classification?.Count}");
115+
}
107116
}
108117
}

0 commit comments

Comments
 (0)