11 Şubat 2012 Cumartesi

Kinect Mouse

Eskilerden, ingilizce bir postum geliyor.


My first post will be about Kinect. As you know Microsoft has released a beta sdk for Windows use of Kinect. Which can be downloaded via this link.


The SDK is beta, maybe that is the reason that, we can see some ​inconsistency in the positions we get. You can see, your leg position is changing, even if you don't move it at all.


So let's start with building something.


Let's start with building a WPF application;






That was the hardest part :D


Now, if you installed the SDK, you have to add some dlls to your solution. To accomplish, right click to references and click "Add Reference".


The DLL files you have to add are:


Microsoft.Research.Kinect.dll;
Coding4Fun.Kinect.dll;


Coding4Fun contains an extension class, which helps us to scale the environment and get positions as pixels. You can find it here.


After you add required dlls (btw Kinect dll can be found in Program Files (x86)\Microsoft Research KinectSDK\) now it's time to add namespace directives:


using Microsoft.Research.Kinect.Nui;
using Coding4Fun.Kinect.Wpf;


Now, to start, we initialize a Kinect Runtime, which MUST be disposed when the user closes the application, unless if the user wants to see the red laser light coming from the depth camera all the time. :D

To initialize a runtime we type;




Runtime nuiRuntime;


public MainWindow()


{


    InitializeComponent();


    nuiRuntime = new Runtime();


    this.Closed += (sender, e) => nuiRuntime.Uninitialize();


}


As you know, we have depth sensor, rgb camera. We can start the peripheral in different ways. We can get pictures, video frames, or just skeleton positions, which is the only thing we need for kinectMouse.


To get skeleton positions, we add event handler, and then initialize nuiRuntime to get skeleton positions. Our code will look like:







Now, in SkeletonFrameReady event, arguement e holds skeletonframes. SkeletonFrames contains SkeletonData which has attributes such as:
TrackingState
TrackingID
Joints
Position




TrackingState must be tracked, we are going to move the mouse only if someone stands front of it. Tracking ID is the unique id given to each different skeleton. Joints holds positions for joints, and position is the general skeleton position.





The procedure we are going to watch will be:
We will have an id named humanID, will be something negative
humanID will be the TrackingID of first human tracked, if it is negative
When we get some tracked skeletons, we will get the one which has the same id with our humanID
If the skeleton we get is null (it's trackingID is not the same with our humanID), we get the first skeleton (if we have one or more) and our humanID gets the value of new trackingID.




The code we are going to produce will look like;















Now, in the block when human is not null; we can get the positions of wished body parts or the ones we can get with this SDK :D


I am a right-handed, so I am going to control the mouse with my right hand.


var rightHandPosition = human.Joints[JointID.HandRight].ScaleTo(1366, 768).Position;


This line gives us right hand position. JointID is an enum, contains ids for joints. I used ScaleTo extension function to get the position scaled on my computer screen.


The value we get from here is a Vector contains X,Y,Z, and W. We only need X and Y.


I can directly send the position to the mouse if i wish, but I want to make this program more reliable. Maybe it's beta, maybe because of other reasons, we can get some inconsistent position values as I mentioned. One way to eliminate those is creating a class which holds some position values (let's say like 5 values in a row), each time you add position inside, it gets the average of those values and moves the mouse to the average point with linear movement.





We call AddNewPoint when we get right handPosition, and it handles everything. When the positions we have is 5, it removes the oldest position in the list and adds the new one.
And then it gets the average point and sends the position to smoothTransform function which moves the mouse from the point it was, linearly.
We need System.Windows.Forms.dll in order to move the mouse. Or you can add MouseHook.
So our code will look like:







To test, connect your Kinect device to the USB port, and run the software. Make sure you are 2 meters away from Kinect! :D
If you want to make the form transparent, make it fullscreen and give it transparency key.

Hiç yorum yok:

Yorum Gönder