LoginSignup
0
0

More than 1 year has passed since last update.

【Python】3DモデルのIoUを計算した

Posted at

概要

3D分野の研究では、生成したモデルの精度を評価するために、ターゲットオブジェクトとのIoUを測ることがあります。
今回はボクセル表現の3次元モデルにおけるIoUをPythonで実装しました。

IoUとは

IoUはIntersection over Unionの事で、「2つの物体の領域がどれだけ重なっているか」を評価する指標です。
2D画像では物体検出などに用いられます。

例えば、物体Aと物体BのIoUを測る際は以下のように求めることができます。

IoU(A, B) = \frac{A \;\cap \; B}{A \; \cup \; B}

したがって、物体のAND領域をOR領域で割ることで、どれだけ重なっているかを求めることができるのです。

では3DモデルにおけるIoUとは、どのように求めるのでしょうか?
最もシンプルな方法は、3Dモデルをボクセル表現に変換し、その重なりを調べる事です。

ボクセル表現とは、2D画像を構成するピクセルの3次元版にあたります。この表現を用いれば、単純なAND, OR領域の算出でIoU計算ができます。

Pythonでの実装

まずはボクセル表現の3Dモデルを用意します。
もし3Dモデルがボクセル表現以外(メッシュや点群)の場合、Pythonの3D操作などで用いられるライブラリを用いる方法があります。

例)

もし上記のライブラリでボクセル表現を取得した場合は、そこからnumpy配列を取得しましょう。
…といいつつ、ここら辺のライブラリの仕様が理解しきれていないため、具体的な方法はわかっていません。おそらくライブラリ内のget系関数やプロパティを活用すれば取得できるはず。

以下は実装になります。

def calculate_volume_IoU(preds, gt, thresh=0.4):
	"""3次元IoU評価指標

	Args:
		preds (np.array): 推論ボクセル
		gt (np,array): GTボクセル
		thresh (float, optional): ボクセルの閾値. Defaults to 0.4.

	Returns:
		float: IoU値
	"""
    # 推論numpy配列の値が0,1(True, False)でない場合の処理
	preds_occupy = preds >= thresh
	# ボリュームの積集合を計算
	intersection = np.logical_and(preds_occupy, gt[0, :, :, :, 0])
	# 2つのボリュームの和集合を計算
	union = np.logical_or(preds_occupy, gt[0, :, :, :, 0])
	# IoU計算
	volume_IoU = np.sum(intersection) / np.sum(union)
	return volume_IoU

まとめ

3D表現の変換まわりについて分かったことがあれば、別途まとめたいです。

参考サイト

0
0
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
0
0