Question

I'm using some third party libraries to gesture detection in my Kinect based application. Everything works but I have only one small problem and it would be great if someone of you could help me.

To use this library I had to write kinect_SkeletonFrameReady like this:

    void kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
    {
        Skeleton[] skeletons = new Skeleton[0];

        using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
        {
            if (skeletonFrame != null)
            {
                skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
                skeletonFrame.CopySkeletonDataTo(skeletons);
            }
        }

        if (skeletons.Length > 0 && inter != null)
        {
            Skeleton first = null;
            int b = 0;
            while (b < skeletons.Length && first == null)
            {
                if (skeletons[b].TrackingState == SkeletonTrackingState.Tracked)
                    first = skeletons[b];
                b++;
            }
            if (first != null)
            {
                GDLWatch.Stop();
                double TimeHelp = GDLWatch.Elapsed.TotalSeconds;
                GDLWatch.Reset();
                GDLWatch.Start();
                Point3D[] bodyParts = GenerateBodyPartArray(first, 0);
                System.String[] con = inter.ReturnConclusions(bodyParts, 0, TimeHelp);
                System.String conclusionsString = "";
                for (int a = 0; a < con.Length; a++)
                {
                    conclusionsString += con[a] + "\r\n";
                    System.Diagnostics.Debug.WriteLine(conclusionsString);
                    if (conclusionsString.Contains("!"))
                    {
                        this.alreadyDone++;
                        this.RaisePropertyChanged(() => this.AlreadyDone);
                    }
                }
            }
        }
    }

The only problem is that variable allreadyDone is not increased once, but many times. I think that the data from sensor, match for gesture description for some period of time. How to increase this variable only once, when the gesture appears for the first time? Adding something lik break or return does not work here.

Was it helpful?

Solution 3

I found a solution. Had to add a property:

    private bool _isGestureCatched;
    private bool IsGestureCatched
    {
        get { return _isGestureCatched; }
        set
        {
            if (_isGestureCatched != value)
            {
                if (!IsGestureCatched)
                {
                    this._alreadyDone++;
                    this.RaisePropertyChanged(() => this.AlreadyDone);
                }            
            }

            _isGestureCatched = value;
        }
    } 

And then in SkeletonFrameReady have to set it like this:

if (conclusionsString.Contains("!"))
                {
                    IsGestureCatched = true;
                }
                else
                {
                    IsGestureCatched = false;
                }

It is working, only sometimes this code catched one gesture twice so if someone have better idea, is welcome, reply from @dav_i is helpfull

OTHER TIPS

Why not make alreadyDone a bool, then do:

alreadyDone &= true;

So if it has to be an int why not add another field/property: bool hasBeenCalled, then do:

alreadyDone += hasBeenCalled ? 0 : 1;

Another idea:

Why not modify your code to this - that way the loop is removed (which I think is your problem here):

// get the string[] from the method
var conclusionsStrings = inter.ReturnConclusions(bodyParts, 0, TimeHelp);
// combine each of the strings with a new line between each
var conclusionsString = String.Join(Environment.NewLine, conclusionsStrings);
// does the combined string have a ! in?
if (conclusionsString.Contains("!"))
{
    this.alreadyDone++;
    this.RaisePropertyChanged(() => this.AlreadyDone);
}

The above is also more performant because rather than doing string concatenation using += you're using .Join( which is in mscorlib.dll which means it gets access to the raw memory of the string rather than creating a new instance each time (see C# in Depth - Jon Skeet: Strings in C# and .NET for more info).

SkeletonFrameReady is fired every time a frame is ready in the stream. (See http://msdn.microsoft.com/en-us/library/microsoft.kinect.kinectsensor.skeletonstream.aspx). That means if you track motion there will come many frames over time, probably limited only to the power of the Kinect device and the computer.

So if you want to track the gesture once, you need to verify if it is already increased. Or do something like dav_i proposed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top