投稿

5月, 2020の投稿を表示しています

Open3D 0.10.0

イメージ
Open3Dの新しいバージョン0.10.0がリリースされた。 http://www.open3d.org/2020/05/19/open3d-0-10/ 今回のリリースではVisualization関連が大幅にアップデートされている。これによって、Physically-based rendering (PBR)なども取り扱うことができるようになった模様。Computer Vision系のライブラリでこういう高級なレンダリングを扱えるものは無かったように思う。時間を見つけて少し触ってみよう。

色付き点群(Colored Point Cloud)の位置合わせ

イメージ
色付きの2つの点群を位置合わせするための変換行列を推定する。Open3Dでは色付き点群の位置合わせのために、open3d::registration::RegistrationColoredICPが用意されている。この関数を利用する際には、以下のヘッダファイルをインクルードする必要がある。 #include <Open3D/Registration/ColoredICP.h> 色付き点群の生成方法については、 RGBDImageからPointCloudへの変換(Open3D) を参照。 色付き点群pcd_target, pcd_srcを位置合わせするコードの例は以下の通り。この例では、位置合わせに全ての点群を用いるのではなく、まず、ダウンサンプルを行い位置合わせの対象とする点群を削減している。また、ダウンサンプル後に、各点に対する法線を推定する処理が入っている。位置合わせ結果は、result_icp(open3d::registration::RegistrationResultクラス)に保持される。このクラスに位置合わせの精度(fitness)や変換行列の情報が保持されている。 double voxel_size = 0.05; auto pcd_target_down = pcd_target->VoxelDownSample(voxel_size); auto pcd_src_down = pcd_src->VoxelDownSample(voxel_size); pcd_target_down->EstimateNormals( open3d::geometry::KDTreeSearchParamHybrid(voxel_size, 30)); pcd_src_down->EstimateNormals( open3d::geometry::KDTreeSearchParamHybrid(voxel_size, 30)); // trans_matには変換パラメータの初期値を入れることができる。 // 初期値無しの場合は、4x4単位行列(Eigen::Matrix4d)をセットすれば良い auto result_icp = open3d::reg

RGBDImageからPointCloudへの変換(Open3D)

イメージ
Open3Dでopen3d::geometry::RGBDImageから点群データ(Point Cloud)を生成する方法について紹介する。Open3Dでは点群データはopen3d::geometry::PointCloudで取り扱うことができる。RGBDImageからPointCloudへの変換は以下のように書ける。 auto pcd = open3d::geometry::PointCloud::CreateFromRGBDImage( rgbd_img, camera_intrinsics); ここで、camera_intrinsics_はカメラ内部パラメータの情報で、以下のような感じで設定できる。 camera_intrinsics = open3d::camera::PinholeCameraIntrinsic( image_width, image_height, fx, fy, cx, cy); また、ポイントクラウド同士の統合や変換行列の適用も以下のように簡単に行える。extrinsic_mat1, extrinsic_mat2はそれぞれカメラ外部パラメータ行列(Eigen::Matrix4d)となっている。 auto pcd1 = open3d::geometry::PointCloud::CreateFromRGBDImage( rgbd_img1, camera_intrinsics_); auto pcd2 = open3d::geometry::PointCloud::CreateFromRGBDImage( rgbd_img2, camera_intrinsics_); pcd1->Transform(extrinsic_mat1); // World座標へ変換 pcd2->Transform(extrinsic_mat2); // World座標へ変換 *pcd1 += *pcd2; // pcd1にpcd2を追加 以下はTUM RGB-D Datasetのカメラ位置姿勢の真値を使って、各視点から得られるポイントクラウドを一つの座標に統合した結果となっている。単純に点群データを位置合わせして表示してみると、元のRGB-Dデータにはノイズが結

Color Map Optimization

