MeshLab を使って曲率を取得するのをバッチ処理して自動化する

MikuHatsune2017-04-05

3次元物体の曲率を以前やっていたのだが、自前のスクリプトに重大なミスが発覚したので、プログラミング力の高い人のプログラムから借用することを考える。
離散的な3D オブジェクトから、平均曲率とガウス曲率を計算したいが、意外とない。
と思ったらMeshLab にあるようである。
.obj を読みこんで、Filters > Color creation and processing > Discrete curvature と選択すると、mean かgaussian か選べと出るので、どちらか選んでapply すると、こんな感じになる。

色は Filter > Quality measure and computations > Quality mapper applier から、カラースケールを適当にいじる。
Render > Show vert quality histogram を選ぶと、今回は頂点について曲率を計算しているので、頂点の値に応じたヒストグラムが出てくる。これはGUI では背景が濃い青だったので白抜きの文字が本当は見えている。

 
ここで、この値情報を保持したままファイルに書き出してその値が欲しいのだが、値の情報は .ply 形式しか保持してくれないようである。なので、ファイルの保存は .ply にする。
ここで、.ply にはbinary 形式とascii 形式があるので、export のときにadditional parameters のbinary encoding のチェックをはずさないと、その後のデータ処理で困る。
 
というのがGUI での一連の操作である。ここで、この処理をしないといけないファイルが複数あるとき、for loop に入れたい。
この時に使えるのがmeshlabserver コマンドである。
まず、このGUI での操作を、Filters > Show current filter script に行って、マクロ化したスクリプト .mlx ファイルを手にいれる。ここでは、Filter タブでの操作(のみ、たぶん)が記録される。
こうして、GUI 操作がマクロ化されたので、

meshlabserver -i input.obj -o output.ply -s procedure.mlx -om vq > /dev/null 2>&1

とする。入力はなんでもよく、出力に .ply を指定すれば勝手に .ply 形式で出力してくれる。-s でやりたい操作.mlx を指定して、今回は頂点の曲率の値が欲しいので、-vq で vertices quality 値を .ply ファイルに書き出しておく。
ここで、meshlabserver の標準出力がどうしても邪魔なので、/dev/null 2>&1 であの世へ送る。
 
この場合に問題になるのが、-o output.ply がどうしてもbinary 形式の .ply ファイルしか書き出さないようで、けっこうなmeshlab ユーザーが困っているようである。というわけで、binary 形式で出力した .ply をascii 形式の .ply に変換したいのだが、どうもいいのがないようなのでR で頑張る。
R のRvcg パッケージに .ply ファイルをbinary 形式でも読める関数があるので、これで .ply ファイルを読み込み、目的のquality 値だけ取り出して出力できるようにバッチ処理にしてみる。

# quality.R
library(Rvcg)
args <- commandArgs(TRUE)
ply <- vcgPlyRead(args)
cat(sprintf("%f", ply$quality))
cat("\n")

これをバッチ処理すると、コンソールにquality 値がずらずらと出力されるので、適当にファイルに保存する。

Rscript --slave --vanilla quality.R $ply.ply > `printf %04d $ply`.tmp

R でバッチ処理したものを出力すると、

[1] 1

というのが残るので、cat して改行コードを付け足しておく。
 
とすればなんとか取得できる。