以前ブログ記事で紹介いたしましたPointCloudデータ(点群データ)をメッシュ化して面データとして書き出す方法を紹介いたしましたが点群には色情報がありますので色をテクスチャ画像として書き出す方法を紹介します。

■MeshLabにPointCloudデータ(点群データ)の読み込み

以前紹介いたしました「MeshLabでPCDデータをメッシュに変換、書き出し」ではPCLから書き出されたPCDデータを読み込む方法を紹介いたしましたが今回はデータ形式にはこだわらずにPointCloudデータ(点群データ)を読み込みます。
点群データは色情報がついたものを読込ますと上画像のように色付状態で表示されます。
点群に色がついていない場合は色情報を読み込むことができておりませんので点群スキャン時の書き出し方法を確認してみてください。
(点群データがasciiでしたらテキストエディタで開き色情報があるかを確認できます)


■点群の色情報からテクスチャ画像生成

<1>「normals」を再計算
メッシュ化を行う前に「Compute normals for point sets」で「normals」を再計算しておきます。
Filters/Normals, Curvatures and Orientation/Compute normals for point sets/
設定値はデフォルトのままでApplyを押します。
計算がされますが見た目に変化はありません。

<2>点群をメッシュ化
点群をメッシュ化していきます。 Filters/Remeshing simpleification and Reconstruction/Surface Reconstruction : VCG/ 以前の記事で紹介しました際には「Ball Pivoting」でメッシュ化を行いましたがBall Pivotingですと面分割の境界線が多くなりテクスチャ書き出し時にエラーが出るため今回はVCGでメッシュ化いたします。
点群の形状が閉じている場合は「Poisson」でサーフェイス化を行うと閉じたメッシュになります。


<3>Per-Triangleパラメータ設定
Texture/Parametrization:Trivial Per-Triangle
設定値はInter-triangle borderを「0」、Methodを「Basic」に変更してApplyを押します。 ここで「Inter-triangle border is too much」とエラーが出る場合はメッシュの境界線が多すぎるためです。
(メッシュ化時にメッシュ分割を抑える必要があります)

<4>プロジェクトを保存
File/Save Project/
保存形式は「.ply」で設定値はチェック項目すべてにチェックを入れます。

<5>テクスチャ画像の書き出し
いよいよテクスチャ画像の書き出しを行います。
Texture/Transfer Vertex Attributes to Texture(between 2 meshs)/
設定値は以下の通りです。
・Source Mesh … メッシュ化前の点群データを選択
・Terget Mesh … メッシュ化後のメッシュデータを選択
・Texture file … ファイル名を指定
・Texture width , height … 書き出しを行うテクスチャの解像度をピクセル指定
・Assign Texture … チェックを入れる

書き出しが完了するとメッシュにテクスチャが貼られた状態になります。
またプロジェクトを保存したディレクトリにPNG画像データが保存されます。


<6>メッシュデータの保存
上記のようにテクスチャ画像は自動的にファイル化を行ってくれますが3Dデータは別途保存する必要があります。
File/Export Mesh As…/
汎用データとしてはOBJデータが扱いやすいので書き出します。
ただMeshLabから書き出されたOBJデータが稀にエラーで読めないソフトもあります。その際には別のソフトを間にかませたりすると読み込めます。
フリーソフトで「Colud Compare」というソフトが使い勝手も良いのでMeshLabと合わせてインストールしておくと良いでしょう。 Colud Compareについてはまた別の記事で紹介したいと思います。


■まとめ

点群からメッシュ化を行う時点で色情報が失われてしまうと思っておりましたがテクスチャ化を行うことでメッシュに色情報を張り付けることができることがわかりました。
書き出したテクスチャ画像は他のCGソフトなどで読み込み質感設定を行うとUVマップとしてきれいに貼り付けることができました。 ただメッシュ化の細かさによってはテクスチャの書き出しができないため細かくメッシュ化されたものは対応できなさそうです。

有限会社マグネットインダストリー
西内伸太郎

PCLから書き出したPointCloudデータ(PCD)をMeshLabを使ってメッシュ化し面データとして編集する方法を紹介します。 少し強引な方法ですが参考までに。

■MeshLabとは

以前紹介いたしました「MeshLab概要」記事で簡単に説明しましたがMeshLabはWindows、Macで使用できるフリーのソフトウェアです。


■PointCloudデータ(PCD)をMeshLabで読み込むには

PCDデータはMeshLabでは通常読み込むことができません。
 ①少し強引な方法ですがPCDデータをテキストエディタで開きラベル部分のテキストを削除します。
 ②PCDデータの拡張子を「.pcd」→「.asc」に変更します。
 ③MeshLabでASCII形式で読み込めます。
PCDデータがASCIIではなくバイナリ形式ですとこの方法は使えません。
PCLでPCDを書き出す際にSTLに書き出せばMeshLabに読み込むことができます。

■読み込んだPointCloudをMeshLabでメッシュ化

<1>ASCIIデータ読み込み
まず上記で変更したASCIIデータを読み込みます。
File/Import Mesh/から読み込み。(Pre-Open OptionはGrid triangulationのチェックを外す)


<2>点群を計算
必ず必要というわけではなさそうですが場合によっては後の処理がうまくいかない場合があるので一応処理しておきます。
Filters/Pointset/Compute nomals for point seets/
設定値はNeighbour numを3に変更してApplyを押します。

<3>サンプリング
これも必ず必要というわけではなさそうですが念のため処理しておきます。
サンプリングして点群数を間引くことができます(ダウンサンプリング)
Filters/Sampling/clustered vertex subsampling/
設定値はCell Sizeを1.000→0.500に変更してApplyを押します。

