質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • C#

    8511questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • OpenCV

    1429questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

  • Kinect

    101questions

    Kinect(キネクト)はマイクロソフトから発売されたジェスチャー・音声認識によって 操作ができるデバイスです。

KINECTで得られた画像をOpenCvSharpに渡して処理を行いたいです。

受付中

回答 0

投稿

  • 評価
  • クリップ 1
  • VIEW 343

keisuke1995

score 8

KINECTの深度情報から、ある一定距離以上のところを塗りつぶして二値化しています。ここまでは分かるのですが、ここからはOpencvsharpで処理を行いたいです(面積計算など)。Opencvsharpでの処理は、どこにプログラムを書くべきでしょうか?

また、どのようにしてKINECTからOpencvsharpに画像(深度画像)を渡せば良いのか教えてくれませんか?
以下は、KINECTから色画像と深度画像を得るプログラムです。

よろしくお願いいたします。

using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Navigation;
using OpenCvSharp;
using OpenCvSharp.Extensions;

using Microsoft.Kinect;

namespace KINECT_Opencv
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindow()
        {
            try
            {
                InitializeComponent();

                // Kinectが接続されているかどうかを確認する
                if (KinectSensor.KinectSensors.Count == 0)
                {
                    throw new Exception("Kinectを接続してください");
                }

                // Kinectの動作を開始する
                StartKinect(KinectSensor.KinectSensors[0]);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Close();
            }
        }

        /// <summary>
        /// Kinectの動作を開始する
        /// </summary>
        /// <param name="kinect"></param>
        private void StartKinect(KinectSensor kinect)
        {
            // RGBカメラを有効にして、フレーム更新イベントを登録する
            kinect.ColorStream.Enable();
            kinect.ColorFrameReady +=
              new EventHandler<ColorImageFrameReadyEventArgs>(kinect_ColorFrameReady);

            // 距離カメラを有効にして、フレーム更新イベントを登録する
            kinect.DepthStream.Enable();
            kinect.DepthFrameReady +=
              new EventHandler<DepthImageFrameReadyEventArgs>(kinect_DepthFrameReady);

            // Kinectの動作を開始する
            kinect.Start();

            // defaultモードとnearモードの切り替え
            comboBoxRange.Items.Clear();
            foreach (var range in Enum.GetValues(typeof(DepthRange)))
            {
                comboBoxRange.Items.Add(range.ToString());
            }

            comboBoxRange.SelectedIndex = 0;
        }

        /// <summary>
        /// Kinectの動作を停止する
        /// </summary>
        /// <param name="kinect"></param>
        private void StopKinect(KinectSensor kinect)
        {
            if (kinect != null)
            {
                if (kinect.IsRunning)
                {
                    // フレーム更新イベントを削除する
                    kinect.ColorFrameReady -= kinect_ColorFrameReady;
                    kinect.DepthFrameReady -= kinect_DepthFrameReady;

                    // Kinectの停止と、ネイティブリソースを解放する
                    kinect.Stop();
                    kinect.Dispose();

                    imageRgb.Source = null;
                    imageDepth.Source = null;
                }
            }
        }

        /// <summary>
        /// RGBカメラのフレーム更新イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            try
            {
                // RGBカメラのフレームデータを取得する
                using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
                {
                    if (colorFrame != null)
                    {
                        // RGBカメラのピクセルデータを取得する
                        byte[] colorPixel = new byte[colorFrame.PixelDataLength];
                        colorFrame.CopyPixelDataTo(colorPixel);

                        // ピクセルデータをビットマップに変換する
                        imageRgb.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,
                            PixelFormats.Bgr32, null, colorPixel, colorFrame.Width * colorFrame.BytesPerPixel);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 距離カメラのフレーム更新イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        readonly int Bgr32BytesPerPixel = PixelFormats.Bgr32.BitsPerPixel / 8;

        void kinect_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
        {
            try
            {
                // Kinectのインスタンスを取得する
                KinectSensor kinect = sender as KinectSensor;
                if (kinect == null)
                {
                    return;
                }

                // 距離カメラのフレームデータを取得する
                using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
                {
                    if (depthFrame != null)
                    {
                        // 距離データを画像化して表示
                        imageDepth.Source = BitmapSource.Create(depthFrame.Width,
                          depthFrame.Height, 96, 96, PixelFormats.Bgr32, null,
                          ConvertDepthColor(kinect, depthFrame),
                          depthFrame.Width * Bgr32BytesPerPixel);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 距離データをカラー画像に変換する
        /// </summary>
        /// <param name="kinect"></param>
        /// <param name="depthFrame"></param>
        /// <returns></returns>
        private byte[] ConvertDepthColor(KinectSensor kinect,
          DepthImageFrame depthFrame)
        {
            ColorImageStream colorStream = kinect.ColorStream;
            DepthImageStream depthStream = kinect.DepthStream;

            // 距離カメラのピクセルごとのデータを取得する
            short[] depthPixel = new short[depthFrame.PixelDataLength];
            depthFrame.CopyPixelDataTo(depthPixel);

            // 距離カメラの座標に対応するRGBカメラの座標を取得する(座標合わせ)
            ColorImagePoint[] colorPoint =
              new ColorImagePoint[depthFrame.PixelDataLength];
            kinect.MapDepthFrameToColorFrame(depthStream.Format, depthPixel,
              colorStream.Format, colorPoint);

            byte[] depthColor = new byte[depthFrame.PixelDataLength * Bgr32BytesPerPixel];
            for (int index = 0; index < depthPixel.Length; index++)
            {
                // 距離カメラのデータから、距離を取得する
                int distance = depthPixel[index] >> DepthImageFrame.PlayerIndexBitmaskWidth;

                // 変換した結果が、フレームサイズを超えることがあるため、小さいほうを使う
                int x = Math.Min(colorPoint[index].X, colorStream.FrameWidth - 1);
                int y = Math.Min(colorPoint[index].Y, colorStream.FrameHeight - 1);

                // 動作が遅くなる場合、MapDepthFrameToColorFrame を外すと速くなる場合が
                // あります。外す場合のx,yはこちらを使用してください。
                //int x = index % depthFrame.Width;
                //int y = index / depthFrame.Width;

                int colorIndex = ((y * depthFrame.Width) + x) * Bgr32BytesPerPixel;

                // 指定された距離より遠ければ色付け
                if (distance >= depthStream.MinDepth)
                {
                    depthColor[colorIndex] = 0;
                    depthColor[colorIndex + 1] = 0;
                    depthColor[colorIndex + 2] = 255;
                }

            }

            return depthColor;
        }

        /// <summary>
        /// 距離カメラの通常/近接モード変更イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBoxRange_SelectionChanged(object sender,
          System.Windows.Controls.SelectionChangedEventArgs e)
        {
            try
            {
                KinectSensor.KinectSensors[0].DepthStream.Range =
                  (DepthRange)comboBoxRange.SelectedIndex;
            }
            catch (Exception)
            {
                comboBoxRange.SelectedIndex = 0;
            }
        }


        /// <summary>
        /// Windowsが閉じられるときのイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            StopKinect(KinectSensor.KinectSensors[0]);
        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

同じタグがついた質問を見る

  • C#

    8511questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • OpenCV

    1429questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

  • Kinect

    101questions

    Kinect(キネクト)はマイクロソフトから発売されたジェスチャー・音声認識によって 操作ができるデバイスです。