我正在从事一个项目,该项目涉及从 Kinect 相机的颜色和深度帧中提取特征。我面临的问题是,每当我尝试显示 2 个图像时,UI 都会挂起。当我尝试调试时,depthFrame 和 colorFrame 为空。如果只启用颜色流,那么 colorImage 和 featureImage1 都会正确显示,如果我只启用深度流,它应该可以正常工作。但是当我同时启用它们时,用户界面就会挂起。我不知道是什么导致了这个问题。我的 Kinect 应用程序有以下代码。这个问题的原因是什么,我该如何解决?配置:Windows 8 Pro 64bit,2Ghz Core2Duo,VisualStudio 2012 Ultimate,EmguCV 2.4.0。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
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 Emgu.CV;
using Emgu.CV.WPF;
using Emgu.CV.Structure;
using Emgu.Util;
namespace features
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private Image<Bgra, Byte> cvColorImage;
private Image<Gray, Int16> cvDepthImage;
private int colorWidth = 640;
private int colorHeight = 480;
private int depthWidth = 640;
private int depthHeight = 480;
private static readonly int Bgr32BytesPerPixel = (PixelFormats.Bgr32.BitsPerPixel + 7) / 8;
private byte[] colorPixels;
private byte[] depthPixels;
private short[] rawDepthData;
private bool first = true;
private bool firstDepth = true;
Image<Bgra, byte> image2;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
kinectSensorChooser.KinectSensorChanged += new DependencyPropertyChangedEventHandler(kinectSensorChooser_KinectSensorChanged);
}
void kinectSensorChooser_KinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
{
KinectSensor oldSensor = (KinectSensor)e.OldValue;
KinectStop(oldSensor);
KinectSensor _sensor = (KinectSensor)e.NewValue;
_sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
_sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
_sensor.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(_sensor_DepthFrameReady);
_sensor.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(_sensor_ColorFrameReady);
_sensor.DepthStream.FrameHeight);
try
{
_sensor.Start();
}
catch
{
kinectSensorChooser.AppConflictOccurred();
}
}
void KinectStop(KinectSensor sensor)
{
if (sensor != null)
{
sensor.Stop();
}
}
private void Window_Closed(object sender, EventArgs e)
{
KinectStop(kinectSensorChooser.Kinect);
}
void _sensor_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if (colorFrame == null) return;
if (first)
{
this.colorPixels = new Byte[colorFrame.PixelDataLength];
first = false;
}
colorFrame.CopyPixelDataTo(this.colorPixels); //raw data in bgrx format
processColor();
}
}
void _sensor_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame == null) return;
if (firstDepth)
{
this.rawDepthData = new short[depthFrame.PixelDataLength];
firstDepth = false;
}
depthFrame.CopyPixelDataTo(rawDepthData);
processDepth();
}
}
private void processColor(){...}
private void processDepth(){...}
}
}
processDepth 函数如下。我只是从 RAW 深度数据制作图像。
private void processDepth() {
GCHandle pinnedArray = GCHandle.Alloc(this.rawDepthData, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
cvDepthImage = new Image<Gray, Int16>(depthWidth, depthHeight, depthWidth << 1, pointer);
pinnedArray.Free();
depthImage.Source = BitmapSourceConvert.ToBitmapSource(cvDepthImage.Not().Bitmap);
}
processColor 函数如下。这里只是为了它,我试图显示克隆的图像而不是提取特征,只是为了检查滞后。当两个流都启用(颜色和深度)时,以下函数会正确显示 colorImage,但是一旦我取消注释注释行,UI 就会挂起。
private void processColor() {
GCHandle handle = GCHandle.Alloc(this.colorPixels, GCHandleType.Pinned);
Bitmap image = new Bitmap(colorWidth, colorHeight, colorWidth<<2, System.Drawing.Imaging.PixelFormat.Format32bppRgb, handle.AddrOfPinnedObject());
handle.Free();
cvColorImage = new Image<Bgra, byte>(image);
image.Dispose();
BitmapSource src = BitmapSourceConvert.ToBitmapSource(cvColorImage.Bitmap);
colorImage.Source = src;
//image2 = new Image<Bgra, byte>(cvColorImage.ToBitmap()); //uncomment and it hangs
//featureImage1.Source = BitmapSourceConvert.ToBitmapSource(image2.Bitmap); //uncomment and it hangs
}