本記事ではPCL点群データから画像を作成する方法を紹介します。

1. 使用する環境

・Ubuntu 20.04 LTS
・PCL 1.8.1
・OpenCV 4.2

2. プログラムのダウンロードとコンパイル

以下のリンクからPCL点群データを画像に変換するプログラムをダウンロードします。
PointCloudtoImage
 
ダウンロードを行った後、以下のコマンドを実行します。
プログラムをコンパイルして、実行しています。

cd ~/ダウンロード
mv PointCloudtoImage.zip  ~/
cd ~/
unzip PointCloudtoImage.zip
cd PointCloudtoImage/build
cmake ..
make
./PointCloudtoImage

プログラムを実行するとウィンドウが開き、PCL点群データから生成された画像が表示されます。
今回は”PointCloudtoImage”ディレクトリのPCL点群データファイルcloudA.pcdを読み込み、画像を生成しています。
cloudA.pcd(PCL点群データ)を表示するには、以下のコマンドを実行します。

pcl_viewer cloudA.pcd

 

図1. cloudA.pcdをpcl_viewerで表示
図2. プログラムの実行結果

以下のプログラムはPCL点群データから画像を出力するプログラムです。

#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/io/pcd_io.h>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>

int main() {
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    pcl::io::loadPCDFile<pcl::PointXYZRGB>("../cloudA.pcd", *cloud);

    int camera_height = cloud->height;
    int camera_width = cloud->width;
    cv::Mat pcl_image(camera_height, camera_width, CV_8UC3);

    for (int y = 0; y < camera_height; y++) {
        for (int x = 0; x < camera_width; x++) {
            cv::Vec3b color = cv::Vec3b(
                cloud->points.at(y * camera_width + x).b,
                cloud->points.at(y * camera_width + x).g,
                cloud->points.at(y * camera_width + x).r);

            pcl_image.at<cv::Vec3b>(cv::Point(x, y)) = color;
        }
    }

    cv::imshow("PointCloud Image", pcl_image);
    cv::waitKey(0);

    return 0;
}

 
プログラムの処理の流れは以下の通りです。
1. PCL点群データファイルを読み込む
2. PCL点群データの高さと横幅を取得して、その値をOpenCVの画像サイズに使用
3. cv::Matを使用して、OpenCVの画像を生成
4. ネストされたループを使用して、各点の色情報をPCL点群データから取得し、OpenCVの画像に設定

 
9行目でPCL点群データファイルを読み込んでいますが、この部分をChoreonoidやRealSenseから取得したPCL点群データを使用するように書き換えることで保存されたデータ以外も画像にできます。

3. PCL点群データから画像に変換する方法

PCL点群データは、3次元空間内の点の位置情報と、各点に対する色情報を持つデータセットです。これは、深度画像と色画像(RGB画像)から取得できます。深度画像とは、カメラやセンサーで捉えた画像で、各ピクセル(画素)にその点までの距離(深度)が記録されています。色画像(RGB画像)は、各ピクセルにその点の色の情報が記録された画像です。深度画像の各ピクセルに対応するカメラからの3次元座標を計算し、それらの座標と色画像の各ピクセルの色情報を組み合わせてPCL点群データを作成します。この際には、画像の左上から順にPCL点群データを1次元配列に格納していきます。
図3は横幅640、高さ480のカメラからPCL点群データを取得した場合の変換を表した図です。
 


図3. 深度画像と色画像からPCL点群データに変換

 
PCL点群データから画像を作成する場合は、逆に1次元配列に格納されたPCL点群データを2次元配列に順番に格納することで、画像を取得することができます。このとき画像の縦幅と横幅は、点群データを取得時のカメラのサイズになります。PCL点群データは縦幅と横幅のデータを持っている場合がありますが、ない場合もありますので事前に確認をしてください。
図4は横幅640、高さ480のカメラから点群データを取得し、画像を作成した場合の変換を表した図です。

 


図4. PCL点群データから画像データに変換

 
この方法を使用するとChoreonoidやRealSenseから取得したPCL点群データを画像にすることができます。しかし、PCL点群データが画像を作成するのに足りない場合、画像データの生成に失敗することもあります。その場合はこの方法は使用することができません。
 
 
いかがだったでしょうか。
本記事ではPCL点群データから画像を作成する方法を紹介しました。
皆様のお役に立てばと思います。