Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
26
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

cv::VideoCaptureでRealSenseからデータを取得する

この投稿はOpenCV Advent Calendar 2018の9日目の記事です。

はじめに

この記事では、OpenCV 4.0からサポートされたcv::VideoCaptureでRealSenseからデータを取得する方法について紹介します。

動作確認環境

  • RealSense D415/D435 (FW 5.10.13)
  • Windows 10 Pro (1809)
  • Visual Studio 2017 (15.9.3)
  • OpenCV 4.0.0
  • RealSense SDK 2.17.0
  • CMake 3.13.1

RealSenseとは?

RealSenseとは、Intelから発売されているRGB-Dセンサーです。
RealSenseには過去にもいくつかのモデルが存在しますが、現行のモデルはRealSense D400シリーズ(RealSense D415、RealSense D435、RealSense D435iなど)になります。

RealSense D400シリーズはInfraredのステレオカメラを搭載してDepthを計算します。(厳密には、赤外線波長をカットしていないRGBまたはGrayscaleのカメラです。)
ステレオカメラなのでテクスチャの乏しいシーンは苦手ですが、RealSense D400シリーズではプロジェクターからInfraredのパターンを投影してテクスチャを補うことができます。よく勘違いされますが、Kinect v1のようなStructured Light方式ではありません。

RealSense D400シリーズは、RealSense SDK 2.xを使用してデータを取得することができます。
このSDKを直接利用してデータを取得してもよいですが、この記事ではOpenCVのcv::VideoCaptureで他のカメラと同じようにデータを取得する方法を紹介します。1

RealSense D415

RealSense D415

RealSense D435

RealSense D435

OpenCVでRealSenseからデータを取得する方法

RealSenseをサポートしたOpenCVをビルド、インストールする

公式に配布されいてるビルド済みのOpenCVはRealSenseのサポートが有効になっていません。まずは、OpenCVをソースコードからビルドしましょう。OpenCVのビルド方法の詳細については、多くの記事があるのでそちらを参考にしてください。

ここでは、要点だけをまとめておきます。

  1. RealSense SDKをダウンロード、インストールする。

  2. OpenCVのソースコードをダウンロード、バグを修正する。

  3. CMakeで以下の設定を行う。

    • LIBREALSENSE
      • LIBREALSENSE_INCLUDE_DIR C:/Program Files (x86)/Intel RealSense SDK 2.0/include
      • LIBREALSENSE_LIBRARIES C:/Program Files (x86)/Intel RealSense SDK 2.0/lib/x86/realsense2.lib(またはC:/Program Files (x86)/Intel RealSense SDK 2.0/lib/x64/realsense2.lib)
    • WITH
      • WITH_LIBREALSENSE ☑(check)
  4. 生成したOpenCVのプロジェクトをビルド、インストールする。

cv::VideoCaptureでRealSenseからデータを取得する

main.cpp
#include <opencv2/opencv.hpp>

int main( int argc, char* argv[] )
{
    // (1) Open cv::VideoCapture() with RealSense
    cv::VideoCapture capture( cv::VideoCaptureAPIs::CAP_INTELPERC );
    if( !capture.isOpened() ){
        return -1;
    }

    while( true ){
        // (2) Grab All Frames
        capture.grab();

        // (3) Retrieve Each Frames
        // (3.1) Color Frame
        cv::Mat color_frame;
        capture.retrieve( color_frame, cv::CAP_INTELPERC_IMAGE );

        // (3.2) Depth Frame
        cv::Mat depth_frame;
        capture.retrieve( depth_frame, cv::CAP_INTELPERC_DEPTH_MAP );

        // (3.3) Infrared Frame
        cv::Mat infrared_frame;
        capture.retrieve( infrared_frame, cv::CAP_INTELPERC_IR_MAP );

        // (4) Show Image
        cv::imshow( "Color", color_frame );
        depth_frame.convertTo( depth_frame, CV_8U, -255.0 / 10000.0, 255.0 ); // Scaling
        cv::imshow( "Depth", depth_frame );
        cv::imshow( "Infrared", infrared_frame );

        const int32_t key = cv::waitKey( 33 );
        if( key == 'q' ){
            break;
        }
    }

    cv::destroyAllWindows();

    return 0;
}

(1) Open cv::VideoCapture() with RealSense

// (1) Open cv::VideoCapture() with RealSense
cv::VideoCapture capture( cv::VideoCaptureAPIs::CAP_INTELPERC );
if( !capture.isOpened() ){
    return -1;
}

cv::VideoCapture()cv::VideoCaptureAPIs::CAP_INTELPERCを指定することでRealSenseからキャプチャできます。
CAP_INTELPERCなのは、祖先にあたるIntel Perceptual Computing SDKの名残りですね。

(2) Grab All Frames

// (2) Grab All Frames
capture.grab();

cv::VideoCapture::grab()を呼ぶことで、フレームの取得を待ちます。

(3) Retrieve Each Frames

// (3) Retrieve Each Frames
// (3.1) Color Frame
cv::Mat color_frame;
capture.retrieve( color_frame, cv::CAP_INTELPERC_IMAGE );

// (3.2) Depth Frame
cv::Mat depth_frame;
capture.retrieve( depth_frame, cv::CAP_INTELPERC_DEPTH_MAP );

// (3.3) Infrared Frame
cv::Mat infrared_frame;
capture.retrieve( infrared_frame, cv::CAP_INTELPERC_IR_MAP );

cv::VideoCapture::retrieve()cv::Matにフレームを取得します。
第2引数にcv::CAP_INTELPERC_IMAGEを指定することでColor、cv::CAP_INTELPERC_DEPTH_MAPを指定することでDepth、cv::CAP_INTELPERC_IR_MAPを指定することでInfraredのフレームをそれぞれ取得することができます。
ColorはCV_8UC3(BGR)、DepthはCV_16UC1、InfraredはCV_8UC1のフォーマットでデータが格納されています。

(4) Show Image

// (4) Show Image
cv::imshow( "Color", color_frame );
depth_frame.convertTo( depth_frame, CV_8U, -255.0 / 10000.0, 255.0 ); // Scaling
cv::imshow( "Depth", depth_frame );
cv::imshow( "Infrared", infrared_frame );

DepthはCV_16UC1のフォーマットのため、そのまま可視化できません。
ここでは、CV_16U([0, 10000])をCV_8U([255, 0])にスケーリングして表示しています。

実行結果

Color Depth Infrared

OpenCVのRealSenseサポートについて検討する

OpenCVでは他のカメラと同じようにRealSenseを簡単に扱うことができます。
安価で手軽に利用できるRGB-Dセンサーを簡単に扱えることは大きな利点ですね。
ただし、未実装の機能や制限も多く、まだ実用に耐えられるものではないかもしれません。
これらの機能を使いたいときは、RealSense SDKを直接利用するべきでしょう。1

未実装機能

  • 解像度、フレームレート、フォーマットの設定、取得
  • ステレオカメラの両方のフレームを取得
  • ファイルからのキャプチャ
  • 複数台のRealSenseのサポート

おわりに

この記事では、OpenCVのcv::VideoCaptureでRealSenseからデータを取得する方法について紹介しました。
明日もすーぱーUnaさんたいむで「cv::kinfu::KinFuでKinect FusionをRealSenseで動かしてみる」です。


  1. もちろん、RealSense SDKを直接利用してデータを取得する方が柔軟に対応できます。RealSense SDKのサンプルを公開しているので、興味がある方はこちらを参考にしてください。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
26
Help us understand the problem. What are the problem?