イメージ
Open3DでRGB-Dデータの統合 で作ったモデルをよく見ると、以下のように生成されたモデルのテクスチャがボケてしまっているのが確認できる。 たぶん、カメラ位置姿勢の誤差やローリングシャッターの影響などでこのような結果になってしまっているんだろうと思う。そこで、今回は、Open3Dに実装されているColor Map Optimizationを試してみた。 Color Map Optimization http://www.open3d.org/docs/release/tutorial/Advanced/color_map_optimization.html 実装されているのは、以下の論文で提案されている手法となっている。 Color Map Optimization for 3D Reconstruction with Consumer Depth Cameras http://vladlen.info/papers/color-mapping.pdf Color Map Optimizationを適用した結果は以下のようになった。左が最適化前、右が最適化後の結果となっている。最適化後の方が、より鮮明になっていることが確認できる。ただし、最適化にはそこそこの処理時間が必要なので、実際に利用する際にはキーフレーム選択のようなことをやって利用するフレームを間引く必要があるかもしれない。

cv::MatをOpen3Dの形式に変換する

Open3DでRGB-Dデータの統合 でカラー画像、デプス画像を読み込んで以下のようにRGBDImageを生成する必要があった。 std::shared_ptr rgbd_img; rgbd_img = open3d::geometry::RGBDImage::CreateFromColorAndDepth(rgb, depth, depth_scale, depth_trunc, false); Open3Dにも画像の読み込みを行うための関数が用意されているが、OpenCVで既に書いているプログラムをベースにする場合は、OpenCVのcv::Mat形式からOpen3Dのopen3d::geometry::Image形式に変換できると都合が良い。ということで、cv::MatからOpen3Dの画像形式への変換を行ってみた。カラー画像の変換は以下のようにするとうまくいった。OpenCVはBGR、Open3DはRGBなので、まず、カラーチャンネルの入れ替えを行っている。 cv::Mat3b rgb_img; cv::cvtColor(bgr_img, rgb_img, cv::COLOR_BGR2RGB); open3d::geometry::Image rgb; rgb.Prepare(rgb_img.cols, rgb_img.rows, rgb_img.channels(), sizeof(uchar)); memcpy(rgb.data_.data(), rgb_img.data, rgb_img.rows * rgb_img.cols * rgb_img.channels() * sizeof(uchar)); 同様にデプス画像は以下のようにすることで変換できた。ただし、デプス画像depth_imgは16bitのpngで保存されているものを読み込んでいる。 open3d::geometry::Image depth; depth.Prepare(depth_img.cols, depth_img.rows, depth_img.channels(), sizeof(short)); memcpy(depth.data_.data(), depth_img.data,

Open3DでRGB-Dデータの統合

Open3Dを使ってKinectなどから取得したRGB-Dのデータを統合し、一つの3Dモデルを生成してみる。RGB-Dデータの統合のためには、各RGB-D画像を取得したカメラの位置姿勢情報が必要となるが、今回は統合の部分だけを試してみたいので、ミュンヘン工科大学のRGB-Dデータセットを入力として使った。 RGB-D SLAM Dataset and Benchmark https://vision.in.tum.de/data/datasets/rgbd-dataset 今回は「rgbd_dataset_freiburg3_long_office_household」をダウンロードして使ってみた。データセットには、カラー画像とデプス画像の他にそれぞれのデータが取得されたタイムスタンプと画像ファイルの対応表rgb.txt,depth.txtやカメラの位置姿勢の真値groundtruth.txtなどが含まれている。 このデータセットを使うとGround Truthの位置姿勢があるため、統合処理のみを試すことが可能になる。ただし、rgb, depth, groundtruthでそれぞれの取得タイミングが微妙に異なるので、まずは近い時刻のデータをまとめ上げる必要がある。このまとめ上げには、Datasetと一緒に公開されている、ツールを利用すると簡単にデータの準備を行うことができる。 Useful tools for the RGB-D benchmark https://vision.in.tum.de/data/datasets/rgbd-dataset/tools とりあえず、公開されているpython scriptをダウンロードする。この中の、associate.pyを使うことで近い時刻のデータをまとめることができる。今回は、まず、rgbとdepthのデータを統合し、その後、統合したデータとGround Truthのデータを統合することで、rgb,depth,groundtruthのデータを作成した。注意点として、ツールはPython2系で書かれているため、Python3系で利用するためには一部修正する必要がある。 python associate.py rgb.txt depth.txt > rgb_depth.txt python as