/* * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections; using System.Linq; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Threading.Tasks; using InteropInference = Interop.MediaVision.Inference; using Unmanaged = Interop.MediaVision; namespace Tizen.Multimedia.Vision { /// /// Represents a Landmark in pose detection. /// /// 9 public struct Landmark { /// /// Represents a location in the 2D space. /// /// 9 public Point Location { get; set; } /// /// Confidence score of point. /// /// 9 public float Score { get; set; } } /// /// Provides the ability to detect Pose landmarks on image source using inference engine. /// /// 9 public static class PoseLandmarkDetector { /// /// Detects Pose landmarks on the source image using inference engine set in .
///
/// /// To set region-of-interest area in source image, please set . /// If not set, full image area will be used to detect Pose landmark. /// /// http://tizen.org/feature/vision.inference /// http://tizen.org/feature/vision.inference.face /// The source of the media where poses will be detected. /// The engine's configuration that will be used for detecting. /// /// A task that represents the asynchronous detect operation.
///
/// or is null. /// Internal error. /// The feature is not supported. /// The caller has no required privilege. /// /// 9 public static async Task DetectAsync(MediaVisionSource source, InferenceModelConfiguration config) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } var tcs = new TaskCompletionSource(); using (var cb = ObjectKeeper.Get(GetCallback(tcs))) { IntPtr roiUnmanaged = IntPtr.Zero; try { if (config.Roi.HasValue) { var roi = config.Roi.Value.ToMarshalable(); roiUnmanaged = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Unmanaged.Rectangle))); Marshal.WriteIntPtr(roiUnmanaged, IntPtr.Zero); Marshal.StructureToPtr(roi, roiUnmanaged, false); } InteropInference.DetectPoseLandmark(source.Handle, config.GetHandle(), roiUnmanaged, cb.Target). Validate("Failed to detect Pose landmark."); } finally { if (roiUnmanaged != IntPtr.Zero) { Marshal.FreeHGlobal(roiUnmanaged); } } return await tcs.Task; } } private static InteropInference.PoseLandmarkDetectedCallback GetCallback(TaskCompletionSource tcs) { return (IntPtr sourceHandle, IntPtr poses, IntPtr _) => { try { if (!tcs.TrySetResult(GetResults(poses))) { Log.Error(MediaVisionLog.Tag, "Failed to set Pose landmark detection result."); } } catch (Exception e) { tcs.TrySetException(e); } }; } private static Landmark[,] GetResults(IntPtr poses) { int numOfPoses, numOfLandMarks; float score; InteropInference.GetPoseNum(poses, out numOfPoses).Validate("Failed to get number of pose"); InteropInference.GetLandmarkNum(poses, out numOfLandMarks).Validate("Failed to get number of landmark"); Unmanaged.Point location = new Unmanaged.Point(); Landmark[,] results = new Landmark[numOfPoses, numOfLandMarks]; for (int np = 0; np < numOfPoses; np++) { for (int nl = 0; nl < numOfLandMarks; nl++) { InteropInference.GetLandmark(poses, np, nl, out location, out score).Validate("Failed to GetLandmark"); results[np, nl].Score = score; results[np, nl].Location = location.ToApiStruct(); } } return results; } } }