3Dデータの欠損をMeshLabを使って穴埋めする filling in blanks of 3D data using MeshLab

はじめに

 iPhone 12 ProのLiDAR機能を使って3Dファイルを得て来たが,CloudCompareでまずは体積や面積を求めるというような言わば幾何学的空間分析での基礎的な作業の際に,3Dデータの欠損に基づくエラーには悩まされてきた。そして,単に体積や面積を求めることよりも,3D空間データの位置の信頼性そのものも気にかかるところではあった。
 この種の問題を解決してくれるであろうMeshLabに本日出会った。他の用件もあるけど,大きな関心があり,ちょっと触ってみた。

1 始める前に

 MeshLabは,3Dメッシュデータ用ではあるが,点群ファイルにも使うことができるらしい。読み込み対応ファイルのうち,ぼくが使うiPhone 12 ProのアプリはScaniverseとMetascanで,これらのエキスポートファイル形式との関係では,MetascanのメッシュデータではSTLとOBJ,点群データではPLYとXYZ,ScaniverseのメッシュデータではSTLとOBJ,点群データではPLYに限られる。何らかの作業が終わって出力する形式はCloudCompareの利用を考えると,メッシュデータではSTLとOBJ,点群データではPLYに限られる。
 MeshLabアプリは,https://www.meshlab.net/ から提供されており,最新のものは MeshLab version: 2022.02 28/Feb/2022であり,mac,Windows64,何れにも対応している。さきほど何れにもインストールし,何の問題も無かった。同梱のRead.meには次の但し書きがある。

図1 MeshLab アイコン

Please, when using this tool, cite the following reference:

Meshlab: an open-source mesh processing tool.
P. Cignoni, M. Callieri, M. Corsini, M. Dellepiane, F. Ganovelli, G. Ranzuglia
Proceedings of the 2008 Eurographics Italian Chapter Conference,
ISBN: 978-3-905673-68-5, pp. 129-136, DOI: 10.2312/LocalChapterEvents/ItalChap/ItalianChapConf2008/129-136

 さて,操作マニュアルを調べてみた。
MeshLAB Tutorial ここには,はじめに,Cloud Compare:  Point cloud and mesh editor,MeshLab  Point cloud and mesh editor,とあって,ネット上では,meshファイル対応と流布されているが,点群のPLYファイルが重視されている。
MeshLab Documentation November 13, 2017 | Author: Lucy Sharp | Category: N/Aこれは,2017年発行でPDFの形でダウンロードできる。ほとんど図が無くて覚え書きのような印象である。

追記 Jan. 27, 2023: School of Design, Faculty of Liberal Arts and SciencesのMeshLab: Point Cloud to Mesh の情報はpoint cloudをmeshに変換するためのMeshLab使用の注意点を学生に示したものである。一般に3Dスキャナーで得られたpoint cloudの点数は膨大のため,その前に軽量化せよという。iPhone 12 Pro LiDARを使うボクには全くあてはまらない。ただ,MeshLabがそういう使い方のためでもあると理解できたのである。File > Import mesh,のコマンドは,そういう訳で,point cloudを当然含んでいることになる。そして,そのあと,mesh出力が可能なのである。point cloudファイルはここでは.ascなので,三段階の処理が必要になる。ぼくの場合の3Dスキャン結果の出力データはplyファイルなので,この必要は無いと思うが,図2のOBJファイル表示を見ていると,メッシュファイルであっても,faceの裏表が不揃いなので,plyファイルについてもこの三段階の作業は必要かも知れないと思う。そこで,一応,上記サイトの情報を次にコピペしておく。上記サイトには図も掲載されている。

Once it has imported successfully then you need to do three operations:

1. Compute Normals: (メッシュの三角形面faceを作成するために必要な法線の作成)
Filters > Normals, Curvatures and Orientation > Compute Normals for Point Sets
– Accept the default settings by pressing Apply. Wait

2. Optimise your point cloud: (これはpoint cloudの膨大なpoint数を縮減するための操作でぼくの場合は不要か)
Reduce the density of the point cloud by choosing
Filters > Point Set > Point Cloud Simplification

 このPoint Cloud Simplificationのパネルについて,
