using System.Collections.Generic;
using System.Linq;
namespace MMDeploy
{
#pragma warning disable 0649
internal unsafe struct CPoseDetect
{
public Pointf* Point;
public float* Score;
public int Length;
}
#pragma warning restore 0649
///
/// Single detection result of a bbox.
/// A picture may contains multiple reuslts.
///
public struct PoseDetect
{
///
/// Keypoins.
///
public List Points;
///
/// Scores.
///
public List Scores;
///
/// Init points and scores if empty.
///
private void Init()
{
if (Points == null || Scores == null)
{
Points = new List();
Scores = new List();
}
}
///
/// Add single keypoint to list.
///
/// Keypoint.
/// Score.
public void Add(Pointf point, float score)
{
Init();
Points.Add(point);
Scores.Add(score);
}
internal unsafe void Add(Pointf* point, float score)
{
Init();
Points.Add(new Pointf(point->X, point->Y));
}
}
///
/// Output of PoseDetector.
///
public struct PoseDetectorOutput
{
///
/// Pose detection results for single image.
///
public List Results;
///
/// Gets number of output.
///
public int Count
{
get { return (Results == null) ? 0 : Results.Count; }
}
///
/// Result for box level.
///
/// Box res.
public void Add(PoseDetect boxRes)
{
if (Results == null)
{
Results = new List();
}
Results.Add(boxRes);
}
}
///
/// PoseDetector.
///
public class PoseDetector : DisposableObject
{
///
/// Initializes a new instance of the class.
///
/// model path.
/// device name.
/// device id.
public PoseDetector(string modelPath, string deviceName, int deviceId)
{
ThrowException(NativeMethods.mmdeploy_pose_detector_create_by_path(modelPath, deviceName, deviceId, out _handle));
}
///
/// Get information of each image in a batch.
///
/// input mats.
/// bounding boxes..
/// bounding boxes count for each image.
/// Results of each input mat.
public List Apply(Mat[] mats, Rect[] bboxes, int[] bboxCount)
{
List output = new List();
unsafe
{
CPoseDetect* results = null;
fixed (Mat* _mats = mats)
fixed (Rect* _bboxes = bboxes)
fixed (int* _bboxCount = bboxCount)
{
ThrowException(NativeMethods.mmdeploy_pose_detector_apply_bbox(_handle, _mats, mats.Length, _bboxes, _bboxCount, &results));
FormatResult(mats.Length, _bboxCount, results, ref output, out var total);
ReleaseResult(results, total);
}
}
return output;
}
///
/// Get information of each image in a batch.
///
/// Input mats.
/// Results of each input mat.
public List Apply(Mat[] mats)
{
List output = new List();
unsafe
{
CPoseDetect* results = null;
fixed (Mat* _mats = mats)
{
ThrowException(NativeMethods.mmdeploy_pose_detector_apply(_handle, _mats, mats.Length, &results));
}
int[] _bbox_count = Enumerable.Repeat(1, mats.Length).ToArray();
fixed (int* bbox_count = _bbox_count)
{
FormatResult(mats.Length, bbox_count, results, ref output, out var total);
ReleaseResult(results, total);
}
}
return output;
}
private unsafe void FormatResult(int matCount, int* bboxCount, CPoseDetect* results, ref List output, out int total)
{
total = 0;
for (int i = 0; i < matCount; i++)
{
PoseDetectorOutput outi = default;
for (int j = 0; j < bboxCount[i]; j++)
{
PoseDetect boxRes = default;
for (int k = 0; k < results->Length; k++)
{
boxRes.Add(results->Point[k], results->Score[k]);
}
outi.Add(boxRes);
results++;
total++;
}
output.Add(outi);
}
}
private unsafe void ReleaseResult(CPoseDetect* results, int count)
{
NativeMethods.mmdeploy_pose_detector_release_result(results, count);
}
///
protected override void ReleaseHandle()
{
NativeMethods.mmdeploy_pose_detector_destroy(_handle);
}
}
}