dev #22

Merged
louis.dufour merged 28 commits from dev into master 1 year ago

@ -36,6 +36,7 @@
<Reference Include="Microsoft.Kinect, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Kinect.2.0.1410.19000\lib\net45\Microsoft.Kinect.dll</HintPath>
</Reference>
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@ -54,6 +55,14 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KinectUtils\KinectUtils.csproj">
<Project>{2d44487e-f514-4063-9494-2af1e8c9e9c8}</Project>
<Name>KinectUtils</Name>
</ProjectReference>
<ProjectReference Include="..\LibMyGesturesBank\MyGesturesBank.csproj">
<Project>{2496DFB1-EB55-47A1-A780-211E079B289D}</Project>
<Name>MyGesturesBank</Name>
</ProjectReference>
<ProjectReference Include="..\Lib\Lib.csproj">
<Project>{0751c83e-7845-4e5f-a5d3-e11aba393aca}</Project>
<Name>Lib</Name>

@ -1,11 +1,15 @@
using Lib;
using KinectUtils;
using Lib;
using Microsoft.Kinect;
using MyGesturesBank;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace ConsoleApp
{
@ -13,41 +17,18 @@ namespace ConsoleApp
{
static void Main(string[] args)
{
// KinectManager kinectManager = new KinectManager();
// if (kinectManager.StartSensor())
// {
// Console.WriteLine("Kinect n'est pas connecté ou non reconnu.");
// return;
// }
// allumer la kinect
KinectManager kinectManager = new KinectManager();
kinectManager.StartSensor();
Console.WriteLine("Kinect démarre");
// // Créez les instances de vos postures
// PostureHandUp handUpPosture = new PostureHandUp();
// PostureHandsOnHead handsOnHeadPosture = new PostureHandsOnHead();
// // Abonnez-vous aux événements de reconnaissance de posture
// handUpPosture.GestureRecognized += (sender, e) =>
// {
// Console.WriteLine("Posture Hand Up reconnue !");
// };
// handsOnHeadPosture.GestureRecognized += (sender, e) =>
// {
// Console.WriteLine("Posture Hands On Head reconnue !");
// };
// // Boucle pour tester les postures
// while (true)
// {
// Body body = kinectManager.GetNextBody(); // Méthode fictive pour obtenir les données du corps
// if (body != null)
// {
// handUpPosture.TestGesture(body);
// handsOnHeadPosture.TestGesture(body);
// }
// Thread.Sleep(50); // Une petite pause pour ne pas surcharger le CPU
// }
AllGesturesFactory allGesturesFactory = new AllGesturesFactory();
GestureManager.AddGestures(allGesturesFactory);
GestureManager.StartAcquiringFrames(kinectManager);
while (true)
{
Thread.Sleep(50);
}
}
}
}

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KinectUtils
{
public class AllGesturesFactory : IGestureFactory
{
public IEnumerable<BaseGesture> CreateGestures()
{
throw new NotImplementedException();
}
}
}

@ -9,7 +9,7 @@ namespace KinectUtils
public event EventHandler GestureRecognized;
// Nom du geste - marqué comme virtual pour permettre la substitution
public string GestureName { get; protected set; }
public virtual string GestureName { get; protected set; }
// Méthode abstraite pour tester le geste
public abstract void TestGesture(Body body);
@ -32,5 +32,4 @@ namespace KinectUtils
GestureName = gestureName;
}
}
}

