0

我正在使用一些第三方库在基于 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不起作用的东西。

4

3 回答 3

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#和 .NET了解更多信息)。

于 2013-11-21T13:48:38.967 回答
0

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

所以如果你想跟踪一次手势,你需要验证它是否已经增加了。或者做类似 dav_i 提议的事情。

于 2013-11-21T13:23:32.483 回答
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 的回复很有帮助

于 2013-11-22T06:17:51.080 回答