<4>メッシュを貼ります
点群からメッシュを貼ります。
Filters/Remeshing simpleification and Reconstruction/Surface Reconstruction : Ball Pivoting/
設定値そのままでApplyを押すと計算が始まりしばらく待つとメッシュ化されます。 ただ表示が点表示のままですと変化がありませんので表示をFlast等に変更すると面が貼れていることを確認できます。

<5>スムージングを行います
メッシュ化を行うとよほど綺麗な点群でない限りガタガタになっていると思います。スムージングを行い面を慣らします。
Filters/Smooth ,Fairing and Deformation/Laplacian Smooth/
設定値Smoothing steps の数値が大きいほどなめらかになります。
ここで注意が必要ですがスムージングをかけるということは面がなだらかになっていき本来の形状から離れていくことになります。

<6>その他の機能
MeshLabではそのほかにも点を間引いたり面の編集を行ったりすることができるようです。まずはPCDの点群データをメッシュ(面)データに変換することが目的でしたのでその他の機能については割愛します。


■まとめ

実際に低価格のDepthセンサーから取得した点群データを面データに変換してみて感じたことですがそのまま変換すると面の欠け、穴などが激しく3DCGソフト等で後加工していくのは厳しいように思います。加工が難しいと思われる要因としては以下の通りです。
 ・面と面がつながっておらず1面づつ修正していく必要がある。
 ・穴あき部分も他の面が連結されていないため埋めていく作業量が大きい。
 ・面の法線方向がバラバラなため部分ごとに裏返しの面になっており修正する必要がある。
 ・ある程度形状が判別できるようにするため面分割が細かくなることで編集負荷も膨大になる。
以上のようにそのままでの加工は難しいです。

どのようにすれば良いのか?
ではどのようにすれば良いかですが基本的にDepthセンサーで取得した情報をなるべくプログラム側で加工を行い 後処理を少なくした方が良いように思います。
ソフトウェアでの編集加工は力技なのに比べプログラム側ではいろいろと処理ができそうだからです。
どのようにしていくのが最善かは現段階では不明ですが現在研究を行っていますので判明次第レポートしたいと思います。 以上、MeshLabによるPCD点群データのメッシュ化でした。

有限会社マグネットインダストリー
西内伸太郎

林です。Point Cloud Libraryの全体像の紹介記事の2回目です。



この記事(②)ではPoint Cloud Libraryの概要として「どのような機能が搭載されていて、それらを用いてどういったことが実現できるか」について紹介します。


■Point Cloud Libraryの概要

Point Cloud Libraryは、(OpenCVと同じように)数々の処理モジュールから構成されている、C++言語による大規模点群処理ライブラリです。ロボットビジョン(ロボットが自立的に作業するための眼として使うアプリケーション)、および(ロボットではないが、デプスセンサーと計算機で点群を処理する)3Dコンピュータビジョンや、その他3D処理目的に使用できる3D点群処理が数多く格納されたライブラリです。リアルタイム処理性(計算スピード)と、マルチプラットフォーム対応を目的として、C++言語が採用されており、Windows, Mac OSX, LinuxのそれぞれのOSにおいて、C++言語によってPCLに用意されている数多くのクラスを使用することができます。

以下のPCLの公式サイトの「about(英語)」に、概要が説明されています。

Point Cloud Libaryついての説明(about)

このaboutの真ん中程にも書かれているように、PCLはトヨタ社やTrimble社など、3D点群を測量やマシンビジョンで活用している会社を中心に、多くの企業から支援を受けながら開発されています。

PCLのライセンスは「3-clause BSD license」 であり、商用にも研究用にも無料で使用できます。また、安価なKinect/Intel RealSenseなどのデプスセンサーだけでなく、高価な商用のLIDARセンサー等とも連携しており(※ PCLの点群データ形式でこれらのセンサーから簡単にデータを取得可能)、建築、医療、自動車、などの少し効果な起業向けの点群処理用途にも全て対応しています。

2014年9月末現在、PCL1.7.2が最新版であるPCLでは、モジュールごとに点群処理に必要な様々な処理が網羅的に収録されています。中心となるモジュール群で網羅されている点群処理に必要な基本機能、「点群の入出力処理」「フィルタリング」「レジストレーション(位置合わせ)」「近傍探索」「キーポイントと特徴量の計算」「点群の3D可視化」などに加えて、ここ最近では「物体認識」「人物追跡と人物姿勢推定」「トラッキング(物体追跡)」などの発展的な機能もオプションモジュールとして追加されてきています(以下のaboutページから引用の画像が、モジュール間の関係性を表示)。


■Point Cloud Libraryを用いた、単純なアプリケーション例

以下の動画は、Kinectからリアルタイムに取得した点群を、PCLのVisualizationモデルに搭載されているCloud Viewerで表示しているデモ動画です



Point Cloud LibraryではKinectなどのデプスセンサーから取得したデータを、次回紹介を行うPCL専用の点群データ構造であるPointCloudオブジェクトとして変換された状態で取得し、この動画のようにそれを(簡単に)3D可視化することが可能です。Primisense社のセンサーの場合は、「OpenNIGrabber」というPCLのクラスで、デプスセンサーからのRGBD点群のリアルタイム取得が可能です。


■デプスセンサーのSDKとの比較:PCLは基本的な点群処理が全部入り

PCLは既に説明したように「主な点群処理」が広く網羅的に収録されたライブラリです。この記事の読者には、PCLは使用してはいないものの、Kinect SDKやOpenNI 2などのライブラリは既に使用されているエンジニアの方も多いと思います。そこで、それらのライブラリとPCLの違いを、整理しておきたいと思います。