@ -7,27 +7,80 @@ using System.Threading.Tasks;
namespace KinectUtils
{
class BaseMapping<T>
public abstract class BaseMapping<T>
{
public void SubscribeToStartGesture(BaseGesture gesture)
protected bool running = false;
public event EventHandler<OnMappingEventArgs<T>> OnMapping;
protected BaseMapping(BaseGesture startGesture, BaseGesture endGesture)
{
SubscribeToStartGesture(startGesture);
SubscribeToEndGesture(endGesture);
// Assuming GestureManager has an event that provides processed body data
GestureManager.ProcessedBodyFrameArrived += OnProcessedBodyFrameArrived;
}
protected abstract T Mapping(Body body);
protected bool TestMapping(Body body, out T output)
{
throw new NotImplementedException();
output = default(T);
if (running)
{
output = Mapping(body);
return true;
}
return false;
}
public void SubscribeToEndGesture(BaseGesture gesture)
protected void SubscribeToStartGesture(BaseGesture gesture)
{
throw new NotImplementedException();
gesture.GestureRecognized += (sender, e) => { if (!running) running = true; };
}
public void SubscribeToToggleGesture(BaseGesture gesture)
protected void SubscribeToEndGesture(BaseGesture gesture)
{
throw new NotImplementedException();
gesture.GestureRecognized += (sender, e) => { if (running) running = false; };
}
protected T Mapping(Body body)
// Assuming your GestureManager provides a similar event
protected void OnProcessedBodyFrameArrived(object sender, ProcessedBodyFrameEventArgs e)
{
throw new NotImplementedException();
foreach (var body in e.Bodies)
{
if (body.IsTracked)
{
T output;
if (TestMapping(body, out output))
{
OnMapping?.Invoke(this, new OnMappingEventArgs<T>(output));
}
}
}
}
public bool TestMapping(Body body, out T output)
{
throw new NotImplementedException();
}
public class OnMappingEventArgs<T> : EventArgs
{
public T MappedValue { get; private set; }
public OnMappingEventArgs(T mappedValue)
{
MappedValue = mappedValue;
}
}
// Custom EventArgs to be used within your application logic
// This is not from the Kinect SDK, but rather a custom class to pass along processed body data
public class ProcessedBodyFrameEventArgs : EventArgs
{
public Body[] Bodies { get; private set; }
public Body ClosestBody { get; private set; }
public ProcessedBodyFrameEventArgs(Body[] bodies, Body closestBody)
{
Bodies = bodies;
ClosestBody = closestBody;
}
}
}

@ -7,43 +7,48 @@ using System.Threading.Tasks;
namespace KinectUtils
{
abstract class Gesture : BaseGesture
public abstract class Gesture : BaseGesture
{
public bool IsTesting { get; protected set; }
public bool IsRecognitionRunning { get; set; } = false;
protected int MinNbOfFrames = 10; // Exemple de valeur, ajustez selon le geste
protected int MaxNbOfFrames = 50; // Exemple de valeur, ajustez selon le geste
private int mCurrentFrameCount = 0;
// public bool isRecognitionRunning { get; set; }
private int currentFrameCount = 0;
public override void TestGesture(Body body)
{
if (!IsTesting)
if (!IsRecognitionRunning)
{
if (TestInitialConditions(body))
{
IsTesting = true;
mCurrentFrameCount = 0;
IsRecognitionRunning = true;
currentFrameCount = 0;
}
}
else
{
mCurrentFrameCount++;
currentFrameCount++;
if (!TestPosture(body) || !TestRunningGesture(body) || mCurrentFrameCount > MaxNbOfFrames)
if (
!TestPosture(body)
|| !TestRunningGesture(body)
|| currentFrameCount > MaxNbOfFrames
)
{
IsTesting = false;
IsRecognitionRunning = false;
}
else if (TestEndConditions(body) && mCurrentFrameCount >= MinNbOfFrames)
else if (TestEndConditions(body) && currentFrameCount >= MinNbOfFrames)
{
OnGestureRecognized(body);
IsTesting = false;
Console.WriteLine(GestureName);
IsRecognitionRunning = false;
}
}
}
abstract protected bool TestInitialConditions(Body body);
abstract protected bool TestPosture(Body body);
abstract protected bool TestRunningGesture(Body body);
abstract protected bool TestEndConditions(Body body);
protected abstract bool TestInitialConditions(Body body);
protected abstract bool TestPosture(Body body);
protected abstract bool TestRunningGesture(Body body);
protected abstract bool TestEndConditions(Body body);
}
}

@ -1,36 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
using Lib;
using Microsoft.Kinect;
namespace KinectUtils
{
static class GestureManager
public static class GestureManager
{
private static BodyFrameReader bodyFrameReader;
private static Body[] bodies;
static event EventHandler GestureRecognized;
public static event EventHandler BodyFrameArrived;
public static event EventHandler<ProcessedBodyFrameEventArgs> ProcessedBodyFrameArrived;
static KinectManager KinectManager { get; set; }
static List<BaseGesture> KnownGestures { get; set; }
static List<BaseGesture> KnownGestures { get; set; } = new List<BaseGesture>();
static public void AddGestures(IGestureFactory factory)
public static void AddGestures(IGestureFactory factory)
{
KnownGestures = (List<BaseGesture>)factory.CreateGestures();
var gestures = (List<BaseGesture>)factory.CreateGestures();
foreach (var gesture in gestures)
{
AddGesture(gesture);
}
}
static public void AddGestures(params BaseGesture[] gestures)
public static void AddGesture(BaseGesture gesture)
{
foreach (var gesture in gestures)
if (!KnownGestures.Contains(gesture))
{
KnownGestures.Add(gesture);
gesture.GestureRecognized += (sender, e) => GestureRecognized?.Invoke(sender, e);
}
}
public static void RemoveGesture(BaseGesture gesture)
{
if (KnownGestures.Contains(gesture))
{
KnownGestures.Remove(gesture);
gesture.GestureRecognized -= (sender, e) => GestureRecognized?.Invoke(sender, e);
}
}
static public void RemoveGesture(BaseGesture gesture)
public static void StartAcquiringFrames(KinectManager kinectManager)
{
KnownGestures.Remove(gesture);
bodyFrameReader = kinectManager.Sensor.BodyFrameSource.OpenReader();
bodyFrameReader.FrameArrived += Reader_BodyFrameArrived;
}
static public void StartAcquiringFrames(KinectManager kinectManager)
private static void Reader_BodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
throw new NotImplementedException();
using (var bodyframe = e.FrameReference.AcquireFrame())
{
if (bodyframe != null)
{
if (bodies == null)
{
bodies = new Body[bodyframe.BodyCount];
}
bodyframe.GetAndRefreshBodyData(bodies);
Body closestBody = bodies.Where(b => b.IsTracked)
.OrderBy(b => b.Joints[JointType.SpineBase].Position.Z)
.FirstOrDefault();
ProcessedBodyFrameArrived?.Invoke(sender, new ProcessedBodyFrameEventArgs(bodies, closestBody));
foreach (var body in bodies)
{
if (body.IsTracked)
{
foreach (var gesture in KnownGestures)
{
gesture.TestGesture(body);
}
}
}
}
}
}
}
}

@ -6,8 +6,8 @@ using System.Threading.Tasks;
namespace KinectUtils
{
interface IGestureFactory
public interface IGestureFactory
{
IEnumerable<BaseGesture> CreateGestures();
IEnumerable<BaseGesture> CreateGestures();
}
}

@ -42,7 +42,6 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AllGesturesFactory.cs" />
<Compile Include="BaseGesture.cs" />
<Compile Include="BaseMapping.cs" />
<Compile Include="Gesture.cs" />

