C# 是否可以提取播放器';s仅深度像素,超出深度位图?
我是kinect开发的新手,也是stackoverflow的新手! 我的情况如下: 有了深度相机,我可以很容易地获得深度数据。我想做的是,一旦我检测到摄像机前有人(玩家),我将只提取玩家的深度像素,并将其置于透明背景上,这样输出的是透明背景上的玩家深度图像的静态图像。C# 是否可以提取播放器';s仅深度像素,超出深度位图?,c#,kinect,pixel,depth,C#,Kinect,Pixel,Depth,我是kinect开发的新手,也是stackoverflow的新手! 我的情况如下: 有了深度相机,我可以很容易地获得深度数据。我想做的是,一旦我检测到摄像机前有人(玩家),我将只提取玩家的深度像素,并将其置于透明背景上,这样输出的是透明背景上的玩家深度图像的静态图像。 我想问一下能做这项工作吗?我做了一些研究,发现一些函数可能有助于实现这一点,如SkeletonDepthimage()或深度像素数据(包括距离和玩家索引)。我假设您的意思是,您希望根据深度数据渲染玩家的轮廓,仅显示其轮廓。对吗 提
我想问一下能做这项工作吗?我做了一些研究,发现一些函数可能有助于实现这一点,如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,是否可以为骨骼添加额外的关节?例如,如果一个人拿着一根棍子,那么骨架将添加一个表示棍子的额外关节?如果你能让我知道是否有任何解决办法?