In the “Number of Samples” field pick somewhere between 100,000 (quicker, less detailed) and 1,000,000 (slower, bigger but more detailed). Click Apply. Wait.
 You will now see two versions of your point cloud scan – the original and the reduced version.
 この画面の説明として,You can switch them on and off (like Photoshop layers) in the right hand panel. Also you can drag the point size lower to get a clearer view of your scan.

3. Convert the optimised point cloud to a mesh: (点群をメッシュに)
Click to turn off the original point cloud, leaving just the optimised version on and selected. Then Choose
Filters > Remeshing, Simplification and Reconstruction > Surface Reconstruction: Ball Pivoting
Accept the defaults and select Apply. Wait – potentially for a while.
After the process is complete you will then be able to view your mesh – if it is too poor quality you could try again by optimising the original point cloud with a higher sample count.
When you are happy with the result export the mesh using
FILE > EXPORT MESH AS
and choose an appropriate file type – OBJ would be suitable for bringing into Rhino, Blender, 3DS etc
NOTE: when you bring your mesh into your 3d application there may be “back to front” sections; in Rhino these will show up as darker patches.
To unify these normal, issue the command
UnifyMeshNormals
and select everything. This will flip all back to front faces in the same way.

 なお,Rhino, Blender, 3DSなどの嗜好を知るのに,【2021年】3DCADとBlenderは違う~3Dモデリング検証編 は参考になるかもしれない。ただ,ぼくはこの分野には全く関心がない。

2 メッシュファイル OBJの読み込み

 mouseのWindows 10にイントールしたMeshLabを立ち上げて,ScaniverseでLiDAR撮影した段ボール三箱のOBJファイルを読み込んだ。メーンメニュー File > Import mesh を実施したが,まともに読み込めない。右のペーンの下部に,赤字でエラーメッセージがある。

図2 メッシュファイルOBJを読み込んだが

 ネット検索して,SOURCE FORGEのMeshLab Discussionで,たぶん原因を見つけた。

windbrand2012-05-18

Hiya,
I tried to import and obj model (sleeveless top) in meshlab, however it gives
this error: “Error details: some materials definitions were not found, a
default white material is used where no materials are available”. The model
imports correctly but like the error says there is no material, it’s just
blank. All my material files are there, I even tried to copy over all the
files into the same folder as the .obj file. Does anyone know what might be
causing this?
Thanks.

Giulio2012-06-05

Try this, it worked for all my .obj with the same error. Seems that Meshlab
doesn’t allow spaces in the name of the files.
Rename texture, .mtl file, .obj file without spaces. Open with wordpad o
notepad .mtl file and .obj file and at the beginning change the name of the
texture and of the .mtl file. Open .obj with meshalb again!

 CloudCompareでは日本語のファイル名には何の問題もなかったが,MeshLabでは問題が生じるのであろう。図2のメーンペーンの下縁の紫色の中央に,ぼくの日本語「段ボール箱」を含むファイル名が文字化け無しで表示されている。元のファイル名は,段ボール箱scaniverse_Jan10_2complete.jpg, .mtl, objである。an10_2completeの,_も気になるところである。carton_scaniverse_Jan10_2complete.jpg, .mtl, .objと変更した。ブラウザーではこの変更は見えるが,MeshLabで何回か,読み込もうとしてもファイル名の変更が実現しないので,Windowsを再起動するなどした。そして,開いたのであるが,図次のようなメッセージが出ている。奇妙なことに,objファイル名は変更したものと一致するが,jpgファイルでは段ボール箱が残っている。

図3 手作業でファイル名を替えてもだめだった

  そこで,共有しているmacでzipファイル名を丸ごと替えることにしたのであるが,これを解凍すると図4のようであった。図4でハイライトがあるcarton_scaniverse⋯⋯⋯⋯⋯.zipを解凍すると,この直ぐ上のファイル名になるというか,替えたzipファイル名が全く反映していない。
 それゆえ,Scaniverseに格納されているファイルに戻って,ここでファイル名を替えて,エアドロップでmacに移動して,解凍して,Windowsに移動した。macからWindowsのこの関連ファイルを削除しようとしたがどうしてもできなかった。Windows内のファイルはWindows内で削除しなければならなかった。スクリーンショットの場合と異なる形だ。
 そして,MeshLabを立ち上げて,File > Import Mesh,を実行して,図5のように,問題無く,読み込むことができた。