例えばKinect for Windows SDKでは、3D投影はされていない距離画像の状態で毎フレームの3Dデータが取得されますが、先程のKinectからのリアルタイム点群取得の動画の例では、PCLのクラス(OpenNIGrabber)が、「距離画像+RGB画像からのPointCloudへの変換処理」をブラックボックス化し、担当してくれています。

すなわちPCLを用いれば、Kinectから毎フレームのデータは既に3D点群に変換された状態で取得できるので、その毎フレームの点群データを用いた点群処理にのみ集中することが可能です。ここには、「点群取得以降の点群処理が主目的であり、それ以外の煩わしさをなるべく除いておきたい」という、PCLの設計志向を感じることができます。事実、最新のPCL1.7.2では、Intel社のReal Senseデプスセンサーや、自律走行車などの研究で使われているVelodyne社のセンサーなどからも、リアルタイムに毎フレームのPCL形式の点群を簡単に取得することができます。(参考:Velodyne社のセンサーから点群取得ができる、HDL Grabberクラスのチュートリアル)。また、PCL専用の点群データ形式である.pcd形式での入出力に加え、例えば旧来から使われている「.ply形式」での保存もPCLではできるので、点群を処理したあと.ply形式で保存して、点群処理・メッシュ処理のアプリケーションからその点群を読み込んで編集・加工することも可能です(例:先日PCCでも紹介したMeshlabなど)。

また、例えば、先程のデプスセンサーからの点群取得・可視化のプログラムに、毎フレームで取得した点群をフィルタリングで処理するといったことも、既にPCLに用意されているクラスを用いると、たった数行のコードの追加のみで実現できます(例:バイラテラルフィルタでノイズ除去をしながら滑らかな点群にする)。

点群ファイルを1つ(もしくは複数)読み込み、それ(ら)に対して、レジストレーション、セグメンテーション、特徴点の計算とマッチングなどを行う際も同様で、それぞれ「registarion」「segmentation」「features」などのPCLの各モジュールに、多くの基本的な点群処理が用意されているので、それらを用いて(良い意味で誰でも)点群処理プログラムを作成することが可能となっています。(※ もちろん、OpenNIなどと同時にPCLを使用すれば、リアルタイムで取得する人間のポーズ情報と、点群処理を組み合わせたアプリケーションを作成することも可能です)。

以上のように、Kinect SDKなどが「モーションキャプチャ」や「ナチュラルインターフェース」が主な目的であるのに対して、PCLの目的は「3D点群や距離画像そのものに対する処理」が、幅広く収録されており、点群自体を処理・解析することが目的であることが、今後の記事を通してもわかっていただければ幸いです。

ここまでKinectを入力センサーを用いた話ばかり例示していたので、勘違いを防ぐために最後に強調していましたが、PCLは汎用的な点群データ全てを入力とできるライブラリです。専用データ形式以外の.pcdデータ以外の3Dデータでも、内容を読み込んで、PCLのPointCloud<PointT>にさえ格納してしまえば、後は豊富なPCLの点群処理クラスを全て活用できるからです。従って、この記事の序盤にも話した、「昔から存在するレーザー測量などによる高価で高精度な3Dスキャナー」を用いて取得した点群データも、Point Cloud Libraryで処理することは当然ながら可能です。更に言うと、CG的に生成したデータでも、Point Cloud Libraryのデータ形式に変換すれば処理することが当然ながら可能です。別途、そういった記事も書くかもしれませんが、3Dプリンターで出力するための綺麗な穴がないデータに加工するようなアプリケーションも、Point Cloud Libraryを用いれば作ることも可能です。

以上のように、Kinect SDKなどはデプスセンサーの生データ取得とモーションキャプチャデータへのアクセスが主な機能であるのに対して、PCLは点群データの処理が広く全部入っている大規模ライブラリです。


■まとめ

以上、今回の前編では「PCLの概要」について紹介しました。あらゆる点群データ全てに対して使用可能であるPoint Cloud Libraryは、ライブラリの規模も大きくてすぐには使いこなせないかもしれませんが、3D点群を活用する皆様の武器になると思います。ぜひ注目しててみてください(次回の③に続きます)。

林 昌希

林です。本記事では、Point Cloudコンソーシアムと関連が非常に深い、無料でオープンソースの「3D点群処理」のための大規模ソフトウェアライブラリであるPoint Cloud Library(PCL)の概要について紹介します。

Point Cloud Libraryのサイト

Point Cloud Libraryは、本コンソーシアムと非常に深く関連するソフトウェアであり、3D点群データの処理を行う場合には、Point Cloud Libraryは現状唯一の選択となる場合が多いです。私は以下のブログの記事にて、PCL登場初期の頃から、日本語では当時は情報がほとどん存在しなかったPCLのチュートリアル記事を、先行的に発信してきました。

DERiVEコンピュータビジョンブログのシリーズ記事まとめページ

以下の③回の記事を通して、「Point Cloud Libraryを用いるとどういった点群処理が使用可能で、それらの搭載された処理を用いるとどういったことが実現できるのか」について紹介し、PCLの全体像についてまずは皆様に掴んで頂こうと思います。




この記事①では「PCLの登場の経緯」と「なぜPCLに注目すべきなのか」をまず説明します。次回の記事②ではPoint Cloud Libraryの概要として「どのような機能が搭載されていて、それらを用いてどういったことが実現できるか」について紹介します。最後の記事③では、「点群とはどういうものか?」という事を押さえたのちに、その(一般的な)点群データ形式をPCLではどのように取り扱かうかの概要を述べる予定です。


■PCL登場の経緯

