165
115

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

武蔵野Advent Calendar 2017

Day 21

Intel RealSense Depth Cameraがいかにやばいかについて

Last updated at Posted at 2017-12-20

#TL;DR

  • Intel RealSense Depth Cameraはやばい
    • Intel Euclid Development Kitが神デバイス過ぎてやばい
      • 手のひらサイズなのにDepthを処理しながら映像をエンコーディングできてやばい
    • 次のD400シリーズの解像度が高いのに値段が安くてやばい

はじめに

はじめに武蔵野アドベントカレンダーの枠を譲ってくださったnishiyさんに
この場を持って感謝の意をお伝えしたいと思います。
ありがとうございます。

私は武蔵野に縁のある会社に勤めてはおりますが、
武蔵野にはいません。横須賀にいます。
武蔵野とは違い、横須賀では窓から富士山がきれいに見えます。
横須賀にいる人は誰しもが自慢します。そしてそれぐらいしか自慢するところがありません。

IMG_5036.JPG
図1 横須賀という場所から見える富士山

はい

なぜデプスカメラの話をするのか

そんな富士山がよく見える横須賀で、私は人とロボットとのインタラクションについて調べています。
ロボットが人とインタラクションするには人の位置をしっかり把握することがかかせません。そうでないとロボットと人がぶつかります。 ロボット三原則もクソもないです。
そこで役立つのがデプスカメラです。
デプスカメラとは映像の奥行きが測定できるカメラのことです。デプスカメラは奥行きが測定できることから、人や物体の位置をロボットが認識することに使われます。つまり、ロボットの目として使われています。たとえば、デプスカメラを組み込んだロボットとして、○epperくんとかHSRとかがあります。

このデプスカメラの1つとして、Intelが作っているRealSenseデプスカメラ(以下、RealSense)を紹介します。

今回、このRealSenseがいかにやばいのかを語らせていただこうと思います。

なお、デプスカメラがわからない人のために、これからデプスカメラの詳細を説明します。デプスカメラを知っている人は次の章まで読み飛ばしてください。

デプスカメラってなにさ

デプスカメラとは画像の各画素が距離を表している深度画像を撮影することができるカメラのことです。

depth.PNG
図2 デプスカメラにて撮影した自室と私(画素値が赤いほど近く、緑ほど遠い)

デブスちゃうで
デプスカメラはいろいろ製品があります。
たとえば、先述のRealSenseやKinect、Xtion、Leapがあります。

IMG_4291.jpgkinect.pngIMG_4288.jpg

図3 いろんなデプスカメラ(左:Realsense、真ん中:Kinect、右:Leap)

特に圧倒的な販売量を誇るのはKinectです。 3500万台 売れたそうです。
なぜそんなに売れたのかというと、Xboxのおまけだったことと モーションキャプチャー機能 があったからです。
モーションキャプチャーとは人の位置や姿勢などを非接触に取ることができる機能のことです。
これは発売当時画期的なことでした。
これまでモーションキャプチャーといえば、数百万から数千万円のシステムを買う必要がありました。
一方で、Kinectは2万円ぐらい、1/1000ぐらいの価格に破壊してしまったのです。
ただし、精度はそんなに高くなかったので、新しいモーションキャプチャー市場を開拓したという感じでした。
ちなみにKinectのアルゴリズムは画像処理の最難関国際会議ICCVで最優秀賞Best paperを取っています。
Kinectはアカデミアでもビジネスでも成功した稀有な製品なんです。
そんなKinectで実際に撮影してみたのがこちらです。

体を3次元で撮影している感じがよくわかります。この情報を使って、モーションキャプチャーを行うのです。
他のRealSenseやLeapもモーションキャプチャー機能を持っています。特にLeapは手のモーションキャプチャーに特化しているため、VRのHMDに無理やり引っ付けてVR空間に自分の手を飛ばすという無茶な用途に利用されています。

ちなみにLeapの使い方を説明した「自然非言語処理」という私の一人アドベントカレンダーもあるので、そちらもあわせてご覧ください(ステマ)
自然非言語処理第11日目:運動を用いた非言語処理(知覚・認知編)

