Files
Speykious d562895694 Rewrite solutions (#33)
* Add paths for Linux in BlazePose example

* Add BlazePose example to VSCode debug launchers

* Use `pose_landmark` instead of `pose_tracking_*`

* Pluralize `SidePacket`

The correct way to call it is actually `SidePackets`,
as it is internally a `map<string, Packet>`.

* Little XML doc

* Consolidate `StartRun` method parameters

* Add `SidePackets` property to `Calculator`

* Add side packet arguments to `BlazePose`

* Use the `pose_tracking` graph

Let's try specifying side packets there instead.

* Use asynchronous SeeShark frame input

Looks like that doesn't fix the FPS...

* Remove unnecessary `unsafe`

* Better error handling in example program

* Uncomment additional SidePacket

* Implement new Packet API

* Rename `Packet` namespace to `OldPacket`

* Rename `NewPacket` namespace to `Packet`

* Actually, `Packets` is better...

* Delete old Packet API

* Replace Calculators with Solutions

Solutions are written in a way to imitate the
MediaPipe Python API as much as possible.

* Remove Old Packet API tests

* Fix remaining tests

* No more `SignalAbort` :0

* Revert "No more `SignalAbort` :0"

This reverts commit dd63b53fb53590560188d652346130ff31c74c62.

* Create `FaceMeshCpuSolution`

* Add interface

* Temporarily remove non-compiling example projects

* This solution produces segfaults...

* Create `PacketType` enum

Store packet outputs instead of packets in solution
No segfault now :D

* Use an `IDictionary` for outputs

* Create a `Hands` example

* Hand tracking is 10 times slower...

* No threading T-T

* Add `FaceMeshGpu` solution

* Avoid `free(): invalid pointer` error

* Implement `HandsGpu` solution

It works perfectly fine :D

* Start reimplementing Pose example

* Pose landmarks CPU (it's very slow)

* Just correcting some things in the examples

* Implement `PoseGpuSolution` (it's decently fast)

* `OsuFrameworkVisualTests` example works too

Though we need a way to make solutions multithreaded.

* Attempt at thread-safe `Solution` implementation

* There is no thread-safe solution. :')

This reverts commit 6e9ccca3deebf3ca74ed25c41e619c07c5febd94.

* Fix duplicate project in solution

How the fuck did that happen???
2022-07-25 23:53:06 +08:00

118 lines
4.0 KiB
C#

// Copyright (c) homuler and The Vignette Authors
// This file is part of MediaPipe.NET.
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
using System;
using CommandLine;
using FFmpeg.AutoGen;
using Mediapipe.Net.External;
using Mediapipe.Net.Framework.Format;
using Mediapipe.Net.Solutions;
using Mediapipe.Net.Util;
using SeeShark;
using SeeShark.Device;
using SeeShark.FFmpeg;
namespace Mediapipe.Net.Examples.Pose
{
public static class Program
{
private static Camera? camera;
private static FrameConverter? converter;
private static readonly PoseCpuSolution calculator =
new PoseCpuSolution(modelComplexity: 2, smoothLandmarks: false);
private static ResourceManager? resourceManager;
public static void Main(string[] args)
{
// Get and parse command line arguments
Options parsed = Parser.Default.ParseArguments<Options>(args).Value;
(int, int)? videoSize = null;
if (parsed.Width != null && parsed.Height != null)
videoSize = ((int)parsed.Width, (int)parsed.Height);
else if (parsed.Width != null && parsed.Height == null)
Console.Error.WriteLine("Specifying width requires to specify height");
else if (parsed.Width == null && parsed.Height != null)
Console.Error.WriteLine("Specifying height requires to specify width");
FFmpegManager.SetupFFmpeg(@"C:\ffmpeg\v5.0_x64\", @"/usr/lib");
Glog.Initialize("stuff");
if (parsed.UseResourceManager)
resourceManager = new DummyResourceManager();
// Get a camera device
using (CameraManager manager = new CameraManager())
{
try
{
camera = manager.GetDevice(parsed.CameraIndex,
new VideoInputOptions
{
InputFormat = parsed.InputFormat,
Framerate = parsed.Framerate == null ? null : new AVRational
{
num = (int)parsed.Framerate,
den = 1,
},
VideoSize = videoSize,
});
Console.WriteLine($"Using camera {camera.Info}");
}
catch (Exception)
{
Console.Error.WriteLine($"No camera exists at index {parsed.CameraIndex}.");
return;
}
}
camera.OnFrame += onFrameEventHandler;
camera.StartCapture();
Console.CancelKeyPress += (sender, eventArgs) => exit();
}
private static int frameCount = 0;
private static void onFrameEventHandler(object? sender, FrameEventArgs e)
{
if (calculator == null)
return;
Frame frame = e.Frame;
if (frame.Width == 0 || frame.Height == 0)
return;
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
Frame cFrame = converter.Convert(frame);
ImageFrame imgframe = new ImageFrame(ImageFormat.Srgba,
cFrame.Width, cFrame.Height, cFrame.WidthStep, cFrame.RawData);
PoseOutput handsOutput = calculator.Compute(imgframe);
if (handsOutput.PoseLandmarks != null)
{
var landmarks = handsOutput.PoseLandmarks.Landmark;
Console.WriteLine($"Got pose output with {landmarks.Count} landmarks"
+ $" at frame {frameCount}");
}
else
{
Console.WriteLine("No pose landmarks");
}
frameCount++;
}
// Dispose everything on exit
private static void exit()
{
Console.WriteLine("Exiting...");
camera?.Dispose();
converter?.Dispose();
calculator?.Dispose();
}
}
}