PCLは、かつて存在していた米国のロボットのベンチャー起業「willow garage」が2011年に開発を始めた、3D点群処理向けの大規模、C++言語によるオープンソースのソフトウェアライブラリです。同じくwillow garageが開発に大きく関わっている「OpenCV (Open Computer Vision)」の、3D点群版のようなものとも考える事ができます。RGB画像を入力としたコンピュータビジョン向けの大規模オープンソースライブラリにはこれまでOpenCVが存在していましたが、2010年のMicrosoft Kinectの登場と同時期に、点群データを入力とする際の3Dロボットビジョン向けに登場したのがPCLです。

(※ ロボットビジョン: 画像系のデータを入力として実世界を解析する処理一般をコンピュータビジョンと呼びますが、(動く実体のある)ロボット向けのコンピュータビジョン的な処理のことを「ロボットビジョン」と呼び分けることが多いです。)

以前は高価な(精密な計測を行う測量目的の)3Dセンサーしか市場には存在しませんでしたので、3D点群処理のニーズは、建築土木などでの測量や、工場用機械・ロボットでのマシンビジョン、また医療用の3Dスキャン(MRIやCT)などにしか存在しませんでした。もちろん、そういった3Dデータをアプリケーションする需要が高価なスキャナーとセットでしか存在しませんでしたので、そういったセンサーを売る会社にしか、3D点群データを解析したり可視化するソフトウェアを開発できる人材も居ませんでした。当然ながら、計測器が高価ですので、規模の大きい企業で無い限りは数百万以上もする3D計測器は購入ができないので、そもそも需要は限られていました。

一方、自動車の安全運転向けに、「ステレオカメラ」で撮影した前方デプス映像から、歩行者や障害物をビジョン技術により検知する製品は存在します。ただ、ステレオカメラで得られる距離画像はノイズや欠損も多く正確性に欠くので、高価な3D計測器のような綺麗な3D点群は得られません。(参考になる記事: コンピュータビジョンのセカイ 第21回:前方衝突防止システム – 「平行等位ステレオ」による3次元形状復元)

■Kinect登場とPoint Cloud Library

それが2010年のMicrosoft Kinect発売以降、安価なデプスセンサーで(動画による)3D点群撮影が、手軽に実現できるようになりました。これに伴い、PCLのような**3D点群処理をまとめたオープンソースライブラリ**の必要性も出てきました。以前から高価な3D測量の業界にも、商用の点群処理ライブラリやSDK類は存在していたものの、(今風の)無料でかつオープンソースである点群処理ライブラリの登場は嘱望されていました。また、ロボット業界としても、これまでのステレオカメラやレーザー測量ベースのものがKinectなどの安価なデプスセンサーに差し代わっていくので、ロボット向けの3Dビジョン処理がまとまっていて、かつKinectなどと簡単に接続できるライブラリを用意することで、ロボットの研究開発を(便利なライブラリを用いて)より加速度を上げて発展させたいモチベーションがありました。そこで、登場したのがPoint Cloud Libraryです。

PCLは、お手伝いロボットの米ベンチャー企業「Willow Garage」社が先導して開発していたのもあり、ロボット系の研究コミュニティの最新成果が非常に数多く収録される傾向のあるライブラリです。特にロボット系のエンジニアがデプスセンサーを用いてビジョン系の研究開発をするには、PCL以外にライブラリや開発環境の選択肢(競合)が少なく、ほとんどのロボット研究者はPCLを使っている状況であるのもこの傾向を加速させています。PCLはトヨタ社やTrimble社(レーザー測量の会社)などが投資していることもあり、自動車系の工場や、建築とプラントでの測量などの目的の処理も、優先的に追加される傾向があります(後述)。

とはいえ、次回②の「PCLの概要」で説明するように、PCLは特定の分野の処理だけが収録されているものではなく、様々な用途で応用が利く普遍的な点群処理がバランス良く、網羅的に収録されている大規模ライブラリです。そして、Kinect for Windowsで取得できる点群データにも、Point Cloud Libraryの各処理は全て適用できるので、あなたが点群処理を使いこなせるようになれば、Kinectを用いて点群処理が今からでも始められます。PCLは、コンピュータビジョンに強くないと使いこなせないのもあり、まだまだ研究開発者中心の使用のみで、広く普及しているライブラリではありませんが、今後数年でデプスセンサーのモバイルへの普及に伴って、使用する機会が増えていくことが用意に予想できます。


■まとめ

以上、今回の前編では「PCLの登場の経緯」について紹介しました。点群処理は昔から高価な3D計測器を用いる分野では存在していたのが、Kinectの登場で、みなさんが誰でも行えるようにはなった、でもまだ一般には普及していない、という状況が知って頂けたと思います。(次回の②に続きます)。

林 昌希

前回の記事ではPCLでデプスセンサーからの点群情報を可視化、PCDデータとして保存するところまで紹介いたしました。 今回は前回保存したPCDデータを読み込み可視化する方法を紹介したいと思います。
Windows8.1でPCLを動かすまで(初心者編①)… インストール方法
Windows8.1でPCLを動かすまで(初心者編②)… VC++初期設定
Windows8.1でPCLを動かすまで(初心者編③)… PCLインクルード
PCLでデプスセンサー(Xtion)から点群情報を取得し可視化 … 点群情報の取得
PCLで点群データにデプスセンサーからの色情報を追加 … 色情報の取得
PCLで取得した点群データをPCDデータとして保存 … PCDデータ保存

■PCDデータを読み込み可視化

<1>PCDデータを用意
前回の記事で保存したPCDデータを用意します。
PCDデータを用意できない場合はPCL公式サイトのMedia/「PCL Tutorial at IROS 2011」よりダウンロードすることができます。(ページ最下段の「data」からダウンロード)