図4 macのファインダでのzipファイル名を英字にしても元の日本語ファイル名は残っている
図5 やっと問題なくOBJファイルを取り込めた

 なお,ファイル名に日本語が入っていたのが原因かどうか,わからない。Windowsが,ファイル名にFEPの関係か勝手にスペースを入れていたようで,スペースが原因の可能性もある。図4では,「_ 」の代わりに「_ 」が入っているが,Windowsで見ると,「⋯⋯Jan10 _ 2complete.obj 」とか,なっていたし。

以上,Jan. 26, 2023記。

3 CloudCompareのファイル名書式の確認を

 図5の絵作りは見事なものであった。どこにも穴が無い。後に示すがMeshLabでこの図5のファイルをwireframeやFace表示したが,ホールが見つからない。一体のunitで,ホールholeを検知detectして,それを表示して,手作業である部位についてはキャンセルなどして,一気に穴埋めする,というようなプロセスをGitHubなどで検索したが,そういう質問はあっても回答は全く無い。ネット上にはそういう役立つコンテンツが無い。昨日,半日ぐらい,英語サイトを中心に探したがみつからなかった。公式マニュアルもリスト的で役に立たない。MeshLabのプラグインリストでpythonのディスクリプションは見つかったが,変数定義が見えないので,理解するのが困難だ。

 とにかく,ぼくとしては,少なくとも10年以上に渡って積み上げられ,無料で公開されているCloudCompareとMeshLabを使って,極めて極めて低次の希望を叶えることである。ぼくの希望は何だろうか。研究のツールなのだけど,高齢なので研究テーマも極めて限定的になる。とにかく,海岸地形の計測ということになろうか。その際にpoint cloudの欠損は問題になるものだろうか。大したことでは無いだろう。身近な直方体の体積をiPhone 12 Pro+ LiDAR写真測量で求める で拘った体積計算も,point cloudファイル情報の精度とCloudCompareの能力を知りたかったからであった。実は,体積そのものにも,研究的な関心がある訳でも無い。ぼくの性癖に由来するものである。ぼくが幾何学やpythonの高い素養があればこの泥沼に入ってしまうのだけど,幸い,そういう素養が無いので,助かっている,と切実に思う。

 さて,そういう訳で,iPhone 12 Pro LiDARで得た3D point cloudやmeshでみっともない欠落などがあった場合,自然界のものなので,そもそも簡単に補修できるものではない。欠落部分が研究の観点から重要な場合,アプリなんかでは,補修できない。現場に行って,3Dスキャンして取得するしかない。と考えると,point cloudやmeshの穴や破れが補修の対象になるのはかなり特殊な目的に限定される。この例が体積や表面積の計算であった。まあ,ぼくが何を求めているのか,都度確認をしないと行けない。

 本章のタイトルのテーマを含めて,新たなポスティングを作成した方がいいと考えた。それは,
iPhone-LiDAR + Scaniverse or Metascanから書き出された点群とメッシュを比較
である。

以上,Jan. 27, 2023記。

 次の章を当初は,「MeshLabでメッシュOBJを点群PLYに変換する」としていた。どうもこの考え方には根本的な問題があるようだ。Can I generate Point Cloud from mesh ? を読んで何となく理解できた。ぼくはmeshからいわば均等のpoint cloudが作られると考えた。その発想が根本的に誤りだった。
 MeshLabでの作業として,点群point cloudからメッシュを作るのが妥当だとすると,ぼくからするとiPhone 12 Pro内のアプリで3Dスキャンした後,点群PLYとしてもメッシュOBJとしても出力できるので,MeshLabは不要ということだ。すでに 元伊勢大饗石のLiDAR測量 では,CloudCompareで,点群からメッシュに変換し,さらにこのメッシュから点群に変換しているので,この後半のプロセスを実行すれば良い。
 そして,MeshLabを使おうと思った動機を思い出した。点群の欠損を探してそれを穴埋めすることだ。でも点群PLYで得られる像がメッシュOBJ に比べてより不完全ならば,メッシュOBJを使うことになる。

以上,Jan. 31, 2023記。

4 MeshLabで欠損を探す1

 MeshLabを立ち上げて,File > Import Mesh,で,段ボール三箱のScaniverseで作成したobjファイルを開く。それが図5になるのであるが,最新のJan. 26のものをまずはここでは使いたい。メッシュの欠損の存否を見たい。