@ -9,16 +9,31 @@ namespace KinectUtils
{
public abstract class Posture : BaseGesture
{
// Déclaration des événements
public event Action<Body> PostureRecognized;
public event Action<Body> PostureUnrecognized;
private bool wasRecognized = false; // Pour garder l'état de reconnaissance précédent
protected abstract bool TestPosture(Body body);
public override void TestGesture(Body body)
{
if (TestPosture(body))
bool isRecognized = TestPosture(body); // Teste la posture actuelle
if (isRecognized && !wasRecognized)
{
// Posture is recognized
OnGestureRecognized();
// La posture est reconnue et ne l'était pas au frame précédent
PostureRecognized?.Invoke(body);
Console.WriteLine(GestureName);
}
else if (!isRecognized && wasRecognized)
{
// La posture n'est plus reconnue alors qu'elle l'était au frame précédent
PostureUnrecognized?.Invoke(body);
}
}
wasRecognized = isRecognized; // Mise à jour de l'état de reconnaissance pour le prochain frame
}
}
}

@ -28,6 +28,7 @@ namespace Lib
get { return bodies; }
private set { bodies = value; }
}
public override void Stop()
{
if (Reader != null)
@ -35,13 +36,22 @@ namespace Lib
Reader.Dispose();
Reader = null;
}
}
public BodyImageStream(KinectManager kinectmanager, Canvas skeletonCanvas) : base(kinectmanager)
public BodyImageStream(KinectManager kinectmanager, Canvas skeletonCanvas)
: base(kinectmanager)
{
var framedescription = kinectmanager.Sensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);
Bitmap = new WriteableBitmap(framedescription.Width, framedescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
var framedescription = kinectmanager.Sensor.ColorFrameSource.CreateFrameDescription(
ColorImageFormat.Bgra
);
Bitmap = new WriteableBitmap(
framedescription.Width,
framedescription.Height,
96.0,
96.0,
PixelFormats.Bgr32,
null
);
reader = kinectmanager.Sensor.BodyFrameSource.OpenReader();
reader.FrameArrived += Reader_BodyFrameArrived;
@ -56,7 +66,10 @@ namespace Lib
Joint joint1 = body.Joints[JointType1];
// ne dessinez que si les deux joints sont suivis
if (joint0.TrackingState == TrackingState.Tracked && joint1.TrackingState == TrackingState.Tracked)
if (
joint0.TrackingState == TrackingState.Tracked
&& joint1.TrackingState == TrackingState.Tracked
)
{
Line bone = new Line
{
@ -74,7 +87,10 @@ namespace Lib
private Point MapJointToScreen(Joint joint)
{
ColorSpacePoint colorPoint = this.KinectManager.Sensor.CoordinateMapper.MapCameraPointToColorSpace(joint.Position);
ColorSpacePoint colorPoint =
this.KinectManager.Sensor.CoordinateMapper.MapCameraPointToColorSpace(
joint.Position
);
// Gestion des coordonnées infinies
float x = float.IsInfinity(colorPoint.X) ? 0 : colorPoint.X;
@ -84,78 +100,80 @@ namespace Lib
}
private void drawskeleton(Body body)
{
// tête et cou
drawbone(body, JointType.Head, JointType.Neck);
drawbone(body, JointType.Neck, JointType.SpineShoulder);
// torse
drawbone(body, JointType.SpineShoulder, JointType.SpineMid);
drawbone(body, JointType.SpineMid, JointType.SpineBase);
drawbone(body, JointType.SpineShoulder, JointType.ShoulderRight);
drawbone(body, JointType.SpineShoulder, JointType.ShoulderLeft);
drawbone(body, JointType.SpineBase, JointType.HipRight);
drawbone(body, JointType.SpineBase, JointType.HipLeft);
// bras droit
drawbone(body, JointType.ShoulderRight, JointType.ElbowRight);
drawbone(body, JointType.ElbowRight, JointType.WristRight);
drawbone(body, JointType.WristRight, JointType.HandRight);
drawbone(body, JointType.HandRight, JointType.HandTipRight);
drawbone(body, JointType.WristRight, JointType.ThumbRight);
// bras gauche
drawbone(body, JointType.ShoulderLeft, JointType.ElbowLeft);
drawbone(body, JointType.ElbowLeft, JointType.WristLeft);
drawbone(body, JointType.WristLeft, JointType.HandLeft);
drawbone(body, JointType.HandLeft, JointType.HandTipLeft);
drawbone(body, JointType.WristLeft, JointType.ThumbLeft);
// jambe droite
drawbone(body, JointType.HipRight, JointType.KneeRight);
drawbone(body, JointType.KneeRight, JointType.AnkleRight);
drawbone(body, JointType.AnkleRight, JointType.FootRight);
// jambe gauche
drawbone(body, JointType.HipLeft, JointType.KneeLeft);
drawbone(body, JointType.KneeLeft, JointType.AnkleLeft);
drawbone(body, JointType.AnkleLeft, JointType.FootLeft);
// dessinez les joints
foreach (JointType JointType in body.Joints.Keys)
{
// tête et cou
drawbone(body, JointType.Head, JointType.Neck);
drawbone(body, JointType.Neck, JointType.SpineShoulder);
// torse
drawbone(body, JointType.SpineShoulder, JointType.SpineMid);
drawbone(body, JointType.SpineMid, JointType.SpineBase);
drawbone(body, JointType.SpineShoulder, JointType.ShoulderRight);
drawbone(body, JointType.SpineShoulder, JointType.ShoulderLeft);
drawbone(body, JointType.SpineBase, JointType.HipRight);
drawbone(body, JointType.SpineBase, JointType.HipLeft);
// bras droit
drawbone(body, JointType.ShoulderRight, JointType.ElbowRight);
drawbone(body, JointType.ElbowRight, JointType.WristRight);
drawbone(body, JointType.WristRight, JointType.HandRight);
drawbone(body, JointType.HandRight, JointType.HandTipRight);
drawbone(body, JointType.WristRight, JointType.ThumbRight);
// bras gauche
drawbone(body, JointType.ShoulderLeft, JointType.ElbowLeft);
drawbone(body, JointType.ElbowLeft, JointType.WristLeft);
drawbone(body, JointType.WristLeft, JointType.HandLeft);
drawbone(body, JointType.HandLeft, JointType.HandTipLeft);
drawbone(body, JointType.WristLeft, JointType.ThumbLeft);
// jambe droite
drawbone(body, JointType.HipRight, JointType.KneeRight);
drawbone(body, JointType.KneeRight, JointType.AnkleRight);
drawbone(body, JointType.AnkleRight, JointType.FootRight);
// jambe gauche
drawbone(body, JointType.HipLeft, JointType.KneeLeft);
drawbone(body, JointType.KneeLeft, JointType.AnkleLeft);
drawbone(body, JointType.AnkleLeft, JointType.FootLeft);
// dessinez les joints
foreach (JointType JointType in body.Joints.Keys)
Joint joint = body.Joints[JointType];
if (joint.TrackingState == TrackingState.Tracked)
{
Joint joint = body.Joints[JointType];
if (joint.TrackingState == TrackingState.Tracked)
{
DrawJoint(MapJointToScreen(joint));
}
DrawJoint(MapJointToScreen(joint));
}
}
}
private void DrawJoint(Point point)
private void DrawJoint(Point point)
{
Ellipse ellipse = new Ellipse
{
Ellipse ellipse = new Ellipse
{
Width = 10,
Height = 10,
Fill = new SolidColorBrush(Colors.Red)
};
Width = 10,
Height = 10,
Fill = new SolidColorBrush(Colors.Red)
};
Canvas.SetLeft(ellipse, point.X - ellipse.Width / 2);
Canvas.SetTop(ellipse, point.Y - ellipse.Height / 2);
Canvas.SetLeft(ellipse, point.X - ellipse.Width / 2);
Canvas.SetTop(ellipse, point.Y - ellipse.Height / 2);
Canvas.Children.Add(ellipse);
}
private void Reader_BodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
Canvas.Children.Add(ellipse);
}
private void Reader_BodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
using (var bodyframe = e.FrameReference.AcquireFrame())
{
using (var bodyframe = e.FrameReference.AcquireFrame())
if (bodyframe != null)
{
if (bodyframe != null)
bodyframe.GetAndRefreshBodyData(this.bodies);
// nettoyer le Canvas avant de dessiner
if (Canvas != null)
{
bodyframe.GetAndRefreshBodyData(this.bodies);
Canvas.Children.Clear(); // nettoyer le Canvas avant de dessiner
Canvas.Children.Clear();
foreach (var body in this.bodies)
{
if (body.IsTracked)
@ -168,5 +186,5 @@ namespace Lib
}
}
}
}
}

@ -22,7 +22,8 @@ namespace Lib
}
private ColorFrameReader _colorReader;
public ColorFrameReader ColorReader {
public ColorFrameReader ColorReader
{
get { return _colorReader; }
private set { _colorReader = value; }
}
@ -33,6 +34,7 @@ namespace Lib
get { return bodies; }
private set { bodies = value; }
}
public override void Stop()
{
if (Reader != null)
@ -40,18 +42,27 @@ namespace Lib
Reader.Dispose();
Reader = null;
}
if(ColorReader != null)
if (ColorReader != null)
{
ColorReader.Dispose();
ColorReader = null;
}
}
public ColorAndBodyImageStream(KinectManager kinectmanager, Canvas skeletonCanvas) : base(kinectmanager)
public ColorAndBodyImageStream(KinectManager kinectmanager, Canvas skeletonCanvas)
: base(kinectmanager)
{
var framedescription = kinectmanager.Sensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);
Bitmap = new WriteableBitmap(framedescription.Width, framedescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
var framedescription = kinectmanager.Sensor.ColorFrameSource.CreateFrameDescription(
ColorImageFormat.Bgra
);
Bitmap = new WriteableBitmap(
framedescription.Width,
framedescription.Height,
96.0,
96.0,
PixelFormats.Bgr32,
null
);
reader = kinectmanager.Sensor.BodyFrameSource.OpenReader();
reader.FrameArrived += Reader_BodyFrameArrived;
ColorReader = KinectManager.Sensor.ColorFrameSource.OpenReader();
@ -67,7 +78,10 @@ namespace Lib
Joint joint1 = body.Joints[JointType1];
// ne dessinez que si les deux joints sont suivis
if (joint0.TrackingState == TrackingState.Tracked && joint1.TrackingState == TrackingState.Tracked)
if (
joint0.TrackingState == TrackingState.Tracked
&& joint1.TrackingState == TrackingState.Tracked
)
{
Line bone = new Line
{
@ -85,7 +99,10 @@ namespace Lib
private Point MapJointToScreen(Joint joint)
{
ColorSpacePoint colorPoint = this.KinectManager.Sensor.CoordinateMapper.MapCameraPointToColorSpace(joint.Position);
ColorSpacePoint colorPoint =
this.KinectManager.Sensor.CoordinateMapper.MapCameraPointToColorSpace(
joint.Position
);
// Gestion des coordonnées infinies
float x = float.IsInfinity(colorPoint.X) ? 0 : colorPoint.X;
@ -157,6 +174,7 @@ namespace Lib
Canvas.Children.Add(ellipse);
}
private void Reader_BodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
using (var bodyframe = e.FrameReference.AcquireFrame())
@ -178,6 +196,7 @@ namespace Lib
}
}
}
private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
@ -193,14 +212,22 @@ namespace Lib
this.Bitmap.Lock();
// Vérifier si la taille de l'image a changé
if ((colorFrameDescription.Width == this.Bitmap.PixelWidth) && (colorFrameDescription.Height == this.Bitmap.PixelHeight))
if (
(colorFrameDescription.Width == this.Bitmap.PixelWidth)
&& (colorFrameDescription.Height == this.Bitmap.PixelHeight)
)
{
colorFrame.CopyConvertedFrameDataToIntPtr(
this.Bitmap.BackBuffer,
(uint)(colorFrameDescription.Width * colorFrameDescription.Height * 4),
ColorImageFormat.Bgra);
this.Bitmap.AddDirtyRect(new Int32Rect(0, 0, this.Bitmap.PixelWidth, this.Bitmap.PixelHeight));
(uint)(
colorFrameDescription.Width * colorFrameDescription.Height * 4
),
ColorImageFormat.Bgra
);
this.Bitmap.AddDirtyRect(
new Int32Rect(0, 0, this.Bitmap.PixelWidth, this.Bitmap.PixelHeight)
);
}
this.Bitmap.Unlock();

