Kinect的帧到达异步 [英] Kinect Frame Arrived Asynchronous

查看:327
本文介绍了Kinect的帧到达异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要寻找一些帮助,我在Kinect的SDK V2事件MultiSourceFrameArrived

I am looking for some help with my MultiSourceFrameArrived event in the Kinect v2 SDK.

以下是问题的方法:

    private async void _reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
    {
        MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame();

        using (var colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame())
        {
            if (colorFrame != null)
            {
                _writeableBitmap.Lock();
                colorFrame.CopyConvertedFrameDataToIntPtr(
                    _writeableBitmap.BackBuffer,
                    (uint)(_colorFrameDescription.Width * _colorFrameDescription.Height * _colorFrameDescription.BytesPerPixel),
                    ColorImageFormat.Bgra);
                _writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, _writeableBitmap.PixelWidth, _writeableBitmap.PixelHeight));
                _writeableBitmap.Unlock();
                reflectionOverlayControl.ReflectionImageSource = _writeableBitmap;
            }
        }

        using (var bodyFrame = multiSourceFrame.BodyFrameReference.AcquireFrame())
        {
            if (bodyFrame != null)
            {
                Body body = JointHelpers.FindClosestBody(bodyFrame);

                if (body != null)
                {
                    if (body.IsTracked)
                    {
                        Dictionary<BodyComponentType, BodyComponent> bodyComponentDictionary = BuildBodyComponentDictionary(body);

                        foreach (BodyComponent bodyComponent in bodyComponentDictionary.Values.OrderBy(x => x.BodyComponentType))
                        {
                            bodyComponent.Generate(_writeableBitmap, _coordinateMapper, FrameType.Color, 25);
                            if (!_isRunningFiltering)
                            {
                                _isRunningFiltering = true;
                                try
                                { 
                                    await Task.Run(() =>
                                        {
                                            bodyComponent.RunFunFiltering();
                                        });
                                }
                                finally
                                {
                                    _isRunningFiltering = false;
                                }
                            }
                        }
                        reflectionOverlayControl.UpdateValues(
                               bodyComponentDictionary,
                               GetFullBodyComponent(body));
                    }
                }
            }
        }
    }

现在,请允许我解释一下:

Now, allow me to explain:


  • 的方法,当一种特定的帧从Kinect的到来运行,这是后天,我可以在使用块提取ColorFrame和BodyFrame出来。

  • 第一个用块轮番ColorFrame到WPF WriteableBitmap的(在构造函数中声明),并设置用户控件的ReflectionImageSource设置等于这个WriteableBitmap的。如果这是唯一使用块,我会看到非常流畅的饲料在屏幕上!

  • 使用第二BodyFrame确定最接近体,如果它被跟踪,然后创建填充了一个人BodyComponents一个词典(手,脚,头部等)

  • 这里的foreach循环运行在每个BodyComponent,这台几个它的属性中的生成功能。例如,它设置一个EncompassingRectangle属性是一个旨在涵盖成分的Int32Rect对象。

接下来一位是我需要帮助!

该方法RunFunFiltering是,在运行时,将创建一个冻结了我的UI阻塞语句巨资密集的处理方法。这将有可能使我的彩色帧视频源很紧张的效果!此RunFunFiltering方法需要设置一些BodyComponent类的属性,如矩形,应显示的颜色,白色的像素的数目在它的ReflectionImageSource并设置另一个可写的位图与被包含在所述第一ReflectionImageSource的部分长方形。

The method RunFunFiltering is a heavily intensive processing method which, when run, would create a blocking statement that freezes up my UI. This would have the effect of making my color frame video feed very jumpy! This RunFunFiltering method needs to set some of the BodyComponent class's properties, such as the colour that the rectangle should be displayed, the number of white pixels in it's ReflectionImageSource and to set another writeable bitmap with the part of the first ReflectionImageSource which is contained in the rectangle.

由于这个对象现在已经完成,所有的属性进行设置(这已经在字典中为每个BodyComponent的完成)我跑在视图中UpdateValues​​方法,它显示了有趣的东西在BodyComponent类在屏幕上对我来说。

Since this object is now complete, with all properties set (and this has been done for each of the BodyComponent's in the dictionary) I run an UpdateValues method on the view, which displays the interesting stuff in the BodyComponent class on the screen for me.

继在这个岗位@sstan一些建议:<一href=\"http://stackoverflow.com/questions/32035816/async-await-to-keep-event-firing/32062805#32062805\">Async等待保持事件触发

Following some advice from @sstan in this post: Async Await to Keep Event Firing

我扔在Task.Run()块。然而,这似乎并没有被释放我的UI,我仍然看到一个跳动的形象。奇怪的是在计时器的例子,它完美的作品!我在一个有点损失这里知道该怎么办。

I threw in a Task.Run() block. However, this doesn't seem to be releasing my UI and I still see a jumpy image. The weird thing is in that timer example, that it works perfectly! I'm at a bit of a loss here to know what to do.

我有点异步功能的初学者,但我真的想了解您的解决方案。如果你能提供一个解释你的code,我会万分感谢!

I'm a bit of a beginner with asynchronous functions but I would really like to understand your solutions. If you can provide an explanation with your code I'd be extremely grateful!

更新

我已经能够确定using语句,其取得帧块时,它被放置在Task.Run通话之外。在UI

I have been able to identify that the using statement which acquires the frame blocks the UI when it is placed outside of the Task.Run call.

我不能只使用块异步运行,使整个BodyFrame因为我需要先生成功能为总是发生,不是重处理线程的一部分。使用两个看起来块不雅,并推而下的地毯,我的问题...

I can't just make the whole BodyFrame using block run asynchronously because I need the first "Generate" function to always happen and not be part of the heavy processing thread. Two using blocks seems inelegant and is rather pushing my question under the carpet...

推荐答案

从您的评论我的理解如下:

From your comment I understand the following:


  • 您有当一个帧到达被称为异步函数

  • 如果没有RunFunFiltering任务正在运行启动一台

  • 如果这样的任务正在运行时,不要启动一个新的

  • 如果RunFunFiltering完成处理结果

Task taskFunFiltering = null;

private async Task ProcessFrame(...)
{   // a new frame is arrived
    DoSomeProcessing(...);
    // only start a new run fun filtering if previous one is finished
    if (taskFunFiltering == null || taskFunFiltering.IsCompleted)
    {   // start a new fun filtering
        // don't wait for the result
        taskFunFiltering = Task.Run( () => ...);
    }
}

private async Task RunFunFiltering(...)
{
    // do the filtering and wait until finished
    var filterResult = await DoFiltering(...);
    DisplayResult(filterResult);
}

这篇关于Kinect的帧到达异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