図6 メーンメニュー下のショートカットアイコン群

 メーンメニューのすぐ下には,図6のように,ショートカットアイコン群が並ぶ。アイコン群16(Draw XYZ axes in world coordinates)をタップすると,XYZ軸が現れる。XYZはそれぞれRGB三原色の軸が使われており,右手座標系(デカルト座標系)になっているのがわかる。ただ,重力軸はZ軸の筈であるが,Y軸になっている。この点,注意が必要だ。
 Nos. 10〜14の五個のアイコンは,左から,Bounding Box(境界ボックス),Points(点群),Wireframe(立体の辺だけから成るような線の集合で表現されるもの),Vert(vertices 多面体の頂点),そしてFace(多面体の面)が並ぶ。objを読み込んだ際には,この5アイコンのうち,右端のFaceだけが選ばれた状態であり,図7のように見える。押されたFaceをタップして解除すると,全画像が見えなくなる。

 図8はFaceの上にワイアーフレームを表現したものである。右ペーンにもツールアイコン群が並ぶ。この部分でもより細かな設定が可能である。No. 14のFaceのアイコンをタップして解除すると,図9のようにワイアーフレームだけが見えるのであるが,余りに密度が高く,その欠損部を探すのは個々の場所を拡大しても,難しい。

 なお,MeshLabのmouse操作は特殊で,Meshlab_Tutorial_iitd.pdf p.8に掲載されている。右クリックは何故か使われていない。ぼくの環境では機能しないものも幾つかある。興味深いのは1の機能で感覚的に理解しやすい。

NAVIGATION IN MeshLAB

  1. Left mouse button + drag: rotate around trackball center
  2. Mouse wheel: move forward or backward
  3. Center mouse button + drag: pan
  4. Shift + mouse wheel: change camera field of view
  5. Double click on specific point: places that point at the trackball center
  6. Control + mouse wheel: moves near clipping plan
  7. Control + Shift + mouse wheel: moves far clipping plan
  8. Alt + Enter: enter full screen mode
  9. Control + Shift + left mouse button + drag: changes light direction (this
    only takes effect if there are normals)
図7  右手座標系
図8 面およびワイアーフレーム表示
図9 ワイアーフレームのみ

 それで,欠損部(ポリゴン境界やメッシュの欠損部)を探すのに,境界や穴の表示 によれば, Filters > Selection > Select Border である。その結果を次の図10に示す。境界は赤線で表示されており,段ボール三箱を置いている絨毯のトリミングの四角形の四辺に限定されており,メッシュの欠損は無いということになる。

図10 ポリゴン境界を示している

 次に神武天皇遙拝所碑の最新OBJを見てみよう。図11を見ると,点群plyでは頭は大きく欠損していたが,メッシュobjでは全く欠損が見られない。この図11は,Filters > Selection > Select Border ,を反映したものであるが,土台の切り取った部分にしか赤線は無い。

図11 神武天皇遙拝所碑の頭の部分と土台の境界

 最新のScaniverseで得られたメッシュOBJには欠損が全く無い,ということになるが。

以上,0:20, Feb. 3, 2023記。

5 MeshLabで欠損を探す2

 ところが,CloudCompareで Edit > Mesh > Measure volume,で,体積計算すると,consoleに,”The above volume might be invalid (mesh has holes),となっていて,改善が見られない。表面積の方はそういうエラーメッセージは出ない。両数値とも悪い数値では無いが。
 MeshLabでの,Filters > Selection > Select Border,を使ったチェックが役に立っていないのである。ワイアーフレーム表示をして明らかな穴を埋める方法については,後に実行したいと思うが,今のこの問題をどうするかで,である。
 穴埋め関係の情報は,MeshLab Simple Mesh Editing に整理されている。Close Holesに関連して,max size to be closedのデフォルトが30になっているが,このmax sizeの意味が理解できない。このサイトでは,
Close Small Holes Holes which are “small” with respect to the mesh size, possibly almost planar…
Simple filter: Remeshing, simplification and reconstruction->Close Holes
Parameters: max size to be closed (in terms of perimeter lenght)
とある。ここでmax sizeは穴の周囲長としている。が,現物をスキャンした者からすると,単位としてメートルを考えてしまう。段ボール箱などで穴が30mという最大値そのものに意味が無いので,実際に作業をしてみるしかない。

 そこで,まずは次のサイトを参考にした。MeshLab でメッシュの穴埋めを行なう