<2>サンプルコードをコピペ
PCL公式サイトのDocumentation/Tutorials/Visualizationの「The CloudViewer」ページよりサンプルコードをコピペします。

#include "stdafx.h"
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
    
int user_data;
    
void 
viewerOneOff (pcl::visualization::PCLVisualizer& viewer)
{
    viewer.setBackgroundColor (1.0, 0.5, 1.0);
    pcl::PointXYZ o;
    o.x = 1.0;
    o.y = 0;
    o.z = 0;
    viewer.addSphere (o, 0.25, "sphere", 0);
    std::cout << "i only run once" << std::endl;
    
}
    
void 
viewerPsycho (pcl::visualization::PCLVisualizer& viewer)
{
    static unsigned count = 0;
    std::stringstream ss;
    ss << "Once per viewer loop: " << count++;
    viewer.removeShape ("text", 0);
    viewer.addText (ss.str(), 200, 300, "text", 0);
    
    //FIXME: possible race condition here:
    user_data++;
}
    
int 
main ()
{
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>);
    pcl::io::loadPCDFile ("pcd_data.pcd", *cloud);
    
    pcl::visualization::CloudViewer viewer("Cloud Viewer");
    
    //blocks until the cloud is actually rendered
    viewer.showCloud(cloud);
    
    //use the following functions to get access to the underlying more advanced/powerful
    //PCLVisualizer
    
    //This will only get called once
    viewer.runOnVisualizationThreadOnce (viewerOneOff);
    
    //This will get called once per visualization iteration
    viewer.runOnVisualizationThread (viewerPsycho);
    while (!viewer.wasStopped ())
    {
    //you can also do cool processing here
    //FIXME: Note that this is running in a separate thread from viewerPsycho
    //and you should guard against race conditions yourself...
    user_data++;
    }
    return 0;
}
これまで同様に1行目に#include “stdafx.h”を追記します。
39行目「pcl::io::loadPCDFile (“my_point_cloud.pcd”, *cloud);」の「”my_point_cloud.pcd”」を自分で制作したPCDデータのパスとファイル名に変更します。
(パスは.cppが置かれている場所から相対で追っていくか、絶対パスで記述します)
ちなみにPCDデータ容量により読み込みに時間がかかり正常に動いてないように感じることがあるかもしれません。 私は何度も引っかかってしまいました。。。
エラー表示がなければ気長に待つと表示されると思います。
上記のように表示されるかと思います。
画像の左側にある球体は17行目の記述で「sphere」球を生成しているためです。
またカウントされている経過時間の数値は22行~33行目までの記述によるものです。


ここまでのブログ記事でPCLのインストール、設定を行いデプスセンサーから情報を取得・可視化・保存を行い保存したPCDデータを可視化するまでの一連の流れを紹介いたしました。
各機能につきましては機会があれば都度紹介していきたいと思います。
まずはここまででPCL導入の一区切りとしたいと思います。

マグネットインダストリー
西内伸太郎

前回の記事ではPCLでデプスセンサーからの点群情報を可視化するところまで紹介いたしました。 今回はPCLで取得した点群データをローカルに保存する方法を紹介したいと思います。
Windows8.1でPCLを動かすまで(初心者編①)… インストール方法
Windows8.1でPCLを動かすまで(初心者編②)… VC++初期設定
Windows8.1でPCLを動かすまで(初心者編③)… PCLインクルード
PCLでデプスセンサー(Xtion)から点群情報を取得し可視化 … 点群情報の取得
PCLで点群データにデプスセンサーからの色情報を追加 … 色情報の取得

■点群データをPCD形式で保存

<1>前回使用したサンプルコード
前回の記事で紹介しましたサンプルコード。
#include "stdafx.h"
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>

 class SimpleOpenNIViewer
 {
   public:
     SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}

     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud)
     {
       if (!viewer.wasStopped())
         viewer.showCloud (cloud);
     }

     void run ()
     {
       pcl::Grabber* interface = new pcl::OpenNIGrabber();

       boost::function<void (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&)> f =
         boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);

       interface->registerCallback (f);

       interface->start ();

       while (!viewer.wasStopped())
       {
         boost::this_thread::sleep (boost::posix_time::seconds (1));
       }

       interface->stop ();
     }

     pcl::visualization::CloudViewer viewer;
 };

 int main ()
 {
   SimpleOpenNIViewer v;
   v.run ();
   return 0;
 }

<2>PCDデータ保存用のコードを追加

#include "stdafx.h"
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>

#include <pcl/io/pcd_io.h> //pcd_io.hをインクルード
 
 class SimpleOpenNIViewer
 {
   public:
     SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}
 
     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud)
     {
       if (!viewer.wasStopped())
         viewer.showCloud (cloud);
	   //--------------------------------------------「S」キーを押すとPCDデータを保存
	   if(GetAsyncKeyState('S')){
			pcl::io::savePCDFileASCII ("保存先のパス/pcd_data.pcd" , *cloud);
		}
     }
 
     void run ()
     {
       pcl::Grabber* interface = new pcl::OpenNIGrabber();
 
       boost::function<void (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f =
         boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);
 
       interface->registerCallback (f);
 
       interface->start ();
 
       while (!viewer.wasStopped())
       {
         boost::this_thread::sleep (boost::posix_time::seconds (1));
       }
 
       interface->stop ();
     }
 
     pcl::visualization::CloudViewer viewer;
 };
 
 int main ()
 {
   SimpleOpenNIViewer v;
   v.run ();
   return 0;
 }