@ -9,19 +9,26 @@ namespace Lib
public class ColorImageStream : KinectStream
{
private ColorFrameReader reader;
public ColorFrameReader Reader {
get {
return reader;
}
set
{
reader = value;
}
public ColorFrameReader Reader
{
get { return reader; }
set { reader = value; }
}
public ColorImageStream(KinectManager kinectManager) : base(kinectManager)
public ColorImageStream(KinectManager kinectManager)
: base(kinectManager)
{
var frameDescription = KinectManager.Sensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);
this.Bitmap = new WriteableBitmap(frameDescription.Width, frameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
var frameDescription = KinectManager.Sensor.ColorFrameSource.CreateFrameDescription(
ColorImageFormat.Bgra
);
this.Bitmap = new WriteableBitmap(
frameDescription.Width,
frameDescription.Height,
96.0,
96.0,
PixelFormats.Bgr32,
null
);
reader = KinectManager.Sensor.ColorFrameSource.OpenReader();
reader.FrameArrived += Reader_ColorFrameArrived;
}
@ -50,14 +57,22 @@ namespace Lib
this.Bitmap.Lock();
// Vérifier si la taille de l'image a changé
if ((colorFrameDescription.Width == this.Bitmap.PixelWidth) && (colorFrameDescription.Height == this.Bitmap.PixelHeight))
if (
(colorFrameDescription.Width == this.Bitmap.PixelWidth)
&& (colorFrameDescription.Height == this.Bitmap.PixelHeight)
)
{
colorFrame.CopyConvertedFrameDataToIntPtr(
this.Bitmap.BackBuffer,
(uint)(colorFrameDescription.Width * colorFrameDescription.Height * 4),
ColorImageFormat.Bgra);
(uint)(
colorFrameDescription.Width * colorFrameDescription.Height * 4
),
ColorImageFormat.Bgra
);
this.Bitmap.AddDirtyRect(new Int32Rect(0, 0, this.Bitmap.PixelWidth, this.Bitmap.PixelHeight));
this.Bitmap.AddDirtyRect(
new Int32Rect(0, 0, this.Bitmap.PixelWidth, this.Bitmap.PixelHeight)
);
}
this.Bitmap.Unlock();

@ -15,33 +15,33 @@ namespace Lib
private DepthFrameReader reader;
public DepthFrameReader Reader
{
get
{
return reader;
}
set
{
reader = value;
}
get { return reader; }
set { reader = value; }
}
private byte[] depthPixels;
public byte[] DepthPixels {
get {
return depthPixels;
}
set
{
depthPixels = value;
}
public byte[] DepthPixels
{
get { return depthPixels; }
set { depthPixels = value; }
}
public DepthImageStream(KinectManager kinectManager) : base(kinectManager)
public DepthImageStream(KinectManager kinectManager)
: base(kinectManager)
{
var frameDescription = KinectManager.Sensor.DepthFrameSource.FrameDescription;
this.Bitmap = new WriteableBitmap(frameDescription.Width, frameDescription.Height, 96.0, 96.0, PixelFormats.Gray8, null);
this.Bitmap = new WriteableBitmap(
frameDescription.Width,
frameDescription.Height,
96.0,
96.0,
PixelFormats.Gray8,
null
);
reader = KinectManager.Sensor.DepthFrameSource.OpenReader();
reader.FrameArrived += Reader_DepthFrameArrived;
DepthPixels = new byte[frameDescription.Width * frameDescription.Height];
}
private void Reader_DepthFrameArrived(object sender, DepthFrameArrivedEventArgs e)
{
using (DepthFrame depthFrame = e.FrameReference.AcquireFrame())
@ -55,14 +55,25 @@ namespace Lib
depthFrame.CopyFrameDataToArray(depthData);
// Traitez les données de profondeur
ProcessDepthFrameData(depthData, depthFrameDescription.LengthInPixels, depthFrame.DepthMinReliableDistance, depthFrame.DepthMaxReliableDistance);
ProcessDepthFrameData(
depthData,
depthFrameDescription.LengthInPixels,
depthFrame.DepthMinReliableDistance,
depthFrame.DepthMaxReliableDistance
);
// Mettez à jour le bitmap de profondeur
this.Bitmap.WritePixels(
new Int32Rect(0, 0, depthFrameDescription.Width, depthFrameDescription.Height),
new Int32Rect(
0,
0,
depthFrameDescription.Width,
depthFrameDescription.Height
),
this.depthPixels,
depthFrameDescription.Width,
0);
0
);
}
}
}
@ -76,7 +87,12 @@ namespace Lib
}
}
private void ProcessDepthFrameData(ushort[] depthData, uint depthFrameDataSize, ushort minDepth, ushort maxDepth)
private void ProcessDepthFrameData(
ushort[] depthData,
uint depthFrameDataSize,
ushort minDepth,
ushort maxDepth
)
{
// Convertir les données de profondeur en niveaux de gris
for (int i = 0; i < depthFrameDataSize; ++i)
@ -85,6 +101,5 @@ namespace Lib
DepthPixels[i] = (byte)(depth >= minDepth && depth <= maxDepth ? (depth % 256) : 0);
}
}
}
}

