この投稿は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 D435
OpenCVでRealSenseからデータを取得する方法
RealSenseをサポートしたOpenCVをビルド、インストールする
公式に配布されいてるビルド済みのOpenCVはRealSenseのサポートが有効になっていません。まずは、OpenCVをソースコードからビルドしましょう。OpenCVのビルド方法の詳細については、多くの記事があるのでそちらを参考にしてください。
ここでは、要点だけをまとめておきます。
-
RealSense SDKをダウンロード、インストールする。
-
OpenCVのソースコードをダウンロード、バグを修正する。
-
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)
-
LIBREALSENSE
-
生成したOpenCVのプロジェクトをビルド、インストールする。
cv::VideoCaptureでRealSenseからデータを取得する
#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])にスケーリングして表示しています。
実行結果
OpenCVのRealSenseサポートについて検討する
OpenCVでは他のカメラと同じようにRealSenseを簡単に扱うことができます。
安価で手軽に利用できるRGB-Dセンサーを簡単に扱えることは大きな利点ですね。
ただし、未実装の機能や制限も多く、まだ実用に耐えられるものではないかもしれません。
これらの機能を使いたいときは、RealSense SDKを直接利用するべきでしょう。1
未実装機能
- 解像度、フレームレート、フォーマットの設定、取得
- ステレオカメラの両方のフレームを取得
- ファイルからのキャプチャ
- 複数台のRealSenseのサポート
自社の製品なんだから中の人が良い感じに実装すればいいのでは?🤔
— ゆるふわUnaさん (@UnaNancyOwen) 2018年12月2日
おわりに
この記事では、OpenCVのcv::VideoCapture
でRealSenseからデータを取得する方法について紹介しました。
明日もすーぱーUnaさんたいむで「cv::kinfu::KinFuでKinect FusionをRealSenseで動かしてみる」です。