上記コードの5行目に「pcd_io.h」のインクルードを指定。
17行~19行目までに「S」キーを押したときにPCDデータを保存するコードを記述します。
「保存先のパス」部分に保存先のパスを記述して「pcd_data.pcd」を保存します。
ここでは後々の処理を考えてASCIIデータで保存するように「savePCDFileASCII」と指定しています。バイナリデータで保存する場合は「savePCDFileBinary」とすると保存することができます。


次の記事では今回保存したPCDデータをPCLで可視化する方法を紹介します。

マグネットインダストリー
西内伸太郎

前回の記事でPCL公式サイトよりコードをコピペしてデプスセンサー(Xtion)から点群情報の取得を行いました。 取得した点群データに色情報がありませんでしたので今回は点群データに色情報をつけて可視化する方法を紹介したいと思います。
Windows8.1でPCLを動かすまで(初心者編①)… インストール方法
Windows8.1でPCLを動かすまで(初心者編②)… VC++初期設定
Windows8.1でPCLを動かすまで(初心者編③)… PCLインクルード
PCLでデプスセンサー(Xtion)から点群情報を取得し可視化… 点群情報の取得

■デプスセンサーから点群位置情報を取得の際、色情報も同時に取得します

<1>PCL公式サイトからのサンプルコード
前回の記事で紹介しましたサンプルコードに#include “stdafx.h”を追加します。
#include "stdafx.h"
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>

 class SimpleOpenNIViewer
 {
   public:
     SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}

     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
     {
       if (!viewer.wasStopped())
         viewer.showCloud (cloud);
     }

     void run ()
     {
       pcl::Grabber* interface = new pcl::OpenNIGrabber();

       boost::function<void (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr&)> f =
         boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);

       interface->registerCallback (f);

       interface->start ();

       while (!viewer.wasStopped())
       {
         boost::this_thread::sleep (boost::posix_time::seconds (1));
       }

       interface->stop ();
     }

     pcl::visualization::CloudViewer viewer;
 };

 int main ()
 {
   SimpleOpenNIViewer v;
   v.run ();
   return 0;
 }

<2>コードを一部変更します

#include "stdafx.h"
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>

 class SimpleOpenNIViewer
 {
   public:
     SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}

     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud)
     {
       if (!viewer.wasStopped())
         viewer.showCloud (cloud);
     }

     void run ()
     {
       pcl::Grabber* interface = new pcl::OpenNIGrabber();

       boost::function<void (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&)> f =
         boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);

       interface->registerCallback (f);

       interface->start ();

       while (!viewer.wasStopped())
       {
         boost::this_thread::sleep (boost::posix_time::seconds (1));
       }

       interface->stop ();
     }

     pcl::visualization::CloudViewer viewer;
 };

 int main ()
 {
   SimpleOpenNIViewer v;
   v.run ();
   return 0;
 }
上記コードの10行目と20行目の「PointXYZ」を「PointXYZRGB」に変更します。
コードを変更しビルドを行うと色情報つきの点群データを可視化することができます。

<3>各点群情報の取得方法
上記で変更した箇所の記述内容により取得できる点群色情報が変化します。
コードの記述内容と説明を一部紹介します。
コード 説明
PointXYZ 点群3D位置情報のみ取得
PointXYZRGB 点群3D位置情報にRGBの色情報をつけて取得
PointXYZRGBA 点群3D位置情報にRGBAの色情報をつけて取得(Aは透明度Alpha)
PointXYZI 点群3D位置情報に輝度の色情報をつけて取得
上記の説明と同様にコードを変更すると可視化した結果が変わってくるかと思います。


以上までがPCLのインストールから各初期設定、デプスセンサーから点群情報を取得し可視化するまでの流れとなります。

マグネットインダストリー
西内伸太郎

前回までにPCL・Visual C++のインストール、Visual C++ Expressの初期設定、PCLのインクルードを行ってきました。 今回はサンプルコード記述して実際に点群データを取得していきたいと思います。

Windows8.1でPCLを動かすまで(初心者編①)… インストール方法
Windows8.1でPCLを動かすまで(初心者編②)… VC++初期設定
Windows8.1でPCLを動かすまで(初心者編③)… PCLインクルード

■Visual C++ 2010 Expressを起動しコードを書いていきます

<1>Visual C++ 2010 Express起動前の確認
今回はASUS Xtion(デプスセンサー)を使って点群を取得していきます。 Xtionがつながれて付属のドライバがインストールさせれていることを確認します。

<2>Visual C++ Express起動
前記事のWindows8.1でPCLを動かすまで(初心者編①~③)で紹介いたしました設定を完了できた状態で作業を行います。
プロジェクトにコードを記述していきます。
記述するコードはPCLの公式ページよりコピーして持ってきます。
http://mobile.docs.pointclouds.org/documentation/tutorials/
http://mobile.docs.pointclouds.org/documentation/tutorials/openni_grabber.php#openni-grabber

<3>PCL公式ページからのサンプルコード

#include "stdafx.h"
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>

 class SimpleOpenNIViewer
 {
   public:
     SimpleOpenNIViewer () : viewer ("PCL OpenNI Viewer") {}

     void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
     {
       if (!viewer.wasStopped())
         viewer.showCloud (cloud);
     }

     void run ()
     {
       pcl::Grabber* interface = new pcl::OpenNIGrabber();

       boost::function<void (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr&)> f =
         boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);

       interface->registerCallback (f);

       interface->start ();

       while (!viewer.wasStopped())
       {
         boost::this_thread::sleep (boost::posix_time::seconds (1));
       }

       interface->stop ();
     }

     pcl::visualization::CloudViewer viewer;
 };

 int main ()
 {
   SimpleOpenNIViewer v;
   v.run ();
   return 0;
 }
