LoginSignup
9
2

More than 3 years have passed since last update.

COLMAPを使った3次元復元結果の座標変換方法

Last updated at Posted at 2021-04-19

はじめに

「だーれだ?」
「えっ!?もしかして...よしこちゃん?」
いいえ、Mas-sensyn です。
COLMAPは以前ご紹介したSfM(Structure from Motion)のフリーソフトですが、SfMにはスケールがありません。
また、今回、別の方法で表された座標系に変換したい、という要望がありました。
そこで今日は、COLMAPの3次元復元結果を、別の座標系に座標変換する方法についてご紹介いたします。

目的

COLMAPで作られた3次元復元結果を、撮影したカメラ位置を定義している世界座標系に、座標変換する。

注釈

  1. COLMAPの復元結果にはスケールがありません。しかし、本手法を適用することによって、復元結果にスケールも与えることができます。
  2. では、もともとのCOLMAPでの3次元復元結果の座標系は何かと言うと、point cloudの中心位置に原点を定義され、スケールは、最長の方向を[-10,10]mにスケールしています。(ref: google group)
  3. 本記事でご紹介する方法は、COLMAP自身が提供する機能Geo-registrationを用いる手法です。 RANSACを使用して座標変換とスケール(scale+Euclid変換)を導きます。詳細なアルゴリズムは、こちらのソースコードを参照してください。
  4. 点群を直接表している座標系には座標変換できません。即ち、point cloudを、直接、point cloudを別の世界座標で表現した世界座標に変換することはできません。 それをしたい場合は、独自にICP等を適用する必要があります。

結果画像の例

やりたいことをイメージしやすいように、結果画像の一例を貼っておきます。
下図のように、座標系が変換されます。この際、画像からは分かりませんが、実際にはスケールも補正されています。
single_camera optionあり
座標変換前のsparse復元結果

image.png
座標変換後のsparse復元結果

前提

今回用いた環境

GPU: Nvidia GeForce GTX1060 (denseな結果を得るにはGPUが必須です。逆にsparseな結果だけでいいなら要りません。)
OS: Ubuntu18.04 or Ubuntu20.04

使用したソフトウェア

COLMAP 3.7

手順概要

はじめにsparseなreconstructionを通常の方法で行い、sparseな結果(point cloud)をCOLMAPのGeo-registrationを用いて座標変換し、その結果をdense reconstructionします。はじめのsparseなreconstructionは通常の方法なので省略しますが、それも含めた方法を知りたい場合は、最後に載せたscript例をご参照下さい。

sparseな結果の座標変換方法

概要

sparseな結果(point cloud)をCOLMAPのGeo-registrationを用いて座標変換します。

入力

画像群
最低3つ以上のカメラ位置、向きを、目的の世界座標系で表した、以下の形式のテキストファイル。ref: COLMAP Geo-registration

image_name1.jpg X1 Y1 Z1
image_name2.jpg X2 Y2 Z2
image_name3.jpg X3 Y3 Z3
...

出力

出力ディレクトリ内に保存された、以下3つのファイル(座標系が変換されただけで、入力と全く同じ形式)
cameras.bin images.bin points3D.bin

手順

以下のreferenceそのままですが、

colmap model_aligner \
    --input_path /path/to/model \
    --output_path /path/to/geo-registered-model \
    --ref_images_path /path/to/text-file

reference

COLMAP geo registration

denseな結果の座標変換方法

概要

前節のsparseな結果を用いて、denseな結果を作成するだけです。

入力

sparseなgeoregistration出力ディレクトリ内に保存された、以下3つのファイル
cameras.bin images.bin points3D.bin

出力

座標変換された以下2つのファイル
meshed-poisson.ply, meshed-delaunay.ply

手順

全てを一つのコマンドにしたautomatic_reconstructionが使えないので、以下のreference通りにcommand lineで実行します。
reference: COLMAP command line interface

入力画像群からdenseな座標変換結果を出すまでのscript例

#!/bin/sh
# This is a script for COLMAP georegistration and then run dense reconstruction
####

# treat arguments
USAGE="$0 <work directory which have ../images/>"

if [ $# -lt 1 ]; then
    echo $USAGE
    exit 1
fi

# sparse reconstruction
# The project directory must contain a directory "images" with all the images.
DATASET_PATH=$1 #work directory. ../images is the image directory.
cd ${DATASET_PATH}

colmap feature_extractor \
   --database_path $DATASET_PATH/database.db \
   --image_path $DATASET_PATH/../images
   --ImageReader.single_camera 1

colmap exhaustive_matcher \
   --database_path $DATASET_PATH/database.db

mkdir $DATASET_PATH/sparse

colmap mapper \
    --database_path $DATASET_PATH/database.db \
    --image_path $DATASET_PATH/../images \
    --output_path $DATASET_PATH/sparse

# georegistrate sparse point cloud
GEOREGIDIR=georegistration
mkdir -p sparse/${GEOREGIDIR}
colmap model_aligner --input_path sparse/0 --output_path sparse/${GEOREGIDIR} --ref_images_path ../campose.txt --robust_alignment 1 --robust_alignment_max_error 0.01

# dense reconstruciton for georegistered data
mkdir $DATASET_PATH/dense

colmap image_undistorter \
    --image_path $DATASET_PATH/../images \
    --input_path $DATASET_PATH/sparse/${GEOREGIDIR} \
    --output_path $DATASET_PATH/dense/${GEOREGIDIR} \
    --output_type COLMAP \
    --max_image_size 2000

colmap patch_match_stereo \
    --workspace_path $DATASET_PATH/dense/${GEOREGIDIR} \
    --workspace_format COLMAP \
    --PatchMatchStereo.geom_consistency true

colmap stereo_fusion \
    --workspace_path $DATASET_PATH/dense/${GEOREGIDIR} \
    --workspace_format COLMAP \
    --input_type geometric \
    --output_path $DATASET_PATH/dense/${GEOREGIDIR}/fused.ply

colmap poisson_mesher \
    --input_path $DATASET_PATH/dense/${GEOREGIDIR}/fused.ply \
    --output_path $DATASET_PATH/dense/${GEOREGIDIR}/meshed-poisson.ply

colmap delaunay_mesher \
    --input_path $DATASET_PATH/dense/${GEOREGIDIR} \
    --output_path $DATASET_PATH/dense/${GEOREGIDIR}/meshed-delaunay.ply

reference

COLMAP command line interface

上記では1つのカメラを使用することを前提としています。
その場合、上記"feature_extractor"のところにあるように、"--ImageReader.single_camera 1"としておくことにより、カメラ位置復元のエラーをかなり削減できます。
下記は、single_camera optionあり、なしの比較一例です。実際のカメラ経路が不明なので、正解が分からないでしょうが、single_camera optionあり、の方が現実に近かったです。

single_camera optionなし
single_camera optionなし

single_camera optionあり
single_camera optionあり(--ImageReader.single_camera 1)

まとめ

以上、最低3つ以上のカメラ位置、向きを、目的の世界座標系で表したテキストファイルを入力として、
COLMAPで作られた3次元復元結果を、撮影したカメラ位置を定義している世界座標系に、座標変換する方法についてまとめました。

おわりに

COLMAPは結構メジャーなソフトなので、こういう機能も実装されていて便利だな、と感じました。
ただ、カメラ位置を定義した世界座標系を用いて座標変換を行うため、カメラ位置復元の誤差が乗るため、直接の目的が復元結果を合わせることであれば、誤差は大きくなってしまうため、ICP等で直接point cloudを合わせ込みにいったほうがいいでしょう。
それでは皆様、よいCOLMAPライフを!Ciao!

9
2
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
9
2