@ -16,30 +16,27 @@ namespace Lib
private byte[] infraredPixels;
public byte[] InfraredPixels
{
get
{
return infraredPixels;
}
private set
{
infraredPixels = value;
}
get { return infraredPixels; }
private set { infraredPixels = value; }
}
public InfraredFrameReader Reader
{
get
{
return reader;
}
private set
{
reader = value;
}
get { return reader; }
private set { reader = value; }
}
public InfraredImageStream(KinectManager kinectManager) : base(kinectManager)
public InfraredImageStream(KinectManager kinectManager)
: base(kinectManager)
{
var frameDescription = KinectManager.Sensor.InfraredFrameSource.FrameDescription;
this.Bitmap = new WriteableBitmap(frameDescription.Width, frameDescription.Height, 96.0, 96.0, PixelFormats.Gray8, null);
this.Bitmap = new WriteableBitmap(
frameDescription.Width,
frameDescription.Height,
96.0,
96.0,
PixelFormats.Gray8,
null
);
reader = KinectManager.Sensor.InfraredFrameSource.OpenReader();
reader.FrameArrived += Reader_InfraredFrameArrived;
infraredPixels = new byte[frameDescription.Width * frameDescription.Height];
@ -53,6 +50,7 @@ namespace Lib
reader = null;
}
}
private void ProcessInfraredFrameData(ushort[] frameData, uint frameDataSize)
{
// Convertir les données infrarouges en niveaux de gris
@ -81,10 +79,16 @@ namespace Lib
// Mettez à jour le bitmap infrarouge
this.Bitmap.WritePixels(
new Int32Rect(0, 0, infraredFrameDescription.Width, infraredFrameDescription.Height),
new Int32Rect(
0,
0,
infraredFrameDescription.Width,
infraredFrameDescription.Height
),
this.infraredPixels,
infraredFrameDescription.Width,
0);
0
);
}
}
}

