Skip to content

Commit

Permalink
Switching to version 1.0.0 of Body Tracking SDK. Preparations to publ…
Browse files Browse the repository at this point in the history
…ish version 1.3.5 of K4AdotNet library and packages.
  • Loading branch information
bibigone committed Jan 27, 2020
1 parent a8799fa commit 51a9c06
Show file tree
Hide file tree
Showing 22 changed files with 178 additions and 95 deletions.
4 changes: 3 additions & 1 deletion K4AdotNet.Samples.Core.BodyTrackingSpeed/Processor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ protected Processor(ProcessingParameters processingParameters)
if (processingParameters.StartTime.HasValue)
Seek(processingParameters.StartTime.Value);
var config = BodyTracking.TrackerConfiguration.Default;
config.CpuOnlyMode = processingParameters.CpuOnlyMode;
config.ProcessingMode = processingParameters.CpuOnlyMode
? BodyTracking.TrackerProcessingMode.Cpu
: BodyTracking.TrackerProcessingMode.Gpu;
tracker = new BodyTracking.Tracker(ref calibration, config);
}

Expand Down
8 changes: 7 additions & 1 deletion K4AdotNet.Samples.Wpf.BodyTracker/BackgroundTrackingLoop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ internal sealed class BackgroundTrackingLoop : IDisposable

