none
[Kinect SDK 1.8] DepthImageStream.OpenNextFrame(int)がSystem.InvalidCastException例外を送出する RRS feed

  • 質問

  • 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>

    2014年8月9日 8:23