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

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

ただいまの
回答率

90.51%

  • C#

    8534questions

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

  • OpenCV

    1430questions

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

  • Kinect

    101questions

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

KINECTで得た画像をOpencvSharpに渡したいです。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 577

keisuke1995

score 8

以下のようなプログラムで、デプス情報の画像とRGBの画像の両方を得ました。

ここからOpencvSharpで、処理を行いたいのですが、どのようにして画像を変換するべきなのか教えていただきたいです。よろしくお願いいたします。

ビットマップからIplImage型に変換するため、ToIplImage()を、追加しました。// ピクセルデータをビットマップに変換する の下です。
しかし、次のようなエラーが出ます。

型'Bitmap'は、参照されていないアセンブリに定義されています。アセンブリ'SYstem.Drawing,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a'に参照を追加する必要があります。

何か対策法を教えていただけませんか?

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_depth
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        // OpenCV用
        private IplImage openCVImage;
        private IplImage openCVGrayImage;

        /// <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);

             IplImage iplOriginal = imageRgb.Source.ToIplImage();
                    }
                }
            }
            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 >= 500)
                {
                    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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

BMPファイルであれば
using (IplImage im = new IplImage("△△.bmp"))  // 入力画像の取得 

using (new CvWindow("Test", im))            // 画面に画像を表示 

Cv.WaitKey();                           // キー入力待機 

}

変換ではこんな感じでやった記録があります。
Bitmap bmp =new Bitmap(SearchSize, SearchSize);
IplImage qimg = (OpenCvSharp.IplImage)BitmapConverter.ToIplImage(bmp);
OPenCVSherpのバージヨンによって動作しない場合があるかもしれません。
Ver.2.4.10

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/16 14:43

    回答ありがとうございます。
    Bitmap bmp を打ち込むと、現在のコンテキストには Biymapは存在しませんと言われます。
    どのようにして、BMPファイルとして読み込むのでしょうか?

    キャンセル

  • 2018/02/16 14:53

    すいません、上記の件については解決しました。
    変換された画像データをグレースケールにしようとすると、Cv.CvtColor(qimg, qimg, ColorConversion.BgrToGray);でエラーが出ます。
    データ型が違うのでしょうか?

    キャンセル

  • 2018/02/16 15:03

    読み込んだら表示はできましたか?
    期待した画像か確認ください。
    帰るので次は月曜日になります。

    キャンセル

  • 2018/02/16 15:13

    すいません。自己解決しました。
    ありがとうございました。

    キャンセル

0

回答がないようなのでコメントしますが Kinect は使ったことはありません。
OpenCVSharp を利用したことがある程度の者です。
①最終目標は分かりませんが 距離データ(2値化したもの)をOpenCVSharpで表示したいと思っていましたが・・・??
// 距離データを画像化して表示 の後で処理された方がいいと思います。
②解決の手段の一つとして 「距離データを画像化して表示」の直後に Kinect でファイルに落とすことはできませんか?
ファイルをOpenCVSharpで復元する方法も一例かと。
それが可能ならば直接変換も可能になります。(Kinect のデータ構造知らないので)
③アップされたプログラムで imageRgb がどこで定義されているか確認できませんでした。OpenCVSharp で定義が必要かと?

違っていたらすみません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/16 13:15

    回答ありがとうございます。遅れて申し訳ありません。imageRgbは、KINECTのプログラムの中で定義されてます。
    imageRgb.Source.Save(DateTime.Now.Year + "-" + DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + DateTime.Now.Hour + "-" + DateTime.Now.Minute + "-" + DateTime.Now.Second + ".bmp"); 
    を追加して、ビットマップとして保存を行いたいと思います。

    キャンセル

  • 2018/02/16 15:13

    すいません。解決できました。
    回答していただき、ありがとうございました。

    キャンセル

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

  • C#

    8534questions

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

  • OpenCV

    1430questions

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

  • Kinect

    101questions

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