在手势检测时增加一次变量

时间:2013-11-21 13:18:59

标签: c# events kinect-sdk nui

我正在使用一些第三方库在我的基于Kinect的应用程序中进行手势检测。一切正常,但我只有一个小问题,如果你们中的某个人可以帮助我,那就太好了。

要使用此库,我必须像这样编写kinect_SkeletonFrameReady

    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);
                    }
                }
            }
        }
    }

唯一的问题是变量allreadyDone不会增加一次,但会增加很多次。我认为来自传感器的数据,匹配一段时间的手势描述。当手势第一次出现时,如何仅增加此变量一次? 添加类似breakreturn的内容在此无效。

3 个答案:

答案 0 :(得分:2)

为什么不让alreadyDone成为bool,然后执行:

alreadyDone &= true;

因此,如果必须是int,为什么不添加其他字段/属性:bool hasBeenCalled,那么请执行:

alreadyDone += hasBeenCalled ? 0 : 1;

另一个想法:

为什么不修改你的代码 - 这样就删除了循环(我认为这是你的问题):

// 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);
}

上述内容也更具效果,因为您使用的string使用+=而不是使用.Join(进行mscorlib.dll连接,这意味着它可以访问原始版本string的记忆,而不是每次都创建一个新实例(有关详细信息,请参阅C# in Depth - Jon Skeet: Strings in C# and .NET)。

答案 1 :(得分:0)

每次在流中准备好帧时,都会触发

SkeletonFrameReady。 (见http://msdn.microsoft.com/en-us/library/microsoft.kinect.kinectsensor.skeletonstream.aspx)。这意味着如果你跟踪运动,随着时间的推移会出现很多帧,可能仅限于Kinect设备和计算机的功能。

因此,如果您想要跟踪手势一次,则需要验证它是否已经增加。或者像dav_i那样做。

答案 2 :(得分:0)

我找到了解决方案。不得不添加一个属性:

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

            _isGestureCatched = value;
        }
    } 

然后在SkeletonFrameReady中必须像这样设置:

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

它正在工作,有时候这段代码只抓了两次手势,所以如果有人有更好的想法,欢迎,来自@dav_i的回复是有帮助的