さて、最近問題となっているのは、Kinectが販売終了してしまったことです。
この原因は、Kinectの中に入っていたパーツをPrimeSenseという会社が作っていたのですが、
AppleがPrimeSenseを買収して、パーツを他の会社に売らなくなったかららしいです[2][3]。

(誤情報でした。すいません*1)

ちなみにiPhone XのFace IDはこのPrimeSenseのデプスカメラをセンサとして使っています。

Xboxとセットで販売せず、Kinectを単体で売ると赤字になるからMSは売るのを止めたかったとかいうずっと前から通の間では噂があったからAppleに売っちゃったから生産むりぽという言い訳を作ったんでしょうね

今後のデプスカメラ覇権は誰が手にとるのか?
というところが画像処理界隈のほんのりホットな話題です。

Intel Euclid Development Kitが神デバイス過ぎてやばい

Intel Euclid Development Kit(以下、Euclid)とは、このデプスカメラとそれを処理するためのコンピュータが一体となったプロトタイピング用の製品です。
画像のディープラーニングで有名な東大の中山先生もEuclidがいかに神デバイスであるかをたたえています。

このEuclidの性能をユニポスというサイト[4]から引用すると、

・Intel Atom x7-8700 Quad-Core プロセッサ搭載
・Intel RealSense ZR300 デプスカメラ搭載
・Wi-Fi / Bluetooth無線通信機能
・IMU、気圧センサ、GPS、近接センサなどの環境センサ
・Ubuntu 16.04 OSプリインストール
・ROS(Kinetic Kame)プリインストール

ちなみに僕がさらにいいところを追加すると

・外部バッテリー付属。5V3Aアダプター付属。
・ファン内蔵。高負荷にも安定動作。
・ちゃんと技適マークを取っており、日本でも使用可能
・物体検出、人物検出、モーションキャプチャーなどのライブラリがプリインストール。
・出荷時キャリブレーション済み。キャリブレーション用ソフトもプリインストール。

これでお値段 399ドル
完全に赤字商品。

ちなみに同じぐらいの性能を同じデプスカメラであるKinectで再現するとダンボール1箱ぐらいになります。

IMG_4292.jpg IMG_4293.jpg

図4 EuclidとKinect+PCのサイズの比較(ライターが手の幅サイズだと思ってください)

いかに効率よく小型化をおこなったのかがわかります。

さて、このEuclidの性能を実際に見ていただくために、
モーションキャプチャしながらその様子を可視化してエンコーディングするというデモ
これからお見せします。

手のひらサイズなのにDepthを処理しながら映像をエンコーディングできてやばい

それではEuclidをつかって、モーションキャプチャしながら、その様子を可視化してH.264でリアルタイムエンコードするソースコードを以下に示します。
ちなみにこのソースコードはIntelのGithubにあるサンプルコードをもとに作成されています。
その為、このコードだけでは動きません。
以下にあるリポジトリのpt_tutorial_2のメイン部分を置き換えるとたぶんcmakeができるはずです。
https://github.com/IntelRealSense/realsense_samples

RecorderWithXZPlot.cpp
// License: Apache 2.0. 
// Copyright(c) 2016 Intel Corporation and Alfred Increment. All Rights Reserved.

#include <iostream>
#include "version.h"
#include "rs_sdk.h"
#include <stdio.h>
#include <chrono>
#include <opencv2/opencv.hpp>
#include <thread>

#include "pt_utils.hpp"

using namespace cv;
using namespace std;
using namespace rs::person_tracking;

// constants
const int WIDTH=640;
const int HEIGHT=480;
const int GRAPH_SIZE=200;

// Version number of the samples
extern constexpr auto rs_sample_version = concat("VERSION: ",RS_SAMPLE_VERSION_STR);