1 ツールバー右端の検索場で「close」を入力すると,検索結果に「Close Holes」が見え,それを選ぶと,図12のように,Close Holesのパネルが見えるので,Max size to be closed: 30などデフォールトのまま, Applyする。そうすると,図13のようなFilter Failureが現れる。ここには,filter requires edge manifoldeness,と出ている。

図12 Close Holes
図13 Filter Failure in Close Holes

2 逆引きMeshLab の,Filter (スキャンデータをきれいにする),には,穴埋め欄の説明に,
Filters > [Remeshing simplification and Reconstruction] > [Close Holoes]
Manifoldのエラーが出る場合は事前に、Filters > Cleaning and Repairing > Remove faces from Non Manifold Edges,などを実施,とある。図14のように,現在のMeshLabではより改良されている。
Filters > Cleaning and Repairing > Repair non Manifold Edges

図14 Repair non Manifold Eges
図15 Repair non Manifold Edges

 図15には,Repair non Manifold Edges,のパネルが現れている。選択肢が二つあるが,デフォルトのRemove Facesのまま,Apply。

3 図17右下のconsoleには,Repair non Manifold Edges,が成功したことが示されている。”Successfully removed 15 non-manifold faces”である。
 そして,再び,図16のように,Close Holesを実行したのであるが,図17右下のconsoleには,”Closed 12 holes and added 20 new faces”,とある。なお,Close Holesは,
Filters > Remeshing, Simplification and Reconstruction > Close Holes,で実行される。

図16 またClose Holes
図17 成功

4 とはいえ,実行結果を見ることはできない。またCloudCompareで体積と表面積を計算してみたい。
File > Save Project As…,で,3carton230126scaniverse_obj \ 3carton230126scaniverse_obj_1.mlp,で一応保存した(図18)。
 このファイルではCloudCompareで扱えないので,File > Export Mesh,を実行したが,File > Export Mesh As…としなかったので,ファイル名称変更のステップは無かった。ブラウザーで探したら,元ファイルと同じフォルダーには,新たに,mtlファイルが作成されていた(図19)。図19の右端には,このMTLファイルの作成日(時刻)があり,2023/02/06 17:46(作業時刻と一致),となっている。

図18 MeshLab形式で保存
図19 File > Export Mesh

5 CloudCompareで,これを開いてみた。図20のように,チェッキングリストを全部外した3Dクラウドが図20のものである。RGB情報は全く失われている。そういうものであることを,ここで認識することができた。メーン画面の右下隅のXYZ軸を見ると,MeshLabでの座標系も鉛直軸方向も変わっていない。
 segmentして,Edit > Mesh > Volume, Surfaceを実行した結果が,図21のConsoleの最下行から上の4行に現れている。何と相変わらず,体積について,might be invalid (mesh has holes)が現れている。
 V=0.1287㎥, S=1.4542㎡,であるが,身近な直方体の体積をiPhone 12 Pro+ LiDAR写真測量で求める の表4の実測値と比較すると,0.1287/0.1212 = 1.06,1.4542/1.4522 = 1.00,となっていて,正解と考えて良い。

図20 MeshLabでexportされたobj
図21 Edit > Mesh > Volume, Surface

 以上から,MeshLabでClose Holesを実行し,CloudCompareで表面積を求めるプロセスは,成功したと言えるだろう。

おわりに

 さらに,この後,明らかな欠損を埋めるプロセスをまとめれば,ぼくのMeshLab操作技術は向上することであろうが,一応,ここで終了したい。大きな欠損を埋めることはぼくには実は意味が無いことでもある。3Dプリンターを使う必要性もないし,カラー写真のようなRGBが自然に表現されている3Dイメージがぼくの求めるものであって,細々と触る必要性も無いのである。

 この結果に基づいて,大饗石のメッシュOBJを使って体積と面積を次に求める作業に入りたいと思うが,他のキンドル版出版の作業に入りたいと思っている。この体積計算に拘った切っ掛けは,大饗石の体積値が妥当かという問題意識からであった。

以上,Feb. 6, 2023記。