@ -8,10 +8,9 @@ namespace Lib
public class KinectManager : INotifyPropertyChanged
{
private KinectSensor sensor;
public KinectSensor Sensor {
get {
return sensor;
}
public KinectSensor Sensor
{
get { return sensor; }
set
{
sensor = value;
@ -31,6 +30,7 @@ namespace Lib
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
@ -46,16 +46,20 @@ namespace Lib
sensor.IsAvailableChanged += KinectSensor_IsAvailableChanged;
}
}
public void StartSensor()
{
if (sensor != null && !sensor.IsOpen) {
if (sensor != null && !sensor.IsOpen)
{
sensor.Open();
}
else {
else
{
sensor = KinectSensor.GetDefault();
sensor.Open();
}
}
public void StopSensor()
{
if (sensor != null)
@ -64,6 +68,7 @@ namespace Lib
sensor = null;
}
}
public bool Status
{
get { return Sensor != null && Sensor.IsAvailable; }
@ -72,9 +77,10 @@ namespace Lib
public string StatusText
{
get { return _statusText; }
set {
set
{
_statusText = value;
if(this.PropertyChanged != null)
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("StatusText"));
}
@ -110,4 +116,4 @@ namespace Lib
}
}
}
}
}

@ -39,6 +39,7 @@ namespace Lib
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
@ -60,6 +61,5 @@ namespace Lib
}
public abstract void Stop();
}
}

@ -10,7 +10,8 @@ namespace Lib
public class KinectStreamsFactory
{
private KinectManager _kinectManager;
public KinectManager KinectManager {
public KinectManager KinectManager
{
get { return _kinectManager; }
private set { _kinectManager = value; }
}
@ -22,18 +23,21 @@ namespace Lib
private set { _streamFactory = value; }
}
public KinectStreamsFactory(KinectManager kinect,Canvas SkeletonCanvas)
public KinectStreamsFactory(KinectManager kinect, Canvas SkeletonCanvas)
{
_kinectManager = kinect;
// Initialisation de la fabrique avec les fonctions de création pour chaque type de flux.
StreamFactory = new Dictionary<KinectStreams, Func<KinectStream>>
{
{ KinectStreams.Color, () => new ColorImageStream(KinectManager) },
{ KinectStreams.Depth, () => new DepthImageStream(KinectManager) },
{ KinectStreams.IR, () => new InfraredImageStream(KinectManager) },
{ KinectStreams.Body, () => new BodyImageStream(KinectManager,SkeletonCanvas) },
{ KinectStreams.ColorAndBody, () => new ColorAndBodyImageStream(KinectManager,SkeletonCanvas) }
};
{
{ KinectStreams.Color, () => new ColorImageStream(KinectManager) },
{ KinectStreams.Depth, () => new DepthImageStream(KinectManager) },
{ KinectStreams.IR, () => new InfraredImageStream(KinectManager) },
{ KinectStreams.Body, () => new BodyImageStream(KinectManager, SkeletonCanvas) },
{
KinectStreams.ColorAndBody,
() => new ColorAndBodyImageStream(KinectManager, SkeletonCanvas)
}
};
}
public KinectStream this[KinectStreams stream]
@ -51,4 +55,4 @@ namespace Lib
}
}
}
}
}

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using KinectUtils;
namespace MyGesturesBank
{
public class AllGesturesFactory : IGestureFactory
{
public IEnumerable<BaseGesture> CreateGestures()
{
return new List<BaseGesture>
{
new SwipeRightHand(),
new PostureHandsOnHead(),
new PostureHandUp(),
new RightHandUp(),
new ClapHands(),
// Ajoutez d'autres gestes ici
};
}
}
}

