Open3D+ROS+Pythonで3次元画像処理を楽々プロトタイピング

3次元画像処理ライブラリ「Open3D」の紹介

 いつも読んでいる、「空飛ぶロボットのつくりかた」というブログで、Open3DというIntel製の3次元画像処理のライブラリが紹介されていました。

 「Open3D」の公式サイトは以下です。

Open3D – A Modern Library for 3D Data Processing

 個人的に、3次元画像処理には興味あって、以前Point Cloud Library(以下PCL)を使った、簡単な3次元画像処理を紹介したことがあります(以下記事参照)。

 ただ、PCLには以下のような不満がありました。

  • C++しか使えない(C++苦手…)
  • ちょっとした修正にもいちいちビルドしないといけない
  • たくさん行数書く必要がある

 Open3Dがつくられたのも、上記のような不満を解消するのが目標だったようで、Open3Dを紹介する論文によると、Open3DのPCLに比べた利点は以下とのことです。

  • Pythonが使える
  • 少ない行数でかける(PCLの1/5とのこと)
  • Jupyter Notebookでデバッグできる

 そしてPCLはかなりディスられてました。よっぽど嫌な思いをしたのでしょう(PCLに親を殺されたとか)。

Open3DはROSと連携させると良さそう

 Open3Dは少し触っていて、確かにPythonでサクサク書けるのは便利で、プロトタイピング(試行錯誤)には使いやすそうだなと感じました。

 ただ、3次元画像処理って自分としては3次元センサと組み合わせてリアルタイムで処理したいのですよね。PCLの場合は、ROS(Robot Operation System)と組み合わせることで、ROSに対応した多種多様な3次元センサと、ROSの強力な可視化機能(Rviz)やログ機能(rosbag)が使えたのが非常に便利でした。

 Open3Dは、自分が調べた感じROSには対応していなさそうでした。「対応していないのだったら、自分でROSに対応させちゃえ!」ということで、「open3d_ros」というOpen3DとROSを連携させるちょっとしたツールを作ってみました。

 この記事では、「open3d_ros」の使い方と、どんなことができるかを簡単に紹介いたします。

「open3d_ros」によるOpen3DとROS連携のセットアップ方法

 Open3DとROSを連携させるためのセットアップ手順を説明していきます。ここからの想定は、ネイティブのLinux(Ubuntu 16.04)がインストールされたPC、もしくは仮想環境上でのLinux環境を想定しています。

 Macの仮想環境(Parallels Desktop Lite)に関しては以下記事参照下さい。WindowsでもVirtual Boxなどの環境で同様にできると思います(未確認)。

 仮想環境上で、Open3Dのビルドに失敗する場合は、仮想環境のメモリ設定を最大限確保し、何度かビルドをしてみて下さい。

ROSと3次元センサのセットアップ

 ROSと3次元センサのセットアップに関しては、以下記事参照下さい。

 以降のコードは、Kinectを想定しています。Realsenseの場合は、適宜コードを修正ください。

 もし3Dセンサを持っていなくても、ログデータ(rosbag)で試すこともできます。

Open3Dインストール

 Open3Dのインストールは、pipで簡単にインストールできます。最初に以下コマンドでpipのアップグレードをしておいた方がよいです。

$ sudo pip install --upgrade pip

 あとは、以下コマンドでインストール可能です。

$ sudo pip install open3d-python==0.7.0

 Python3に入れたい場合は pipの代わりにpip3ですね。

 ネイティブのMacも同様にpipで入れられます。sudoは不要です。ネイティブのMacにROSを入れるのは至難の技ですが…

 続いて、以下コマンド実行してテストします。

$ git clone https://github.com/IntelVCL/Open3D
$ cd Open3D
$ git checkout v0.7.0
$ cd ./examples/Python/Basic
$ python rgbd_redwood.py

 以下のような画像が表示されればOKです。

Open3D+ROS連携

 ここからいよいよ「open3d_ros」を使っていきます。ここからは以下のリポジトリを使用します。

 あらかじめ、好きな場所に以下のコマンドで「open3d_ros」をcloneしておいて下さい。

$ git clone https://github.com/karaage0703/open3d_ros

 次に、ターミナルのウィンドウを4つ立ち上げて、それぞれのターミナルでopen3d_rosディレクトリ内で以下コマンドを実行します。

 1つ目でroscore立ち上げ

$ roscore

 2つ目で、ログデータ(rosbag)再生

