我是Kinect的新手。我正在尝试使用骨架跟踪,但我一直收到此警告“警告:ImageFrame实例未处理。”。你知道任何解决方案吗?
这是我的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
using Coding4Fun.Kinect.Wpf;
using System.Diagnostics;
using System.IO;
namespace KinectSkeleton
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
bool closing = false;
const int skeletonCount = 6;
Skeleton[] allSkeletons = new Skeleton[skeletonCount];
private void Window_Loaded(object sender, RoutedEventArgs e)
{
myKinectSensorChooser.KinectSensorChanged += new DependencyPropertyChangedEventHandler(myKinectSensorChooser_KinectSensorChanged);
}
void myKinectSensorChooser_KinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
{
KinectSensor oldSensor = (KinectSensor)e.OldValue;
if (oldSensor != null)
{
oldSensor.Stop();
oldSensor.AudioSource.Stop();
}
KinectSensor mySensor = (KinectSensor)e.NewValue;
if (mySensor == null)
return;
mySensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
mySensor.ColorStream.Enable();
mySensor.SkeletonStream.Enable();
mySensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(mySensor_AllFramesReady);
try
{
mySensor.Start();
Debug.WriteLine("Starting Sensor .....");
Debug.WriteLine("The Current Elevation Angle is: " + mySensor.ElevationAngle.ToString());
mySensor.ElevationAngle = 0;
}
catch (System.IO.IOException)
{
//another app is using Kinect
myKinectSensorChooser.AppConflictOccurred();
}
}
void mySensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
if (closing)
return;
byte[] depthImagePixels;
DepthImageFrame depthFrame = e.OpenDepthImageFrame();
if (depthFrame == null)
return;
depthImagePixels = GenerateDepthImage(depthFrame);
int stride = depthFrame.Width*4;
image1.Source =
BitmapSource.Create(depthFrame.Width, depthFrame.Height,
96, 96, PixelFormats.Bgr32, null, depthImagePixels, stride);
//Get a skeleton
Skeleton first = GetFirstSkeleton(e);
if (first == null)
return;
Debug.WriteLine("Head Position is : " + first.Joints[JointType.Head].ToString());
depthFrame.Dispose();
}
private byte[] GenerateDepthImage(DepthImageFrame depthFrame)
{
//get the raw data from the frame with the depth for every pixel
short[] rawDepthData = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(rawDepthData);
//use frame to create the image to display on-screen
//frame contains color information for all pixels in image
//Height x Width x 4 (Red, Green, Blue, empty byte)
Byte[] pixels = new byte[depthFrame.Height * depthFrame.Width * 4];
//hardcoded locations to Blue, Green, Red (BGR) index positions
const int BlueIndex = 0;
const int GreenIndex = 1;
const int RedIndex = 2;
int player, depth;
//loop through all distances
//pick a RGB color based on distance
for (int depthIndex = 0, colorIndex = 0;
depthIndex < rawDepthData.Length && colorIndex < pixels.Length;
depthIndex++, colorIndex += 4)
{
//get the player (requires skeleton tracking enabled for values)
player = rawDepthData[depthIndex] & DepthImageFrame.PlayerIndexBitmask;
//gets the depth value
depth = rawDepthData[depthIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;
if (player > 0)
{
pixels[colorIndex + BlueIndex] = Colors.Gold.B;
pixels[colorIndex + GreenIndex] = Colors.Gold.G;
pixels[colorIndex + RedIndex] = Colors.Gold.R;
}
else
{
pixels[colorIndex + BlueIndex] = Colors.Green.B;
pixels[colorIndex + GreenIndex] = Colors.Green.G;
pixels[colorIndex + RedIndex] = Colors.Green.R;
}
}
//depthFrame.Dispose();
return pixels;
}
Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e)
{
using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
{
if (skeletonFrameData == null)
{
return null;
}
skeletonFrameData.CopySkeletonDataTo(allSkeletons);
//get the first tracked skeleton
Skeleton first = (from s in allSkeletons
where s.TrackingState == SkeletonTrackingState.Tracked
select s).FirstOrDefault();
return first;
}
}
void StopKinect(KinectSensor sensor)
{
if (sensor != null)
{
if (sensor.IsRunning)
{
sensor.ElevationAngle = 0;
sensor.Stop();
if (sensor.AudioSource != null)
{
sensor.AudioSource.Stop();
}
}
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
closing = true;
Debug.WriteLine("Closing window...");
StopKinect(myKinectSensorChooser.Kinect);
}
}
}
非常感谢, 迈克尔
答案 0 :(得分:4)
在你写的方法mySensor_AllFramesReady中
//Get a skeleton
Skeleton first = GetFirstSkeleton(e);
if (first == null)
return; // Here if first skeleton is null then you are returning without disposing depthFrame frame.
打开深度框时使用块,如下所示
using(DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame == null)
return;
depthImagePixels = GenerateDepthImage(depthFrame);
int stride = depthFrame.Width*4;
image1.Source =
BitmapSource.Create(depthFrame.Width, depthFrame.Height,
96, 96, PixelFormats.Bgr32, null, depthImagePixels, stride);
//Get a skeleton
Skeleton first = GetFirstSkeleton(e);
if (first == null)
return;
Debug.WriteLine("Head Position is : " + first.Joints[JointType.Head].ToString());
}