@ -0,0 +1,67 @@
using KinectUtils;
using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace MyGesturesBank
{
public class ClapHands : Gesture
{
private CameraSpacePoint previousRightHandPosition;
private CameraSpacePoint previousLeftHandPosition;
private bool isClapInitiated = false;
protected override bool TestInitialConditions(Body body)
{
// Initial conditions are not strict for a clap, start directly with TestPosture and TestRunningGesture
return true;
}
protected override bool TestPosture(Body body)
{
var handRight = body.Joints[JointType.HandRight].Position;
var handLeft = body.Joints[JointType.HandLeft].Position;
if (!isClapInitiated)
{
previousRightHandPosition = handRight;
previousLeftHandPosition = handLeft;
isClapInitiated = true;
return false; // Wait for the next frame to start evaluation
}
// Check if hands moved closer since the last frame
bool handsMovingCloser =
(handRight.X - previousRightHandPosition.X) < 0 &&
(handLeft.X - previousLeftHandPosition.X) > 0;
// Update positions for next comparison
previousRightHandPosition = handRight;
previousLeftHandPosition = handLeft;
// Consider hand movement towards each other as part of the posture check
return handsMovingCloser && Math.Abs(handRight.Y - handLeft.Y) < 0.2f;
}
protected override bool TestRunningGesture(Body body)
{
// This method could be used to check for the continuation of the gesture, if necessary
return true;
}
protected override bool TestEndConditions(Body body)
{
var handRight = body.Joints[JointType.HandRight].Position;
var handLeft = body.Joints[JointType.HandLeft].Position;
// End condition based on proximity of hands
return Math.Abs(handRight.X - handLeft.X) < 0.1f;
}
public override string GestureName => "Clap Hands";
}
}

@ -42,13 +42,16 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="AllGesturesFactory.cs" />
<Compile Include="ClapHands.cs" />
<Compile Include="PostureHandsOnHead .cs" />
<Compile Include="PostureHandUp.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RightHandUp.cs" />
<Compile Include="TwoHandsDragon.cs" />
<Compile Include="SwipeRightHand.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KinectUtils\KinectUtils.csproj">

@ -7,11 +7,13 @@ namespace MyGesturesBank
{
protected override bool TestPosture(Body body)
{
// Exemple de condition : la main droite est plus haute que l'épaule droite
return body.Joints[JointType.HandRight].Position.Y > body.Joints[JointType.ShoulderRight].Position.Y;
var handRight = body.Joints[JointType.HandRight].Position;
var handLeft = body.Joints[JointType.HandLeft].Position;
var head = body.Joints[JointType.Head].Position;
return handRight.Y > head.Y || handLeft.Y > head.Y;
}
public override string GestureName => "Hand Up";
public override string GestureName => "Posture Hand Up";
}
}

@ -8,27 +8,17 @@ namespace MyGesturesBank
{
protected override bool TestPosture(Body body)
{
// Condition pour la main droite proche de la tête
bool rightHandNearHead = IsHandNearHead(body.Joints[JointType.HandRight], body.Joints[JointType.Head]);
var handRight = body.Joints[JointType.HandRight].Position;
var handLeft = body.Joints[JointType.HandLeft].Position;
var head = body.Joints[JointType.Head].Position;
// Condition pour la main gauche proche de la tête
bool leftHandNearHead = IsHandNearHead(body.Joints[JointType.HandLeft], body.Joints[JointType.Head]);
// Ajustez les seuils selon la précision souhaitée
var threshold = 0.1f; // Seuil pour ajuster la précision de la détection
return rightHandNearHead && leftHandNearHead;
return Math.Abs(handRight.Y - head.Y) < threshold
&& Math.Abs(handLeft.Y - head.Y) < threshold;
}
private bool IsHandNearHead(Joint hand, Joint head)
{
// Exemple de condition : la main est à moins de 30 cm de la tête
return Math.Sqrt(
Math.Pow(hand.Position.X - head.Position.X, 2) +
Math.Pow(hand.Position.Y - head.Position.Y, 2) +
Math.Pow(hand.Position.Z - head.Position.Z, 2)) < 0.3;
}
public override string GestureName => "Hands On Head";
public override string GestureName => "Posture Hands On Head";
}
}

@ -1,12 +1,23 @@
using System;
using KinectUtils;
using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibMyGesturesBank
namespace MyGesturesBank
{
internal class RightHandUp
public class RightHandUp : Posture
{
protected override bool TestPosture(Body body)
{
var handRight = body.Joints[JointType.HandRight].Position;
var head = body.Joints[JointType.Head].Position;
return handRight.Y > head.Y;
}
public override string GestureName => "Right Hand Up";
}
}