int main(int argc, char** argv)
{


    pt_utils pt_utils;
    // H.264 encording
    VideoWriter videowriter("video.avi",VideoWriter::fourcc('H','2','6','4'),30,Size(640,480));

    rs::core::video_module_interface::actual_module_config actualModuleConfig;
    rs::person_tracking::person_tracking_video_module_interface* ptModule = nullptr;

    // Initializing Camera and Person Tracking modules
    if(pt_utils.init_camera(actualModuleConfig) != rs::core::status_no_error)
    {
        cerr << "[RealsenseManager] Error: Device is null." << endl << "Please connect a RealSense device and restart the application" << endl;
        return -1;
    }

    pt_utils.init_person_tracking(&ptModule);

    ptModule->QueryConfiguration()->QueryTracking()->Enable();

    // Configure enabled module
    if(ptModule->set_module_config(actualModuleConfig) != rs::core::status_no_error)
    {
        cerr<<"[RealsenseManager] Error : Failed to configure the enabled module" << endl;
        return -1;
    }

    // Start the camera
    pt_utils.start_camera();

    cout<<"[RealsenseManager] Management has started."<<endl;
    auto startTime=std::chrono::high_resolution_clock::now();

    while(true)
    {
	auto diff=std::chrono::high_resolution_clock::now()-startTime;
	auto duration=std::chrono::duration_cast<std::chrono::seconds>(diff).count();
	if(duration>30)break;

        rs::core::correlated_sample_set sampleSet = {};

        // Get next frame
        if (pt_utils.GetNextFrame(sampleSet) != 0)
        {
            cerr << "[RealsenseManager]Error: Invalid frame" << endl;
            continue;
        }

	// copy original a image.
	Mat frameOrg(Size(WIDTH,HEIGHT),CV_8UC3,(uchar *)sampleSet.images[static_cast<uint8_t>(rs::core::stream_type::color)]->query_data());
	Mat frame(Size(WIDTH,HEIGHT),CV_8UC3);
	cvtColor(frameOrg,frame,COLOR_BGR2RGB);

	Mat graph=Mat::zeros(GRAPH_SIZE,GRAPH_SIZE,CV_8UC3);

	//plot x axis and z axis
	line(graph,Point(GRAPH_SIZE/2,0),Point(GRAPH_SIZE/2,GRAPH_SIZE),Scalar::all(255),1);
	line(graph,Point(0,GRAPH_SIZE/2),Point(GRAPH_SIZE,GRAPH_SIZE/2),Scalar::all(255),1);
	
        // Process frame
        if (ptModule->process_sample_set(sampleSet) != rs::core::status_no_error)
        {
            cerr << "[RealsenseManager]Error : Failed to process sample" << endl;
            continue;
        }
	

        Intel::RealSense::PersonTracking::PersonTrackingData *trackingData = ptModule->QueryOutput();

        for (int index = 0; index < trackingData->QueryNumberOfPeople(); index++)
        {
            Intel::RealSense::PersonTracking::PersonTrackingData::Person *personData = nullptr;
            personData = trackingData->QueryPersonData(Intel::RealSense::PersonTracking::PersonTrackingData::ACCESS_ORDER_BY_INDEX, index);

            if (personData)
            {

                Intel::RealSense::PersonTracking::PersonTrackingData::PersonTracking *personTrackingData = personData->QueryTracking();
                Intel::RealSense::PersonTracking::PersonTrackingData::PointCombined centerMass = personTrackingData->QueryCenterMass();

                float centerMassWorldX = centerMass.world.point.x;
                float centerMassWorldY = centerMass.world.point.y;
                float centerMassWorldZ = centerMass.world.point.z;


		//draw a user's position.
		circle(graph,Point(centerMassWorldX*GRAPH_SIZE/2+GRAPH_SIZE/2,GRAPH_SIZE-centerMassWorldZ*GRAPH_SIZE/2),10,Scalar::all(255),-1);

            }
        }
	//paste graph into frame.
	graph.copyTo(frame(Rect(WIDTH-GRAPH_SIZE-GRAPH_SIZE/4,HEIGHT-GRAPH_SIZE-GRAPH_SIZE/4,GRAPH_SIZE,GRAPH_SIZE)));

	//encord		
	videowriter<<frame;

        // Release color and depth image
        sampleSet.images[static_cast<uint8_t>(rs::core::stream_type::color)]->release();
        sampleSet.images[static_cast<uint8_t>(rs::core::stream_type::depth)]->release();

    }
    pt_utils.stop_camera();
    actualModuleConfig.projection->release();

    cout << "-------- Stopping --------" << endl;

    return 0;
}