$ rosbag play -l rosbag_data/kinect_room.bag

 3つ目でOpen3D使用

$ python down_sampling.py input:=/camera/depth_registered/points

 4つ目でRviz立ち上げて3次元情報を可視化

$ rosrun rviz rviz -d kinect.rviz

   以下のようにRviz上にダウンサンプリングされた点群が表示されます。
 ダウンサンプリングされた点群


 ダウンサンプリングされる前の点群

 ちなみに、down_sampling.pyは、以下のような30行にも満たないスクリプトです。面倒臭いROSとの連携部分はutil.pyというファイルに詰め込んでインポートしています(興味ある方はutil.pyの方も見てみて下さい)。

#! /usr/bin/env python

import rospy
from sensor_msgs.msg import PointCloud2

import util
import open3d as o3d

def down_sampling(pcl_data):
    downpcd = o3d.voxel_down_sample(pcl_data, voxel_size = 0.05)

    return downpcd


def callback(data):
    pcl_data = util.convert_pcl(data)

    result_pcl = down_sampling(pcl_data)

    util.publish_pointcloud(result_pcl, data)

if __name__ == "__main__":
    rospy.init_node('listener', anonymous=True)
    rospy.Subscriber('input',
                     PointCloud2, callback)

    rospy.spin()

 上記コードのdown_samplingという関数を書き換えると、好きなように3次元処理ができます。これみると、なんとなく簡単に3次元画像処理ができそうな気がしてきますね(してきますよね?)。

 今回はあらかじめ用意したログデータでテストしましたが、3次元センサを使っても、簡単に同様の画像処理ができます。具体的には、以下記事参考にKinectをセットアップします。

 あとは、上記のログ再生コマンドの代わりに以下コマンドを実行してキネクトを起動するだけです。

$ roslaunch freenect_launch freenect.launch

 もちろん、Kinect以外も、ROSに対応している3次元カメラであれば、同じ要領で3次元画像処理が可能です。今だとRealsenseあたりがお手頃でしょうか。これもOpen3Dと同じくIntel製ですね。

まとめ

 Open3D+ROS+Pythonで3次元画像処理のプロトタイピングができる「open3d_ros」というツールを自作して紹介しました。「Open3D」Python使えるのは、ビルドしなくてよいし、簡単にかけて良いですね(C++難しい…)。ただ、速度はPCLに比べて遅い印象があります。ちゃんとした比較はしていませんが、2,3倍遅い気がします。ここらへんは、また時間ができたらちゃんと検証したいところですね。

 Pythonで書くときは、Numpyが使えるのも魅力的です。3次元画像処理って、2次元画像処理と基本的な部分は共通するところが多いので、2次元画像と同じ要領で直接画素を弄って好きなフィルタを作ったりできるはずです。2次元画像の例ですが、Numpyで画像処理フィルタを作る方法は下記記事参照ください。

 あとは、Pythonなので3次元のディープラーニングというのも中々面白いかもしれませんね。3次元でディープラーニングやっている例って、2次元に比べるとまだまだかなり少ない印象です。私が知っているのは、Appleの自動運転の研究くらいでしょうか(End-to-Endで物体検出しています)。

[1711.06396] VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection

 Open3Dによって、3次元のディープラーニングの研究も進んで行く可能性あるかもしれませんね。

 そして何より、Open3DとROSの強力な可視化ソフトやツール群との組み合わせというのは、なかなかパワフルじゃないかなと思います。これ使って、色々試してみたいなと思います。それこそロボット作ってみたいですね。

参考リンク

Open3Dのお勉強(一回目) - 空飛ぶロボットのつくりかた

ROSのPointCloud2で独自のフィールドを定義 - Yura YuLife

http://lang.sist.chukyo-u.ac.jp/classes/Open3D/

http://lang.sist.chukyo-u.ac.jp/classes/PCL/

Open3DのReconstruction Systemを動かす - Mugichoko’s blog

GitHub - sakizuki/SSII2018_Tutorial_Open3D: Open3Dの使い方

SSII2018のTSを例題に,PCL (C++)とOpen3D (Python) の比較 - Qiita

深層学習を用いた三次元点群処理入門 - Speaker Deck

関連記事

変更履歴

  • 2022/09/20 3次元再構成の関連記事追記
  • 2022/05/14 センサのセットアップ修正・参考リンク追記
  • 2019/06/14 Open3Dのインストール方法とコードを、バージョンアップに合わせて修正
  • 2018/03/13 PCLとの処理時間の体感比較追記