そのままコピーしてデバック開始をするとビルドエラーが出ますので上記のように
1行目に#include “stdafx.h”
を追記します。

以上記述してデバック開始すると以下のようにXtionからの点群データを取得することができます。

ただしそのままですと色情報がなく白い点群が表示されます。
色情報を取得するにはプログラムを多少変更する必要があります。

続きは表示させた点群に色情報をつけていく方法を紹介します。

マグネットインダストリー
西内伸太郎

前回までにPCL・Visual C++のインストール、Visual C++ 2010 Expressの初期設定までを紹介しました。 今回はVisual C++ 2010 Expressの設定を行っていきます。
前回は起動して正常に動作させるまででしたが今回はいよいよVisual C++ 2010 Expressを起動してPCLをインクルードするところを紹介します。

Windows8.1でPCLを動かすまで(初心者編①)… インストール方法
Windows8.1でPCLを動かすまで(初心者編②)… VC++初期設定

■Visual C++ 2010 Expressの設定

<1>Visual C++ 2010 Express起動、新規作成
Visual C++ 2010 Expressを起動します。
ファイル/新規作成/プロジェクト/を選択します。
Win32 コンソール アプリケーションを選択しプロジェクトを作成します。

<2>Visual C++ 2010 Expressの構成プロパティ設定
プロジェクトを作成するとプロジェクト名を選択し右クリック、プロパティを選択します。


プロパティウィンドウが開きますのでここで設定を行っていきます。


以下の設定を行っていきます。
●全般
・文字セット:マルチバイト文字セットを使用する
・プラットフォームツールセット:Windows7.1SDK
・プラットフォーム:x64(構成マネージャーで変更)

●C/C++ :全般 :追加のインクルードディレクトリ
C:\Program Files\PCL 1.6.0\include\pcl-1.6;
C:\Program Files\PCL 1.6.0\3rdParty\Boost\include;
C:\Program Files\PCL 1.6.0\3rdParty\Eigen\include;
C:\Program Files\PCL 1.6.0\3rdParty\FLANN\include;
C:\Program Files\PCL 1.6.0\3rdParty\Qhull\include\libqhullcpp;
C:\Program Files\PCL 1.6.0\3rdParty\VTK\include\vtk-5.8;
C:\Program Files\OpenNI\Include;

●リンカー :全般 :追加のライブラリディレクトリ(すべての構成)
C:\Program Files\PCL 1.6.0\lib;
C:\Program Files\PCL 1.6.0\3rdParty\FLANN\lib;
C:\Program Files\PCL 1.6.0\3rdParty\Boost\lib;
C:\Program Files\PCL 1.6.0\3rdParty\Qhull\lib;
C:\Program Files\PCL 1.6.0\3rdParty\VTK\lib\vtk-5.8;
C:\Program Files\OpenNI\Lib64;

●リンカー :入力 :追加の依存ファイル(Debug)
pcl_apps_debug.lib;
pcl_common_debug.lib;
pcl_features_debug.lib;
pcl_filters_debug.lib;
pcl_io_debug.lib;
pcl_io_ply_debug.lib;
pcl_kdtree_debug.lib;
pcl_keypoints_debug.lib;
pcl_octree_debug.lib;
pcl_registration_debug.lib;
pcl_sample_consensus_debug.lib;
pcl_search_debug.lib;
pcl_segmentation_debug.lib;
pcl_surface_debug.lib;
pcl_tracking_debug.lib;
pcl_visualization_debug.lib;
flann-gd.lib;
flann_s-gd.lib;
flann_cpp_s-gd.lib;
qhull6_d.lib;
qhullcpp_d.lib;
qhullstatic_d.lib;
qhullstatic_p_d.lib;
openNI64.lib;
OpenNI.jni64.lib;
NiSampleModule64.lib;
NiSampleExtensionModule64.lib;
MapReduceMPI-gd.lib;
mpistubs-gd.lib;
vtkalglib-gd.lib;
vtkCharts-gd.lib;
vtkCommon-gd.lib;
vtkDICOMParser-gd.lib;
vtkexoIIc-gd.lib;
vtkexpat-gd.lib;
vtkFiltering-gd.lib;
vtkfreetype-gd.lib;
vtkftgl-gd.lib;
vtkGenericFiltering-gd.lib;
vtkGeovis-gd.lib;
vtkGraphics-gd.lib;
vtkhdf5-gd.lib;
vtkHybrid-gd.lib;
vtkImaging-gd.lib;
vtkInfovis-gd.lib;
vtkIO-gd.lib;
vtkjpeg-gd.lib;
vtklibxml2-gd.lib;
vtkmetaio-gd.lib;
vtkNetCDF-gd.lib;
vtkNetCDF_cxx-gd.lib;
vtkpng-gd.lib;
vtkproj4-gd.lib;
vtkRendering-gd.lib;
vtksqlite-gd.lib;
vtksys-gd.lib;
vtktiff-gd.lib;
vtkverdict-gd.lib;
vtkViews-gd.lib;
vtkVolumeRendering-gd.lib;
vtkWidgets-gd.lib;
vtkzlib-gd.lib;opengl32.lib;