動作結果は以下の通りとなります。

ね、やばいでしょ。

Euclidに関する悲しいお知らせ

このEuclid、今年2017年5月31日に発売されたのですが、ユニポスによると

本製品は販売終了となりました

ということです。

なぜこんなにたたえているのかわかりますね。

頼む再販してくれ

そういうことです。

次のD400シリーズの解像度が高いのに値段が安くてやばい

Euclidは販売終了してしまいましたが、ちゃんと次世代のRealSense、D415とD435は開発されており、
来年には販売される予定です。
D415とD435の情報は公式のWebサイトにたくさん載っていますが、arXivに性能やアルゴリズムが公開されているというところ[5]がインテル入ってる感あります。
ちなみに現行のRealSenseと次世代のRealSenseの性能を比較したのが以下の図5らしいです。

D400シリーズ.png
図5 現行のR200と次世代のD400シリーズの精度比較([5]より引用)

質で見れば一目瞭然。せっかくなので、量を表で比較して見ましょう。

比較軸 R200[6] Kinect v2[7] D435[8]
解像度 640 x 480 512×424 1280 x 800
FPS 60 30 30
画角(HxV) 59x46 70x60 91.2x65.5
動作範囲[m] 0.4-2.8 0.5-4.5 0.2-約10
価格[US$] 99 199 179
方式 Active IR Stereo Time-of-Flight Active IR Stereo (Global Shutter)
電源 USB3.0 コンセント USB type-C
屋外での利用 ×

大手が提供するレーダーレンジファインダーでも最低30万円、LiDARに至っては最低100万円のところをD435は約2万円。
やばい。

ちなみに予約サイトはこちらになります。
1/8の週からshipping予定らしいです。日本に届くのはいつでしょうね。
https://click.intel.com/realsense.html
https://www.mouser.jp/new/Intel/intel-realsense-camera-400/

最後に

実はマイクロソフトからKinect終了に関してお気持ちが表明されています[7]。

Kinect センサーとアダプターの製造は終了しましたが、Kinect 技術は HoloLens、Cortana 音声アシスタント、Windows Hello 生体顔認識、コンテキスト対応のユーザー インターフェイスで今も活用されています。
マイクロソフトでは Intel と協力して、Kinect for Windows プラットフォームからの開発者向けの移行オプションに取り組んでいます。マイクロソフトは、オンライン フォーラム、プレミア サポート、有料のテクニカル サポートを通じて、引き続き Kinect for Windows SDK のサポートを提供します。開発者の間では Kinect ハードウェアからの移行が進んでいるため、開発者の皆様には、Intel RealSense デプスカメラの検討をお勧めします。

Intel RealSense Depth Cameraはやばい
IMG_4314.jpg
図6 Euclid上でゴリゴリ開発するときのEuclid覚醒状態の様子

参考文献

[1] https://www.mouser.jp/new/Intel/intel-realsense-camera-400/
[2] http://allthingsd.com/20131124/apple-confirms-acquisition-of-3d-sensor-startup-primesense/
[3] https://japan.cnet.com/article/35109375/
[4] https://www.unipos.net/find/product_item.php?id=3229
[5] Leonid Keselman, John Iselin Woodfill, Anders Grunnet-Jepsen, Achintya Bhowmik, "Intel RealSense Stereoscopic Depth Cameras," arXiv, 2017
[6] https://software.intel.com/sites/default/files/managed/d7/a9/realsense-camera-r200-product-datasheet.pdf
[7] https://developer.microsoft.com/ja-jp/windows/kinect/hardware
[8] https://www.mouser.com/pdfdocs/Intel_D400_Series_Datasheet.pdf

*1

Microsoft now deploys its own homegrown sensor technology for the current generation of Kinect devices, which ship with the recently launched Xbox One.

[2]とあり、v2や最新型はPrimeSense社関係ないようです。

165
115
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
165
115

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?