是否可以仅从深度位图中提取播放器的深度像素? [英] Is it possible to extract the player's depth pixels only, out of the depth bitmap?

查看:68
本文介绍了是否可以仅从深度位图中提取播放器的深度像素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 kinect 开发的新手,也是 stackoverflow 的新手!这是我的情况:

I am new to kinect developing and new to stackoverflow as well! Here's my situation:

有了深度相机,我可以轻松获取深度数据.我想要做的是一旦我检测到一个人(玩家)存在于相机前,我只会提取玩家的深度像素,并将其放在透明背景上,以便输出是透明背景上仅播放器深度图像的静态图像.

Having a depth camera, I can get the depth data easily. What I want to do is once I detect there is a person (player) exists in front of the camera, I would extract the depth pixels of the player only, and put it onto a transparent background, so that the output is a static image of the depth image of the player only, on a transparent background.

我想问是否可以完成这项工作?我做了一些研究,发现一些函数可能有助于做到这一点,例如 SkeletonToDepthImage() 或深度像素数据(包括距离和玩家索引).

I would like to ask is it possible to do the job? I've done some research and find some functions may help to do so like SkeletonToDepthImage() or the depth pixel data (which includes the distance and player index).

推荐答案

我假设您的意思是您想根据深度数据渲染玩家的轮廓,仅显示其轮廓.对吗?

I'm assuming you mean that you want to render a silhouette of the player, based on the depth data, showing just their outline. Is that correct?

Kinect for Windows Developer Toolkit 提供了多种正是这样做的例子.绿屏"示例向您展示了如何提取深度数据并将其映射到颜色流以仅显示所选背景上的播放器.基本交互"示例有一个轮廓示例,它完全符合我的解释.

The Kinect for Windows Developer Toolkit provides multiple examples that does exactly this. The "green screen" examples show you how to extract the depth data and map it to the color stream to show just the player on a background of choice. The "Basic Interactions" example has a silhouette example that does exactly what I'm interpreting you to want.

查看 Microsoft 提供的示例,可以很好地了解 Kinect 的许多基本使用场景.

Look over the examples provided by Microsoft to get a good understanding of many of the basic use scenarios for the Kinect.

基于 Basic Interactions 项目中的剪影示例,我编写了一个剪影控件.控件的核心由以下两个函数组成(即实际产生轮廓的函数.

Based on the silhouette example from the Basic Interactions project, I wrote a silhouette control. The core of the control is made of the following two functions (i.e., the functions that actually produce the silhouette.

private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
    using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
    {
        if (skeletonFrame != null && skeletonFrame.SkeletonArrayLength > 0)
        {
            if (_skeletons == null || _skeletons.Length != skeletonFrame.SkeletonArrayLength)
            {
                _skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
            }

            skeletonFrame.CopySkeletonDataTo(_skeletons);

            // grab the tracked skeleton and set the playerIndex for use pulling
            // the depth data out for the silhouette.
            // TODO: this assumes only a single tracked skeleton, we want to find the
            // closest person out of the tracked skeletons (see above).
            this.playerIndex = -1;
            for (int i = 0; i < _skeletons.Length; i++)
            {
                if (_skeletons[i].TrackingState != SkeletonTrackingState.NotTracked)
                {
                    this.playerIndex = i+1;
                }
            }
        }
    }
}

private void OnDepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
    using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
    {
        if (depthFrame != null)
        {
            // check if the format has changed.
            bool haveNewFormat = this.lastImageFormat != depthFrame.Format;

            if (haveNewFormat)
            {
                this.pixelData = new short[depthFrame.PixelDataLength];
                this.depthFrame32 = new byte[depthFrame.Width * depthFrame.Height * Bgra32BytesPerPixel];
                this.convertedDepthBits = new byte[this.depthFrame32.Length];
            }

            depthFrame.CopyPixelDataTo(this.pixelData);

            for (int i16 = 0, i32 = 0; i16 < pixelData.Length && i32 < depthFrame32.Length; i16++, i32 += 4)
            {
                int player = pixelData[i16] & DepthImageFrame.PlayerIndexBitmask;
                if (player == this.playerIndex)
                {
                    convertedDepthBits[i32 + RedIndex] = 0x44;
                    convertedDepthBits[i32 + GreenIndex] = 0x23;
                    convertedDepthBits[i32 + BlueIndex] = 0x59;
                    convertedDepthBits[i32 + 3] = 0x66;
                }
                else if (player > 0)
                {
                    convertedDepthBits[i32 + RedIndex] = 0xBC;
                    convertedDepthBits[i32 + GreenIndex] = 0xBE;
                    convertedDepthBits[i32 + BlueIndex] = 0xC0;
                    convertedDepthBits[i32 + 3] = 0x66;
                }
                else
                {
                    convertedDepthBits[i32 + RedIndex] = 0x0;
                    convertedDepthBits[i32 + GreenIndex] = 0x0;
                    convertedDepthBits[i32 + BlueIndex] = 0x0;
                    convertedDepthBits[i32 + 3] = 0x0;
                }
            }

            if (silhouette == null || haveNewFormat)
            {
                silhouette = new WriteableBitmap(
                    depthFrame.Width,
                    depthFrame.Height,
                    96,
                    96,
                    PixelFormats.Bgra32,
                    null);

                SilhouetteImage.Source = silhouette;
            }

            silhouette.WritePixels(
                new Int32Rect(0, 0, depthFrame.Width, depthFrame.Height),
                convertedDepthBits,
                depthFrame.Width * Bgra32BytesPerPixel,
                0);

            Silhouette = silhouette;

            this.lastImageFormat = depthFrame.Format;
        }
    }
}

这篇关于是否可以仅从深度位图中提取播放器的深度像素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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