●リンカー :入力 :追加の依存ファイル(Release)
pcl_apps_release.lib;
pcl_common_release.lib;
pcl_features_release.lib;
pcl_filters_release.lib;
pcl_io_release.lib;
pcl_io_ply_release.lib;
pcl_kdtree_release.lib;
pcl_keypoints_release.lib;
pcl_octree_release.lib;
pcl_registration_release.lib;
pcl_sample_consensus_release.lib;
pcl_search_release.lib;
pcl_segmentation_release.lib;
pcl_surface_release.lib;
pcl_tracking_release.lib;
pcl_visualization_release.lib;
flann.lib;
flann_s.lib;
flann_cpp_s.lib;
qhull6.lib;
qhullcpp.lib;
qhullstatic.lib;
qhullstatic_p.lib;
openNI64.lib;
OpenNI.jni64.lib;
NiSampleModule64.lib;
NiSampleExtensionModule64.lib;
MapReduceMPI.lib;
mpistubs.lib;
vtkalglib.lib;
vtkCharts.lib;
vtkCommon.lib;
vtkDICOMParser.lib;
vtkexoIIc.lib;
vtkexpat.lib;
vtkFiltering.lib;
vtkfreetype.lib;
vtkftgl.lib;
vtkGenericFiltering.lib;
vtkGeovis.lib;
vtkGraphics.lib;
vtkhdf5.lib;
vtkHybrid.lib;
vtkImaging.lib;
vtkInfovis.lib;
vtkIO.lib;vtkjpeg.lib;
vtklibxml2.lib;
vtkmetaio.lib;
vtkNetCDF.lib;
vtkNetCDF_cxx.lib;
vtkpng.lib;
vtkproj4.lib;
vtkRendering.lib;
vtksqlite.lib;
vtksys.lib;
vtktiff.lib;
vtkverdict.lib;
vtkViews.lib;
vtkVolumeRendering.lib;
vtkWidgets.lib;
vtkzlib.lib;
opengl32.lib;

以上をプロパティに設定していきます。
上記をコピペで設定できますので自分のインストール先が合っているか確認して設定します。
プロジェクトごとに設定が必要なのでプロジェクトを新規作成する場合は設定が必要です。


■追記情報(2014年11月12日)

追加のインクルードディレクトリ、ライブラリディレクトリのパスが通っていないことによりビルドエラーになります。 PCLのインストール先によりパスが変わることがあります。インストール先をご確認いただきパスを入力していただくとパスが通るかと思います。
OS、Visual C++ 2010、PCLの各バージョンがブログ記事と同じでないと記述内容が変わることがあります。 またPCL All-In-One Installerのバージョンと、使用されますVisual Studioのバージョンが一致していないと動作しませんのでご注意下さい。
ここまでの設定完了しましたらいよいよコードを記述していきビルドして動かしていくことができます。
OSにより設定手順が若干違いますが基本的に設定しなければならない内容は同じとなっています。

続きはサンプルコードを書いて点群の読み込みを紹介します。

マグネットインダストリー
西内伸太郎

前回までにPCL・Visual C++のダウンロード・インストールまでを紹介しました。
今回はVisual C++ 2010 Expressの初期設定を行っていきます。
Visual C++ 2010 Expressを起動して設定を行う前に前準備として必要となる設定があります。
64bitでのビルドを行うための準備、環境変数を通し方を順番にメモ書きで紹介していきます。

Windows8.1でPCLを動かすまで(初心者編①)… インストール方法

■Visual C++ 2010 Expressの初期設定

<1>Visual C++ 2010 Expressのソリューションプラットフォームにx64を設定するために
Microsoft Windows SDK for Windows 7 and .NET Framework 4を公式サイトよりダウンロード・インストール
なぜか再頒布可能パッケージが邪魔をしてインストールできないことがあるので前回の記事で紹介した再頒布可能パッケージを使用してアンインストールします。
・Microsoft Visual C++ 2010 x86 Redistributable ←アンインストール
・Microsoft Visual C++ 2010 x64 Redistributable ←アンインストール
アンインストール完了後にダウンロードしたWindows 7 and .NET Framework 4をインストールします。
インストールが完了したら先ほどの再頒布可能パッケージを再度インストールします。
Visual C++ 2010 Expressを起動しソリューションプラットフォームでx64が選択できることを確認します。

<2>環境変数のパスを設定
環境変数が通っていないと(dllファイルまでのパスが通っていないと)ビルドの際に「dllファイルが見つかりません」とエラーになってしまいます。
Debug、Releaseフォルダに「C:/Program Files/PCL 1.6.0/bin」の.dllファイルをコピーすれば使えますが200MBほどのデータをプロジェクトごとにコピーするわけにはいきませんので環境変数を通すことで解決します。
コントロールパネルのシステム/詳細設定/環境変数にて追加することができます。
今回は「Rapid Environment Editor」という便利なソフトありますのでこちらを使って設定します。
公式ページのヘッダ部分Latest versionからダウンロードできます)

インストール完了後、アプリを起動するとシステム変数(読み取り専用)、ユーザー変数と2つエリアが表示されます。
まずはヘッダメニュー/ファイル/管理者として実行を選択します。
システム変数の読み取り専用が消えているのを確認します。
システム変数の「Path=c:\Program File(x86)\………を選択し右クリックで値の追加をし
「C:/Program Files/PCL 1.6.0/bin」
「C:/Program Files/OpenNI/Bin64」
を入力します。
これで環境変数の設定完了できます。
もしどうしても環境変数が通らない場合(ビルド時にファイルが見つからないエラーがでる場合)C:\Windows\System32にdllファイルをコピーすると動きますがあくまで応急処置です。

ここまででPCL、Visual C++ 2010 Express起動までの準備が整いました。
後はVisual C++ 2010 Expressでインクルードの設定を行えば初期設定完了です。
続きは次の記事で紹介します。

有限会社マグネットインダストリー
西内伸太郎

本コンソーシアムに関するお問合せ、PCL・3D関連のご相談はお問合せフォームよりご連絡ください。

PCL
Copyright (C) 2014 PointCloudConsortium All Rights Reserved.