ねののお庭。

かりかりもふもふ。

【Python】trimeshでmeshから色付きの点(群)をサンプリングできるようになりました。

動機

自分の研究では、しばしば3d meshをコードからこねくり回していました。操作対象は深層学習の学習用データだったので、数が多く、とてもGUIでチマチマやれる量ではなかったのです。

で、こんな需要が私にはありました。

「テクスチャ付きの3d meshから色付きの点(群)を一様サンプリングしたい...!」

この需要を簡単に満たしてくれるものはあるのでしょうか? 答えは、まともに使えるものは無い、です。(*独自調べ)

もちろん、世の中の人も同じ操作をしたいと思う事があるため、ネットの海を漁るとそれらしいコードが出てくるには出てくるんですが、正直想定している使い方やフォーマットなどが極めて限定的な上に、meshの状態(エッジの接続状態等)によってはコケるなど、ぶっちゃけ使い物にならないものばかりでした。悲しい。

そんなわけで結局、自前で実装して研究には使っていました。

trimeshにプルリク

自前で実装したの使ってたんですが、今回それをベースにtrimeshにプルリク投げました。 プルリクは無事マージされ、v3.10.8 から使えるようになったので、紹介したいと思います。めっちゃ簡単に使えます。

github.com

その前にtrimeshってなんじゃらほい、というと、pythonで3D mesh, point cloudを扱う際のデファクトスタンダードとなっているライブラリです。便利関数がたくさん生えていて良い、おすすめ。

github.com

使い方

以下が簡単な使い方。 ./input/mesh.objの表面から100000点、座標とその色を同時にサンプリングして、それを点群として.plyを吐き出すコード。 めちゃ簡単。

import trimesh
from trimesh.sample import sample_surface
import numpy as np


mesh = trimesh.load("./input/mesh.obj")

samples, _, colors = sample_surface(mesh, 100000, sample_color=True)

pcd = trimesh.points.PointCloud(samples, colors.astype(np.uint8))
pcd.export("./out/pcd.ply")

sample_surfaceという関数自体は前からあったのですが、これはmeshから一様に点をサンプリングするだけでした。なんですが、今回のPRでsample_color=Trueという引数を渡すと点だけでなく、テクスチャから色をサンプリングするようになりました。

ちなみに、もともとのsample_surfaceがかなりイケている実装をしているため、読んでみると面白いかも。

まとめ

trimesh v3.10.8 以降では簡単にテクスチャ付きのmeshから色付きの点をサンプリングできるようになりました。 インストールや使い方など非常に簡単な上に、めんどくさい制限も特にないのでおすすめです。