写真測量:MeshLabによる点群ファイルのジオリファレンシング

アイキャッチ, meshlab 写真測量

MicMacWebODMで何らかの理由でジオリファレンシングできなかったり、COLMAPやRegard3Dのようにジオリファレンシングできない3Dモデリングソフトを使ったりしてplyファイルだけが得られた場合を考えます。このplyファイルをMeshLabでジオリファレンシングし、GISで表示可能なcsvファイルにします。DEMはGIS上で作れます。

標定点(GCP)データの準備

下図のMeshLabには、Rigard3Dで作成した密な点群を読み込んであります。

MeshLabでのジオリファレンシングには最低4点の標定点が必要です。実際にどう測量するかは別に譲るとして、ここでは平面直角座標系で4点準備しました。(緯度経度はだめです。)

なお、MeshLabの標定点座標は大きな桁数を扱えないようですので、(-80000, -215000)をオフセットしたgcp2.txtファイルを使います。

標定点座標とオフセットした標定点座標
gcp.txt: 標定点座標、gcp2.txt: オフセットした標定点座標

Reference sceneツールを使う

Reference sceneツールを開き、「Load Reference Points From File」ボタンでgcp2.txtファイルを開きます。すると下図右側のように、標定点座標が読み込まれます。あとは、plyファイルの座標を設定したい行番号をクリックして選択し、「Pick current point on MOVING」ボタンでMeshLab画面上の対応する点をクリックしていけば良いのです。

Reference sceneツールにオフセットした標定点座標を読み込む
Reference sceneツールにオフセットした標定点座標を読み込む

下図は標定点1を画面上でダブルクリックしてplyの座標値を読み込んだところです。

密な点群画面で標定点に対応する場所をクリックする
密な点群画面で標定点に対応する場所をクリックする
すだくん
すだくん

やっぱり標定点を画像じゃなく点群上で探すのは難しいよ。大きな対象物を選ばないと大変だ。GUIで標定点を探せるWebODMはやっぱりいいね。

4点すべて選択し、「Calculate Rototranslation」ボタンを押すと、下図のようにError値が表示されます。また、右下の画面には座標変換パラメータが表示されています。この誤差でよければ、「Apply」ボタンを押します。

標定点誤差と座標変換パラメータ
標定点誤差と座標変換パラメータ
かわのさん
かわのさん

誤差は12cm~38cmだけど、見にくい密な点群の上で標定点を捜したにしては上出来じゃない?

すだくん
すだくん

それそれ。この元画像は100m上空から撮影したものだけど、手持ちカメラで川などを撮影したものなら誤差はもっと小さくできるよね。

変換結果の確定(Freeze)

ここまでの作業で、MeshLab上の表示の上では座標変換が実行され、例えば距離を測定すると実距離が出てきますが、実際にはデータそのものは変更されていません。ウインドウ右側のレイヤパネルを見ると、レイヤ名にアスタリスク(*)がついていることで未確定であることがわかります。変換結果をエクスポートするには、まず変換結果を確定する必要があります。

レイヤパネルでレイヤを選択し、右ボタンメニューでMatrix: Freeze Current Matrixを選びます。出てきたダイアログでApplyボタンをクリックすると結果が確定され、レイヤのアスタリスクも消えます。

変換結果を確定する
変換結果を確定する

変換結果のエクスポート

「File」 – 「Export Mesh As…」 メニューで、「XYZ Point Cloud (with or without normal) (*.xyz)」を選び、ファイル名を決めます。すると右側のダイアログが表示されるので、Normalのチェックを外してOKします。以上で、ジオリファレンスがされた点の座標が、下図の例ではpointcloud.xyzというファイルとして出力されます。このファイルは、単にx,y,z値がスペースで区切られて1行に1点記録されたテキストファイルです。

変換結果のエクスポート
変換結果のエクスポート

以上でMeshLabでの作業は終わりです。

必要ならオフセットを元に戻す

xyzファイルは単純なテキストファイルですので、Excelなどで簡単にオフセットを加算して平面直角座標系に戻すことができるのですが、点の数が多すぎてExcelの行数に収まらないことも起こります。Windows上でできるだけ簡単にオフセットを加算したCSVファイルに変換するために、VBScriptを作成してみました。

以下のコードをメモ帳にコピペしてxoffset, yoffsetの値を修正し、convert.vbsというファイル名で保存し、コマンドプロンプトで以下の冒頭コメントのように実行します。InFile.xyzと書いてあるところが、今回の例ではpointcloud.xyzということになります。

'VBScriptでxyzファイルにオフセットを加算したcsvを作成
' あらかじめxoffset, yoffsetをこのスクリプトconvert.vbsに書き込んでおく
' CMD.EXEを起動してxyzファイルのあるフォルダに移動し、
' cscript convert.vbs < InFile.xyz > OutFile.csv
' でオフセットが加算される。"<" ">"は標準入出力へのリダイレクション

Option Explicit
Const xoffset = -80000
Const yoffset = -215000

On Error Resume Next
Dim objStdIn
Dim objStdOut
Dim intExitCode

Set objStdIn = Wscript.StdIn

Set objStdOut = Wscript.StdOut

Dim line
Do While objStdIn.AtEndOfStream = false
  line = Split(objStdIn.ReadLine)
  objStdOut.WriteLine  (line(0)+xoffset)&","&(line(1)+yoffset)&","&line(2)
Loop

Set objStdIn   = Nothing
Set objStdOut  = Nothing

If Err.Number <> 0 Then
    intExitCode = 1
Else
    intExitCode = 0
End If

Wscript.Quit(intExitCode)

ファイルに出さずに画面に出すと以下のようになります。Copyright行が出ていますので、変換結果を利用するときにはエディタで削除するかQGIS側の読み込み設定で読み飛ばすかしてください。

オフセットを元に戻す
オフセットを元に戻す
すだくん
すだくん

今回はできるだけ特別な準備なしで変換できるようVBScriptを使ったけど、Copyright行が出てしまうとかメンドウだし、Pythonとか得意な言語がある人はそれを使えばいいよ。

QGISに読み込んでみる

できあがったcsvファイルをQGISに「CSVテキストレイヤを追加…」で読み込み、標高で色分けすると以下のようになります。OpenStreetMapと比べても正しい位置に表示されていることがわかります。

ジオリファレンスされた結果をQGISで確認
ジオリファレンスされた結果をQGISで確認
すだくん
すだくん

流況シミュレーションの地形データに利用したいだけなら正しい座標にする必要もないかもね。それならわざわざVBScriptでオフセットを元に戻す作業もいらないよ。

かわのさん
かわのさん

そう言うなら、ジオリファレンシング自体不要じゃない?

すだくん
すだくん

いやいや、ジオリファレンシングしないと寸法や傾きまで信用できなくなるだろ?ジオリファレンシングはどうしても必要だよ。

オフセットをどうするかは目的次第ですが、QGISに読み込んでしまえば、このまま使ってもよし、DEMに変換するもよし、もう自由自在に使えますね! Have fun!

写真測量まとめ:素人でもできる測量を目指して
写真測量は、最近だとドローンを駆使して行うものと思っている方も多いと思いますが、素人・初心者の皆さんが相手にする小さいエリアなら手持ちカメラでも可能です。安価に、簡単にできる方法を探ります。

コメント

タイトルとURLをコピーしました