public BackgroundTrackingLoop(ref Calibration calibration, bool cpuOnlyMode, SensorOrientation sensorOrientation, float smoothingFactor)
{
var config = new TrackerConfiguration { SensorOrientation = sensorOrientation, CpuOnlyMode = cpuOnlyMode };
var config = new TrackerConfiguration
{
SensorOrientation = sensorOrientation,
ProcessingMode = cpuOnlyMode
? TrackerProcessingMode.Cpu
: TrackerProcessingMode.Gpu
};
tracker = new Tracker(ref calibration, config) { TemporalSmoothingFactor = smoothingFactor };
isRunning = true;
backgroundThread = new Thread(BackgroundLoop) { IsBackground = true };
Expand Down
6 changes: 3 additions & 3 deletions K4AdotNet/BodyTracking/BodyFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public BodyFrame DuplicateReference()

/// <summary>Gets the number of detected bodies.</summary>
/// <exception cref="ObjectDisposedException">This property cannot be called for disposed objects.</exception>
public int BodyCount => Helpers.UIntPtrToInt32(NativeApi.FrameGetNumBodies(handle.ValueNotDisposed));
public int BodyCount => (int)NativeApi.FrameGetNumBodies(handle.ValueNotDisposed);

/// <summary>Get the original capture that was used to calculate this body frame.</summary>
/// <remarks><para>
Expand Down Expand Up @@ -124,7 +124,7 @@ public void GetBodySkeleton(int bodyIndex, out Skeleton skeleton)
{
if (bodyIndex < 0 || bodyIndex >= BodyCount)
throw new ArgumentOutOfRangeException(nameof(bodyIndex));
if (NativeApi.FrameGetBodySkeleton(handle.ValueNotDisposed, Helpers.Int32ToUIntPtr(bodyIndex), out skeleton) != NativeCallResults.Result.Succeeded)
if (NativeApi.FrameGetBodySkeleton(handle.ValueNotDisposed, (uint)bodyIndex, out skeleton) != NativeCallResults.Result.Succeeded)
throw new BodyTrackingException($"Cannot extract skeletal data for body with index {bodyIndex}");
}

Expand All @@ -137,7 +137,7 @@ public BodyId GetBodyId(int bodyIndex)
{
if (bodyIndex < 0 || bodyIndex >= BodyCount)
throw new ArgumentOutOfRangeException(nameof(bodyIndex));
return NativeApi.FrameGetBodyId(handle.ValueNotDisposed, Helpers.Int32ToUIntPtr(bodyIndex));
return NativeApi.FrameGetBodyId(handle.ValueNotDisposed, (uint)bodyIndex);
}

internal static BodyFrame Create(NativeHandles.BodyFrameHandle bodyFrameHandle)
Expand Down
7 changes: 4 additions & 3 deletions K4AdotNet/BodyTracking/JointType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// typedef enum
// {
// K4ABT_JOINT_PELVIS = 0,
// K4ABT_JOINT_SPINE_NAVAL,
// K4ABT_JOINT_SPINE_NAVEL,
// K4ABT_JOINT_SPINE_CHEST,
// K4ABT_JOINT_NECK,
// K4ABT_JOINT_CLAVICLE_LEFT,
Expand Down Expand Up @@ -47,8 +47,9 @@ public enum JointType
/// <summary>Pelvis joint.</summary>
Pelvis = 0,

/// <summary>Naval spine joint.</summary>
SpineNaval,
/// <summary>Navel spine joint.</summary>
/// <summary>Navel spine joint.</summary>
SpineNavel,

/// <summary>Chest spine joint.</summary>
SpineChest,
Expand Down
6 changes: 3 additions & 3 deletions K4AdotNet/BodyTracking/JointTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static class JointTypes
public static readonly IReadOnlyList<JointType> All = new[]
{
JointType.Pelvis,
JointType.SpineNaval,
JointType.SpineNavel,
JointType.SpineChest,
JointType.Neck,
JointType.ClavicleLeft,
Expand Down Expand Up @@ -102,8 +102,8 @@ public static JointType GetParent(this JointType jointType)
{
// Spine
case JointType.Pelvis: return JointType.Pelvis;
case JointType.SpineNaval: return JointType.Pelvis;
case JointType.SpineChest: return JointType.SpineNaval;
case JointType.SpineNavel: return JointType.Pelvis;
case JointType.SpineChest: return JointType.SpineNavel;
case JointType.Neck: return JointType.SpineChest;
// Left arm
case JointType.ClavicleLeft: return JointType.SpineChest;
Expand Down
12 changes: 6 additions & 6 deletions K4AdotNet/BodyTracking/NativeApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ public static extern NativeCallResults.WaitResult TrackerPopResult(
[DllImport(Sdk.BODY_TRACKING_DLL_NAME, EntryPoint = "k4abt_tracker_shutdown", CallingConvention = CallingConvention.Cdecl)]
public static extern void TrackerShutdown(NativeHandles.TrackerHandle trackerHandle);

// K4ABT_EXPORT size_t k4abt_frame_get_num_bodies(k4abt_frame_t body_frame_handle);
// K4ABT_EXPORT uint32_t k4abt_frame_get_num_bodies(k4abt_frame_t body_frame_handle);
/// <summary>Get the number of people from the <see cref="NativeHandles.BodyFrameHandle"/>.</summary>
/// <param name="bodyFrameHandle">Handle to a body frame object returned by <see cref="TrackerPopResult(NativeHandles.TrackerHandle, out NativeHandles.BodyFrameHandle, Timeout)"/> function.</param>
/// <returns>Returns the number of detected bodies. 0 if the function fails.</returns>
/// <remarks>Called when the user has received a body frame handle and wants to access the data contained in it.</remarks>
[DllImport(Sdk.BODY_TRACKING_DLL_NAME, EntryPoint = "k4abt_frame_get_num_bodies", CallingConvention = CallingConvention.Cdecl)]
public static extern UIntPtr FrameGetNumBodies(NativeHandles.BodyFrameHandle bodyFrameHandle);
public static extern uint FrameGetNumBodies(NativeHandles.BodyFrameHandle bodyFrameHandle);

// K4ABT_EXPORT k4a_result_t k4abt_frame_get_body_skeleton(k4abt_frame_t body_frame_handle, size_t index, k4abt_skeleton_t* skeleton);
// K4ABT_EXPORT k4a_result_t k4abt_frame_get_body_skeleton(k4abt_frame_t body_frame_handle, uint32_t index, k4abt_skeleton_t* skeleton);
/// <summary>Get the joint information for a particular person index from the <see cref="NativeHandles.BodyFrameHandle"/>.</summary>
/// <param name="bodyFrameHandle">Handle to a body frame object returned by <see cref="TrackerPopResult(NativeHandles.TrackerHandle, out NativeHandles.BodyFrameHandle, Timeout)"/> function.</param>
/// <param name="index">The index of the body of which the joint information is queried.</param>
Expand All @@ -139,10 +139,10 @@ public static extern NativeCallResults.WaitResult TrackerPopResult(
[DllImport(Sdk.BODY_TRACKING_DLL_NAME, EntryPoint = "k4abt_frame_get_body_skeleton", CallingConvention = CallingConvention.Cdecl)]
public static extern NativeCallResults.Result FrameGetBodySkeleton(
NativeHandles.BodyFrameHandle bodyFrameHandle,
UIntPtr index,
uint index,
out Skeleton skeleton);

// K4ABT_EXPORT uint32_t k4abt_frame_get_body_id(k4abt_frame_t body_frame_handle, size_t index);
// K4ABT_EXPORT uint32_t k4abt_frame_get_body_id(k4abt_frame_t body_frame_handle, uint32_t index);
/// <summary>Get the body id for a particular person index from the <see cref="NativeHandles.BodyFrameHandle"/>.</summary>
/// <param name="bodyFrameHandle">Handle to a body frame object returned by <see cref="TrackerPopResult(NativeHandles.TrackerHandle, out NativeHandles.BodyFrameHandle, Timeout)"/> function.</param>
/// <param name="index">The index of the body of which the body id information is queried.</param>
Expand All @@ -153,7 +153,7 @@ public static extern NativeCallResults.Result FrameGetBodySkeleton(
[DllImport(Sdk.BODY_TRACKING_DLL_NAME, EntryPoint = "k4abt_frame_get_body_id", CallingConvention = CallingConvention.Cdecl)]
public static extern BodyId FrameGetBodyId(
NativeHandles.BodyFrameHandle bodyFrameHandle,
UIntPtr index);
uint index);

// K4ABT_EXPORT uint64_t k4abt_frame_get_device_timestamp_usec(k4abt_frame_t body_frame_handle);
/// <summary>Get the body frame's device timestamp.</summary>
Expand Down
8 changes: 4 additions & 4 deletions K4AdotNet/BodyTracking/Skeleton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public struct Skeleton : IEnumerable<Joint>
/// <summary>Pelvis joint.</summary>
public Joint Pelvis;

/// <summary>Naval spine joint.</summary>
public Joint SpineNaval;
/// <summary>Navel spine joint.</summary>
public Joint SpineNavel;

/// <summary>Chest spine joint.</summary>
public Joint SpineChest;
Expand Down Expand Up @@ -132,7 +132,7 @@ public Joint this[JointType index]
switch (index)
{
case JointType.Pelvis: return Pelvis;
case JointType.SpineNaval: return SpineNaval;
case JointType.SpineNavel: return SpineNavel;
case JointType.SpineChest: return SpineChest;
case JointType.Neck: return Neck;
case JointType.ClavicleLeft: return ClavicleLeft;
Expand Down Expand Up @@ -172,7 +172,7 @@ public Joint this[JointType index]
switch (index)
{
case JointType.Pelvis: Pelvis = value; break;
case JointType.SpineNaval: SpineNaval = value; break;
case JointType.SpineNavel: SpineNavel = value; break;
case JointType.SpineChest: SpineChest = value; break;
case JointType.Neck: Neck = value; break;
case JointType.ClavicleLeft: ClavicleLeft = value; break;
Expand Down
56 changes: 29 additions & 27 deletions K4AdotNet/BodyTracking/Tracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ namespace K4AdotNet.BodyTracking
/// <seealso cref="BodyFrame"/>
public sealed class Tracker : IDisposablePlus
{
// Current version of Body Tracking runtime does not support creation of multiple instances.
private static volatile int instancesCounter;

private readonly NativeHandles.HandleWrapper<NativeHandles.TrackerHandle> handle; // this class is an wrapper around this handle
private volatile int queueSize; // captures in queue
private float temporalSmoothingFactor = DefaultSmoothingFactor;
Expand All @@ -38,10 +35,6 @@ public sealed class Tracker : IDisposablePlus
/// Invalid value of <paramref name="calibration"/>: <see cref="Calibration.DepthMode"/> cannot be <see cref="DepthMode.Off"/> and <see cref="DepthMode.PassiveIR"/>.
/// Because depth data is required for body tracking.
/// </exception>
/// <exception cref="NotSupportedException">
/// Only one tracker is allowed to exist at the same time in each process. If you call this constructor without destroying the
/// previous tracker you created, the constructor call will fail with this exception.
/// </exception>
/// <exception cref="BodyTrackingException">
/// Unable to find/initialize Body Tracking runtime.
/// </exception>
Expand All @@ -54,28 +47,15 @@ public Tracker(ref Calibration calibration, TrackerConfiguration config = defaul

DepthMode = calibration.DepthMode;

var incrementedInstanceCounter = Interlocked.Increment(ref instancesCounter);
try
{
if (incrementedInstanceCounter != 1)
throw new NotSupportedException("Oops! Current version of Body Tracking runtime does not support creation of multiple body trackers. Sorry!");

if (!Sdk.TryCreateTrackerHandle(ref calibration, config, out var handle, out var message))
throw new BodyTrackingException(message);
if (!Sdk.TryCreateTrackerHandle(ref calibration, config, out var handle, out var message))
throw new BodyTrackingException(message);

this.handle = handle;
this.handle.Disposed += Handle_Disposed;
}
catch
{
Interlocked.Decrement(ref instancesCounter);
throw;
}
this.handle = handle;
this.handle.Disposed += Handle_Disposed;
}

private void Handle_Disposed(object sender, EventArgs e)
{
Interlocked.Decrement(ref instancesCounter);
queueSize = 0;
handle.Disposed -= Handle_Disposed;
Disposed?.Invoke(this, EventArgs.Empty);
Expand Down Expand Up @@ -166,7 +146,7 @@ public float TemporalSmoothingFactor
}

/// <summary>Adds a Azure Kinect sensor capture to the tracker input queue to generate its body tracking result asynchronously.</summary>
/// <param name="capture">It should contain the depth data compatible with <see cref="DepthMode"/> for this function to work. Not <see langword="null"/>.</param>
/// <param name="capture">It should contain the depth and IR data compatible with <see cref="DepthMode"/> for this function to work. Not <see langword="null"/>.</param>
/// <param name="timeout">
/// Specifies the time the function should block waiting to add the sensor capture to the tracker process queue.
/// Default value is <see cref="Timeout.NoWait"/>, which means checking of the status without blocking.
Expand All @@ -177,7 +157,7 @@ public float TemporalSmoothingFactor
/// <see langword="false"/> - if the queue is still full (see <see cref="IsQueueFull"/> property) before the <paramref name="timeout"/> elapses.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="capture"/> cannot be <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="capture"/> doesn't contain depth data compatible with <see cref="DepthMode"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="capture"/> doesn't contain depth and/or IR data compatible with <see cref="DepthMode"/>.</exception>
/// <exception cref="ObjectDisposedException">Object was disposed before this call or has been disposed during this call.</exception>
/// <exception cref="BodyTrackingException">Cannot add capture to the tracker for some unknown reason. See logs for details.</exception>
public bool TryEnqueueCapture(Capture capture, Timeout timeout = default)
Expand Down Expand Up @@ -214,6 +194,28 @@ public bool TryEnqueueCapture(Capture capture, Timeout timeout = default)
}
}

using (var irImage = capture.IRImage)
{
if (irImage == null)
{
throw new ArgumentException(
"Capture should contain the IR data.",
nameof(capture));
}
if (irImage.Format != ImageFormat.IR16)
{
throw new ArgumentException(
$"Invalid format of IR data in capture: expected {ImageFormat.IR16} but was {irImage.Format}.",
nameof(capture));
}
if (irImage.WidthPixels != DepthMode.WidthPixels() || irImage.HeightPixels != DepthMode.HeightPixels())
{
throw new ArgumentException(
$"Invalid resolution of IR data in capture: expected {DepthMode.WidthPixels()}x{DepthMode.HeightPixels()} pixels but was {irImage.WidthPixels}x{irImage.HeightPixels} pixels.",
nameof(capture));
}
}

throw new BodyTrackingException("Cannot add new capture to body tracking pipeline. See logs for details.");
}

Expand All @@ -226,7 +228,7 @@ public bool TryEnqueueCapture(Capture capture, Timeout timeout = default)
/// <summary>Equivalent to call of <see cref="TryEnqueueCapture(Capture, Timeout)"/> with infinite timeout: <see cref="Timeout.Infinite"/>.</summary>
/// <param name="capture">It should contain the depth data compatible with <see cref="DepthMode"/> for this function to work. Not <see langword="null"/>.</param>
/// <exception cref="ArgumentNullException"><paramref name="capture"/> cannot be <see langword="null"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="capture"/> doesn't contain depth data compatible with <see cref="DepthMode"/>.</exception>
/// <exception cref="ArgumentException"><paramref name="capture"/> doesn't contain depth and/or IR data compatible with <see cref="DepthMode"/>.</exception>
/// <exception cref="ObjectDisposedException">Object was disposed before this call or has been disposed during this call.</exception>
/// <exception cref="BodyTrackingException">Cannot add capture to the tracker for some unknown reason. See logs for details.</exception>
public void EnqueueCapture(Capture capture)
Expand Down
21 changes: 14 additions & 7 deletions K4AdotNet/BodyTracking/TrackerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ namespace K4AdotNet.BodyTracking
// typedef struct _k4abt_tracker_configuration_t
// {
// k4abt_sensor_orientation_t sensor_orientation;
// bool cpu_only_mode;
// k4abt_tracker_processing_mode_t processing_mode;
// int32_t gpu_device_id;
// } k4abt_tracker_configuration_t;
//
/// <summary>Configuration parameters for a k4abt body tracker.</summary>
Expand All @@ -24,16 +25,22 @@ public struct TrackerConfiguration
/// The CPU only mode doesn't require the machine to have a GPU to run this SDK.
/// But it will be much slower than the GPU mode.
/// </remarks>
[MarshalAs(UnmanagedType.I1)]
public bool CpuOnlyMode;
public TrackerProcessingMode ProcessingMode;

// static const k4abt_tracker_configuration_t K4ABT_TRACKER_CONFIG_DEFAULT = { K4ABT_SENSOR_ORIENTATION_DEFAULT, false };
/// <summary>Specify the GPU device ID to run the tracker.</summary>
/// <remarks>The setting is only effective if the <see cref="ProcessingMode"/> setting is set to <see cref="TrackerProcessingMode.Gpu"/>.</remarks>
public int GpuDeviceId;

// static const k4abt_tracker_configuration_t K4ABT_TRACKER_CONFIG_DEFAULT = { K4ABT_SENSOR_ORIENTATION_DEFAULT, // sensor_orientation
// K4ABT_TRACKER_PROCESSING_MODE_GPU, // processing_mode
// 0 }; // gpu_device_id
//
/// <summary>Default configuration setting for k4abt tracker.</summary>
/// <remarks>Use this setting to initialize a <see cref="TrackerConfiguration"/> to a default state.</remarks>
public static readonly TrackerConfiguration Default = new TrackerConfiguration {
SensorOrientation = SensorOrientation.Default,
CpuOnlyMode = false,
};
SensorOrientation = SensorOrientation.Default,
ProcessingMode = TrackerProcessingMode.Gpu,
GpuDeviceId = 0,
};
}
}
Loading

0 comments on commit 51a9c06

Please sign in to comment.