「instantNeRFで遊ぶ Advent Calendar 2022」の22日目です。
今日はdepth maskを使うためにRealityCaptureのdepth mapを変換する方法を検討しました。
業務外の個人的な検討活動です。
depth mask
depth mapの形式はUint16のようです。
もし問題があれば、コードの中、特にnerf_loader.cuのenable_depth_loadingのところを見ることをお勧めします。
深度マップはUINT16のpngファイルに量子化される必要があり、量子化スケールはjsonファイルの "integer_depth_scale "で設定される必要があります。このキーがjsonにない場合、depth_mapsは読み込まれません(現在)。
デフォルトでは、depth_supervision_lambdaは0に設定されているので、0 < に変更する必要があることに注意してください。
(DeepLで翻訳しました https://www.deepl.com/translator)
Reality Captureのdepth map
MESH MODEL / ExportのDepth and Maskを使ってdepth mapを出力できますが、形式がFloat32bitしか選べないようです。またGimpなどで開いてみると背景が真っ黒、前景が真っ白になっていました。
左が入力画像、右が対応する画像の赤枠内のdepth mapです。
ただし背景部分はRealityCapture上で削除しています。
float32 → 上限設定+UINT16変換
openEXR形式のdepth mapを読み込み、距離が無限大扱いになっている数値を変更した上でuint16に変換してpng形式で保存しました。
#https://forum.opencv.org/t/imread-openexr-file/10268/2
import os
import glob
os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"
import cv2 as cv
import numpy as np
path1 = "./depth/"
fileList = glob.glob(path1+"*")
print(fileList)
for fileName in fileList:
exr_neg = cv.imread(fileName, cv.IMREAD_UNCHANGED)
#https://note.nkmk.me/python-os-basename-dirname-split-splitext/
basename_without_ext = os.path.splitext(os.path.basename(fileName))[0]
#https://note.nkmk.me/python-str-remove-strip/
basename_without_ext = basename_without_ext.replace('.jpg.','_')
dstFileName = path1 + basename_without_ext + "_u16.png"
print(fileName, basename_without_ext)
cv.namedWindow('exr_neg',
cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO | cv.WINDOW_GUI_EXPANDED)
exr_neg = exr_neg.astype(np.float16)
# https://note.nkmk.me/python-numpy-where/
exr_neg = np.where(exr_neg > 65535.0, 65535.0, exr_neg)
max = exr_neg.max()
min = exr_neg.min()
print('#1 exr_neg: resolution x {}, y {}; min {} | max {}'.format(exr_neg.shape[0], exr_neg.shape[1], min, max))
exr_neg_minmax = exr_neg.astype('uint16')
print('#2 exr_neg: resolution x {}, y {}; min {} | max {}; type:{}'.format(exr_neg_minmax.shape[0], exr_neg_minmax.shape[1], exr_neg_minmax.min(), exr_neg_minmax.max(), exr_neg_minmax.dtype))
cv.imshow('exr_neg', exr_neg_minmax)
cv.waitKey(0)
cv.imwrite(dstFileName, exr_neg_minmax)
cv.destroyAllWindows()
変換画像を途中で確認した状態です。デプスが見えるようになりました。
transform.json
さきほどのgithubの書き込みのように記述を追加しました。
testbed.exe
instantNeRFを実行しました。
depth maskあり
NeRF training options / Depth supervision strengthの調整が有効になり、洋服も消え気味ですが、背景部分の多くを消すことができました。
Depth supervision strengthの感度が高すぎるので、おそらくdepth mapの最大値やスケールの大きさが適正ではないのかもしれません。