C# 是否可以提取播放器';s仅深度像素,超出深度位图?

C# 是否可以提取播放器';s仅深度像素,超出深度位图?,c#,kinect,pixel,depth,C#,Kinect,Pixel,Depth,我是kinect开发的新手,也是stackoverflow的新手! 我的情况如下: 有了深度相机,我可以很容易地获得深度数据。我想做的是,一旦我检测到摄像机前有人(玩家),我将只提取玩家的深度像素,并将其置于透明背景上,这样输出的是透明背景上的玩家深度图像的静态图像。 我想问一下能做这项工作吗?我做了一些研究,发现一些函数可能有助于实现这一点,如SkeletonDepthimage()或深度像素数据(包括距离和玩家索引)。我假设您的意思是,您希望根据深度数据渲染玩家的轮廓,仅显示其轮廓。对吗 提

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

有了深度相机,我可以很容易地获得深度数据。我想做的是,一旦我检测到摄像机前有人(玩家),我将只提取玩家的深度像素,并将其置于透明背景上,这样输出的是透明背景上的玩家深度图像的静态图像。


我想问一下能做这项工作吗?我做了一些研究,发现一些函数可能有助于实现这一点,如SkeletonDepthimage()或深度像素数据(包括距离和玩家索引)。

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

提供了多个示例,正好可以实现这一点。“绿色屏幕”示例向您展示了如何提取深度数据并将其映射到颜色流,以便仅显示所选背景上的播放器。“基本交互”示例有一个轮廓示例,它正是我解释您想要的

查看Microsoft提供的示例,以充分了解Kinect的许多基本使用场景

基于基本交互项目中的剪影示例,我编写了一个剪影控件。控件的核心由以下两个功能组成(即,实际生成轮廓的功能)

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;
        }
    }
}
私有void OnSkeletonFrameReady(对象发送方,SkeletonFrameReadyEventArgs e)
{
使用(SkeletonFrame SkeletonFrame=e.OpenSkeletonFrame())
{
if(skeletonFrame!=null&&skeletonFrame.SkeletonArrayLength>0)
{
if(_skeletons==null | | | u skeletons.Length!=skeletonFrame.skeletonarraylelength)
{
_skeletons=新骨架[skeletonFrame.SkeletonArrayleLength];
}
skeletonFrame.CopySkeletonDataTo(_skeletons);
//抓取跟踪的骨骼并设置playerIndex以供使用
//为轮廓输出深度数据。
//TODO:假设只有一个跟踪骨架,我们希望找到
//被追踪骨架中最近的人(见上文)。
this.playerIndex=-1;
对于(int i=0;i<_skeletons.Length;i++)
{
if(_skeletons[i].TrackingState!=SkeletonTrackingState.NotTracked)
{
this.playerIndex=i+1;
}
}
}
}
}
私有void OnDepthFrameReady(对象发送方,DepthImageFrameReadyEventArgs e)
{
使用(DepthImageFrame depthFrame=e.OpenDepthImageFrame())
{
if(depthFrame!=null)
{
//检查格式是否已更改。
bool haveNewFormat=this.lastImageFormat!=depthFrame.Format;
if(haveNewFormat)
{
this.pixelData=新短[depthFrame.PixelDataLength];
this.depthFrame32=新字节[depthFrame.Width*depthFrame.Height*bgra32bytesperpoixel];
this.convertedDepthBits=新字节[this.depthFrame32.Length];
}
depthFrame.CopyPixelDataTo(this.pixelData);
对于(inti16=0,i32=0;i160)
{
convertedDepthBits[i32+RedIndex]=0xBC;
convertedDepthBits[i32+绿色索引]=0xBE;
convertedDepthBits[i32+BlueIndex]=0xC0;
convertedDepthBits[i32+3]=0x66;
}
其他的
{
convertedDepthBits[i32+RedIndex]=0x0;
convertedDepthBits[i32+绿色索引]=0x0;
convertedDepthBits[i32+BlueIndex]=0x0;
convertedDepthBits[i32+3]=0x0;
}
}
if(剪影==null | | haveNewFormat)
{
剪影=新的WriteableBitmap(
深度,宽度,
深度框架高度,
96,
96,
PixelFormats.Bgra32,
无效);
剪影图像。来源=剪影;
}
剪影。可写像素(
新的Int32Rect(0,0,depthFrame.Width,depthFrame.Height),
转换的深比特,
深度帧宽度*BGRA32字节/像素,
0);
剪影=剪影;
this.lastImageFormat=depthFrame.Format;
}
}
}

是的,这正是我想要的!非常感谢,我将继续做这项工作:)@Evil-closure-Monkey,是否可以为骨骼添加额外的关节?例如,如果一个人拿着一根棍子,那么骨架将添加一个表示棍子的额外关节?如果你能让我知道是否有任何解决办法?