Skip to content

Commit

Permalink
feat: add FaceDetector sample (#975)
Browse files Browse the repository at this point in the history
* chore: remove unused directories

* refactor: dispose Timestamp

* feat: FaceDetector Sample

* feat: transform the input image properly

* test: add ImageTransformationOptions tests

* chore: rename elements in prefab

* feat: switch delegate at runtime

* refactor: make VisionTaskApiRunner generic

* refactor: rename FaceDetectorSample to FaceDetectorRunner

* ci: set timeout for the license activation step
  • Loading branch information
homuler committed Aug 6, 2023
1 parent 074c29f commit a3af2d8
Show file tree
Hide file tree
Showing 38 changed files with 8,486 additions and 39 deletions.
1 change: 1 addition & 0 deletions .github/workflows/windows-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ jobs:
{
exit $process.ExitCode
}
timeout-minutes: 1

- name: Download built artifacts
uses: actions/download-artifact@v3
Expand Down
37 changes: 37 additions & 0 deletions Assets/MediaPipeUnity/Samples/Common/Scripts/EnumExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) 2023 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

using System;
using System.ComponentModel;

namespace Mediapipe.Unity.Sample
{
public static class EnumExtension
{
public static string GetDescription(this Enum value)
{
var type = value.GetType();
var name = Enum.GetName(type, value);
if (name == null)
{
return null;
}

var field = type.GetField(name);
if (field == null)
{
return null;
}

var attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
if (attr is DescriptionAttribute descriptionAttribute)
{
return descriptionAttribute.Description;
}
return null;
}
}
}
11 changes: 11 additions & 0 deletions Assets/MediaPipeUnity/Samples/Common/Scripts/EnumExtension.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2023 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

namespace Mediapipe.Unity.Sample
{
public readonly struct ImageTransformationOptions
{
public readonly bool flipHorizontally;
public readonly bool flipVertically;
public readonly RotationAngle rotationAngle;

private ImageTransformationOptions(bool flipHorizontally, bool flipVertically, RotationAngle rotationAngle)
{
this.flipHorizontally = flipHorizontally;
this.flipVertically = flipVertically;
this.rotationAngle = rotationAngle;
}

public static ImageTransformationOptions Build(bool shouldFlipHorizontally, bool isVerticallyFlipped, RotationAngle rotation)
{
var isInverted = CoordinateSystem.ImageCoordinate.IsInverted(rotation);
var flipHorizontally = !isInverted && shouldFlipHorizontally;
var flipVertically = !shouldFlipHorizontally ? !isVerticallyFlipped : isInverted ? isVerticallyFlipped : !isVerticallyFlipped;

return new ImageTransformationOptions(flipHorizontally, flipVertically, rotation);
}
}

public static class ImageSourceExtension
{
public static ImageTransformationOptions GetTransformationOptions(this ImageSource imageSource, bool expectedToBeMirrored = false)
{
var shouldFlipHorizontally = (imageSource.isFrontFacing || expectedToBeMirrored) ^ imageSource.isHorizontallyFlipped;
var shouldFlipVertically = imageSource.isVerticallyFlipped;
return ImageTransformationOptions.Build(shouldFlipHorizontally, shouldFlipVertically, imageSource.rotation);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Assets/MediaPipeUnity/Samples/Common/Scripts/Screen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class Screen : MonoBehaviour

public Texture texture
{
private get => _screen.texture;
get => _screen.texture;
set => _screen.texture = value;
}

Expand Down
98 changes: 98 additions & 0 deletions Assets/MediaPipeUnity/Samples/Common/Scripts/TaskApiRunner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) 2023 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

using System;
using System.Collections;
using UnityEngine;

using Stopwatch = System.Diagnostics.Stopwatch;

namespace Mediapipe.Unity.Sample
{
public abstract class TaskApiRunner : MonoBehaviour
{
#pragma warning disable IDE1006
// TODO: make it static
protected virtual string TAG => GetType().Name;
#pragma warning restore IDE1006

public Bootstrap bootstrap;
protected bool isPaused;

private readonly Stopwatch _stopwatch = new();

protected virtual IEnumerator Start()
{
bootstrap = FindBootstrap();
yield return new WaitUntil(() => bootstrap.isFinished);

Play();
}

/// <summary>
/// Start the main program from the beginning.
/// </summary>
public virtual void Play()
{
isPaused = false;
_stopwatch.Restart();
}

/// <summary>
/// Pause the main program.
/// <summary>
public virtual void Pause()
{
isPaused = true;
}

/// <summary>
/// Resume the main program.
/// If the main program has not begun, it'll do nothing.
/// </summary>
public virtual void Resume()
{
isPaused = false;
}

/// <summary>
/// Stops the main program.
/// </summary>
public virtual void Stop()
{
isPaused = true;
_stopwatch.Stop();
}

protected long GetCurrentTimestampMillisec() => _stopwatch.IsRunning ? _stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond : -1;

protected Bootstrap FindBootstrap()
{
var bootstrapObj = GameObject.Find("Bootstrap");

if (bootstrapObj != null)
{
return bootstrapObj.GetComponent<Bootstrap>();
}

Logger.LogWarning(TAG, "Global Bootstrap instance is not found (maybe running a sample scene directly), "
+ "so activating a fallback Bootstrap instance attached to each Solution object");

var bootstrap = GetComponent<Bootstrap>();
bootstrap.enabled = true;

// hide menu button when trying a single scene.
DisableMenuButton();
return bootstrap;
}

private void DisableMenuButton()
{
var menuButton = GameObject.Find("MenuButton");
menuButton.SetActive(false);
}
}
}
11 changes: 11 additions & 0 deletions Assets/MediaPipeUnity/Samples/Common/Scripts/TaskApiRunner.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2021 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

using System.Collections;
using UnityEngine;

namespace Mediapipe.Unity.Sample
{
public abstract class VisionTaskApiRunner<TTask> : TaskApiRunner where TTask : Tasks.Vision.Core.BaseVisionTaskApi
{
[SerializeField] protected Screen screen;

private Coroutine _coroutine;
protected TTask taskApi;

public RunningMode runningMode;

public override void Play()
{
if (_coroutine != null)
{
Stop();
}
base.Play();
_coroutine = StartCoroutine(Run());
}

public override void Pause()
{
base.Pause();
ImageSourceProvider.ImageSource.Pause();
}

public override void Resume()
{
base.Resume();
var _ = StartCoroutine(ImageSourceProvider.ImageSource.Resume());
}

public override void Stop()
{
base.Stop();
StopCoroutine(_coroutine);
ImageSourceProvider.ImageSource.Stop();
taskApi?.Close();
taskApi = null;
}

protected abstract IEnumerator Run();

protected static void SetupAnnotationController<T>(AnnotationController<T> annotationController, ImageSource imageSource, bool expectedToBeMirrored = false) where T : HierarchicalAnnotation
{
annotationController.isMirrored = expectedToBeMirrored;
annotationController.imageSize = new Vector2Int(imageSource.textureWidth, imageSource.textureHeight);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions Assets/MediaPipeUnity/Samples/Mediapipe.Unity.Sample.asmdef
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Mediapipe.Unity.Sample",
"rootNamespace": "",
"references": [
"GUID:04c4d86a70aa56c55a78c61f1ab1a56d"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a3af2d8

Please sign in to comment.