@ -0,0 +1,79 @@
using KinectUtils;
using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyGesturesBank
{
public class SwipeRightHand : Gesture
{
private float previousX = float.NaN;
private bool gestureStarted = false;
protected override bool TestInitialConditions(Body body)
{
var handRight = body.Joints[JointType.HandRight].Position;
var shoulderRight = body.Joints[JointType.ShoulderRight].Position;
// Conditions initiales : main droite au niveau ou à droite de l'épaule droite, mais pas trop éloignée
bool initialCondition = handRight.X >= shoulderRight.X && handRight.X - shoulderRight.X < 0.4f;
if (initialCondition && !gestureStarted)
{
// Si les conditions initiales sont remplies et que le geste n'a pas encore commencé,
// initialiser previousX et marquer le geste comme commencé
previousX = handRight.X;
gestureStarted = true;
return false; // Attendre le prochain frame pour commencer l'évaluation
}
return initialCondition;
}
protected override bool TestPosture(Body body)
{
var handRight = body.Joints[JointType.HandRight].Position;
var head = body.Joints[JointType.Head].Position;
// La main droite ne doit pas être plus haute que la tête
return handRight.Y <= head.Y;
}
protected override bool TestRunningGesture(Body body)
{
if (!gestureStarted) return false; // Assurer que le geste a commencé correctement
var handRight = body.Joints[JointType.HandRight].Position.X;
if (!float.IsNaN(previousX))
{
// Vérifie si la main droite se déplace vers la droite
bool isMovingRight = handRight > previousX;
previousX = handRight;
return isMovingRight;
}
previousX = handRight;
return false;
}
protected override bool TestEndConditions(Body body)
{
var handRight = body.Joints[JointType.HandRight].Position;
var spineBase = body.Joints[JointType.SpineBase].Position;
// Condition de fin : la main droite est bien à droite de la base de la colonne vertébrale
if (handRight.X > spineBase.X + 0.8f) // Ajustez cette valeur selon le besoin
{
gestureStarted = false; // Réinitialiser l'état du geste
previousX = float.NaN; // Préparer pour la prochaine détection
return true;
}
return false;
}
public override string GestureName => "Swipe Right Hand";
}
}

@ -1,12 +1,24 @@
using System;
using KinectUtils;
using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibMyGesturesBank
namespace MyGesturesBank
{
internal class TwoHandsDragon
public class TwoHandsDragon : Posture
{
protected override bool TestPosture(Body body)
{
var handRight = body.Joints[JointType.HandRight].Position;
var handLeft = body.Joints[JointType.HandLeft].Position;
var head = body.Joints[JointType.Head].Position;
return handRight.Y > head.Y && handLeft.Y > head.Y;
}
public override string GestureName => "Two Hands Dragon";
}
}

@ -11,7 +11,5 @@ namespace WpfApp
/// <summary>
/// Logique d'interaction pour App.xaml
/// </summary>
public partial class App : Application
{
}
public partial class App : Application { }
}

@ -11,9 +11,10 @@ namespace WpfApp
public class Bone : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if(PropertyChanged != null)
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
@ -23,23 +24,17 @@ namespace WpfApp
public double Top
{
get { return _top; }
set {
set
{
_top = value;
OnPropertyChanged(nameof(Top));
}
}
public double Left
{
get;
set;
}
public double Left { get; set; }
public double Diameter
{
get
{
return _diameter;
}
get { return _diameter; }
set
{
_diameter = value;
@ -47,9 +42,6 @@ namespace WpfApp
}
}
private double _diameter;
public SolidColorBrush ColorBrush {
get;
set;
}
public SolidColorBrush ColorBrush { get; set; }
}
}

@ -9,9 +9,9 @@ namespace WpfApp
{
class Bones : Collection<Bone>
{
public Bones() {
public Bones()
{
Add(new Bone { });
}
}
}

@ -22,7 +22,7 @@ namespace WpfApp
/// <summary>
/// Logique d'interaction pour MainWindow.xaml
/// </summary>
public partial class MainWindow : Window,INotifyPropertyChanged
public partial class MainWindow : Window, INotifyPropertyChanged
{
private KinectManager kinectManager;
public KinectManager KinectManager
@ -34,7 +34,8 @@ namespace WpfApp
public KinectStream CurrentKinectStream
{
get { return _currentKinectStream; }
set {
set
{
_currentKinectStream = value;
OnPropertyChanged(nameof(CurrentKinectStream));
}
@ -63,10 +64,8 @@ namespace WpfApp
Debug.WriteLine(CurrentKinectStream.KinectManager.StatusText);
CurrentKinectStream.Start();
Debug.WriteLine(CurrentKinectStream.KinectManager.StatusText);
}
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Debug.WriteLine(CurrentKinectStream.KinectManager.StatusText);
@ -104,6 +103,7 @@ namespace WpfApp
Debug.WriteLine(CurrentKinectStream.GetType().Name);
CurrentKinectStream.Start();
}
private void ToColorAndBodyImageStream(object sender, RoutedEventArgs e)
{
CurrentKinectStream.Stop();
@ -112,4 +112,4 @@ namespace WpfApp
CurrentKinectStream.Start();
}
}
}
}

@ -33,14 +33,13 @@ using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //où se trouvent les dictionnaires de ressources spécifiques à un thème
//(utilisé si une ressource est introuvable dans la page,
// ou dictionnaires de ressources de l'application)
//(utilisé si une ressource est introuvable dans la page,
// ou dictionnaires de ressources de l'application)
ResourceDictionaryLocation.SourceAssembly //où se trouve le dictionnaire de ressources générique
//(utilisé si une ressource est introuvable dans la page,
// dans l'application ou dans l'un des dictionnaires de ressources spécifiques à un thème)
//(utilisé si une ressource est introuvable dans la page,
// dans l'application ou dans l'un des dictionnaires de ressources spécifiques à un thème)
)]
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
//
// Version principale

@ -16,8 +16,10 @@ namespace WpfApp
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is BodyImageStream) return ColorAndBodyImageStreamTemplate;
else return OtherStreamTemplate;
if (item is BodyImageStream)
return ColorAndBodyImageStreamTemplate;
else
return OtherStreamTemplate;
}
}
}

Loading…
Cancel
Save