質問者
[Kinect SDK 1.8] DepthImageStream.OpenNextFrame(int)がSystem.InvalidCastException例外を送出する

質問
-
C#とWPFでKinectを勉強しているのですが, 次のコードをデバッグして実行すると, 以下のような例外が送出されて, 打つ手がなくて困っています. エラーが発生する部分のコードにはコメントを付けています.
例外 :
型 'System.InvalidCastException' のハンドルされていない例外が Microsoft.Kinect.dll で発生しました
追加情報:型 'System.__ComObject' の COM オブジェクトをインターフェイス型 'Microsoft.Kinect.Interop.INuiFrameTexture' にキャストできません。IID '{13EA17F5-FF2E-4670-9EE5-1297A6E880D1}' が指定されたインターフェイスの COM コンポーネント上での QueryInterface 呼び出しのときに次のエラーが発生したため、この操作に失敗しました: インターフェイスがサポートされていません (HRESULT からの例外:0x80004002 (E_NOINTERFACE))。
ソースコード :
MainWindow.xaml.cs
using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;using Microsoft.Kinect;
namespace Kinect_BodyPart
{
public partial class MainWindow : Window
{
public static readonly DependencyProperty personImageProperty =
DependencyProperty.Register(
"personImage", typeof(WriteableBitmap), typeof(MainWindow),
new PropertyMetadata(null));public WriteableBitmap personImage
{
get { return (WriteableBitmap)this.GetValue(MainWindow.personImageProperty); }
set { this.SetValue(MainWindow.personImageProperty, value); }
}public KinectSensor kinectSensor;
public Skeleton skeleton;
public Int32Rect screenImageRect;
public byte[] colorPixelData;
public short[] depthPixelData;// 右手, 左手, 頭のセンサーとの距離
public float rightHandZ;
public float leftHandZ;
public float headZ;public double depth;
public object lockObject = new object();
public MainWindow()
{
this.InitializeComponent();this.kinectSensor = null;
this.skeleton = null;
this.colorPixelData = null;
this.depthPixelData = null;this.rightHandZ = 0.0f;
this.leftHandZ = 0.0f;
this.headZ = 0.0f;
this.depth = 1000.0;this.Loaded += MainWindow_Loaded;
this.Closing += MainWindow_Closing;
}public void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.InitializeKinect();
}public void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (this.kinectSensor != null)
{
if (this.kinectSensor.IsRunning)
{
CompositionTarget.Rendering -= this.CompositionTarget_Rendering;
this.kinectSensor.AllFramesReady -= this.kinectSensor_AllFramesReady;
this.kinectSensor.Stop();
this.kinectSensor.Dispose();
}
}
}public void InitializeKinect()
{
// Kinectが接続されていない場合
if (KinectSensor.KinectSensors.Count == 0)
{
MessageBox.Show("Kinectが接続されていません.", "エラー", MessageBoxButton.OK, MessageBoxImage.Error);
Environment.Exit(0);
}try
{
this.kinectSensor = KinectSensor.KinectSensors[0];
this.kinectSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
this.kinectSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
this.kinectSensor.SkeletonStream.Enable();
this.kinectSensor.AllFramesReady += kinectSensor_AllFramesReady;DepthImageStream depthStream = this.kinectSensor.DepthStream;
this.colorPixelData = new byte[this.kinectSensor.ColorStream.FramePixelDataLength];
this.depthPixelData = new short[depthStream.FramePixelDataLength];this.personImage = new WriteableBitmap(
depthStream.FrameWidth, depthStream.FrameHeight,
96, 96, PixelFormats.Bgr32, null);this.screenImageRect = new Int32Rect(
0, 0,
(int)Math.Ceiling(this.personImage.Width),
(int)Math.Ceiling(this.personImage.Height));
this.kinectSensor.Start();CompositionTarget.Rendering += CompositionTarget_Rendering;
this.DataContext = this;
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "エラー", MessageBoxButton.OK, MessageBoxImage.Error);
Environment.Exit(0);
}
}
public void CompositionTarget_Rendering(object sender, EventArgs e)
{
using (ColorImageFrame colorImageFrame = this.kinectSensor.ColorStream.OpenNextFrame(100))
{
using (DepthImageFrame depthImageFrame = this.kinectSensor.DepthStream.OpenNextFrame(100)) // <- エラー!
{
this.RenderScreen(colorImageFrame, depthImageFrame);
}
}
}public void RenderScreen(ColorImageFrame colorImageFrame, DepthImageFrame depthImageFrame)
{
if (this.kinectSensor == null || colorImageFrame == null || depthImageFrame == null)
return;this.textBlock.Text = string.Empty;
int depth = 0;
int depthPixelIndex = 0;
int player = 0;
int colorPixelIndex = 0;
int imageIndex = 0;
ColorImagePoint colorImagePoint;int colorImageStride = colorImageFrame.BytesPerPixel * colorImageFrame.Width;
int playerImageStride = colorImageFrame.BytesPerPixel * depthImageFrame.Width;byte[] playerImage = new byte[depthImageFrame.Height * playerImageStride];
colorImageFrame.CopyPixelDataTo(this.colorPixelData);
depthImageFrame.CopyPixelDataTo(this.depthPixelData);for (int depthY = 0; depthY < depthImageFrame.Height; depthY++)
{
int depthX = 0;
while (depthX < depthImageFrame.Width)
{
depthPixelIndex = depthX + (depthY * depthImageFrame.Width);
player = this.depthPixelData[depthPixelIndex] & DepthImageFrame.PlayerIndexBitmask;
colorImagePoint = this.kinectSensor.MapDepthToColorImagePoint(
depthImageFrame.Format, depthX, depthY, this.depthPixelData[depthPixelIndex],
colorImageFrame.Format);
colorPixelIndex = colorImagePoint.X * colorImageFrame.BytesPerPixel +
colorImagePoint.Y * colorImageStride;if (player != 0)
{
depth = this.depthPixelData[depthPixelIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;
if (depth < this.depth)
{
playerImage[imageIndex] = this.colorPixelData[colorPixelIndex];
playerImage[imageIndex + 1] = this.colorPixelData[colorPixelIndex + 1];
playerImage[imageIndex + 2] = this.colorPixelData[colorPixelIndex + 2];if (this.rightHandZ * 1000.0f < this.depth)
this.textBlock.Text = "右手が検出されました.";if (this.leftHandZ * 1000.0f < this.depth)
this.textBlock.Text = "左手が検出されました.";if (this.rightHandZ * 1000.0f < this.depth && this.leftHandZ * 1000.0f < this.depth)
this.textBlock.Text = "両手が検出されました.";if (this.headZ * 1000.0f < this.depth)
this.textBlock.Text = "頭が検出されました.";
}
}
depthX++;
imageIndex += colorImageFrame.BytesPerPixel;
}
}
this.personImage.WritePixels(this.screenImageRect, playerImage, playerImageStride, 0);
}public void kinectSensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame == null)
return;Skeleton[] skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);this.skeleton = (from trackedSkeleton in skeletons
where trackedSkeleton.TrackingState == SkeletonTrackingState.Tracked
select trackedSkeleton).FirstOrDefault();if (this.skeleton == null)
return;
}
using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())
{
this.GetCameraPoint(depthImageFrame);
}
}public void GetCameraPoint(DepthImageFrame depthImageFrame)
{
try
{
if (depthImageFrame != null)
{
DepthImagePoint leftHandDepthImagePoint =
depthImageFrame.MapFromSkeletonPoint(
this.skeleton.Joints[JointType.HandLeft].Position);
DepthImagePoint rightHandDepthImagePoint =
depthImageFrame.MapFromSkeletonPoint(
this.skeleton.Joints[JointType.HandRight].Position);
DepthImagePoint headDepthImagePoint =
depthImageFrame.MapFromSkeletonPoint(
this.skeleton.Joints[JointType.Head].Position);ColorImagePoint leftHandColorImagePoint =
depthImageFrame.MapToColorImagePoint(
leftHandDepthImagePoint.X, leftHandDepthImagePoint.Y,
ColorImageFormat.RgbResolution640x480Fps30);
ColorImagePoint rightHandColorImagePoint =
depthImageFrame.MapToColorImagePoint(
rightHandDepthImagePoint.X, rightHandDepthImagePoint.Y,
ColorImageFormat.RgbResolution640x480Fps30);
ColorImagePoint headColorImagePoint =
depthImageFrame.MapToColorImagePoint(
headDepthImagePoint.X, headDepthImagePoint.Y,
ColorImageFormat.RgbResolution640x480Fps30);this.leftHandZ = depthImageFrame.MapToSkeletonPoint(
leftHandColorImagePoint.X, leftHandColorImagePoint.Y).Z;
this.rightHandZ = depthImageFrame.MapToSkeletonPoint(
rightHandColorImagePoint.X, rightHandColorImagePoint.Y).Z;
this.headZ = depthImageFrame.MapToSkeletonPoint(
headColorImagePoint.X, headColorImagePoint.Y).Z;
}
}
catch (Exception)
{
return;
}
}
}
}MainWindow.xaml
<Window x:Class="Kinect_BodyPart.MainWindow"
xmlns=".."
xmlns:x=".."
Title="身体の部位の認識" Height="600" Width="960" ResizeMode="NoResize">
<Grid>
<Image x:Name="sourceImage" VerticalAlignment="Top" Height="480" Margin="10,10,0,0"
HorizontalAlignment="Left" Width="640" Stretch="Uniform"
Source="{Binding personImage}"/>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="10,495,0,0"
TextWrapping="Wrap" Text="" VerticalAlignment="Top"
FontSize="16" FontWeight="Normal" Foreground="Red" Width="640"/>
</Grid>
</Window>