3D ์ค์บ, CT ์ด๋ฏธ์ง, Neural Radiance Field(NeRF), Signed Distance Function(SDF) ๋ฑ์์ ์ฌ์ฉ๋๋ 3D ๋ฐ์ดํฐ๋ ๋๋ถ๋ถ density field ํน์ scalar field๋ก ํํ๋๋ค. ์ด๋ฌํ volumetric data๋ ๊ฐ 3์ฐจ์ ์ขํ์ ์ด๋ค ๊ฐ(์: ๋ฐ๋, ๊ฑฐ๋ฆฌ ๋ฑ)์ด ํ ๋น๋ ํํ์ผ ๋ฟ์ด๋ฉฐ, ๊ฒ๋ณด๊ธฐ์๋ ๋จ์ํ ์ซ์๋ค์ ์งํฉ์ ๋ถ๊ณผํ๋ค.
ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ 3D ๋ฐ์ดํฐ๋ฅผ ์ง๊ด์ ์ผ๋ก ์ดํดํ๊ณ ์๊ฐํํ๊ธฐ ์ํด์๋, ์ด ๊ฐ๋ค์ ๋ถํฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด๋๊ฐ ๋ฌผ์ฒด์ด๊ณ ์ด๋๊ฐ ๋ฐฐ๊ฒฝ์ธ์ง, ์ฆ surface๊ฐ ์ด๋์ ์กด์ฌํ๋์ง๋ฅผ ์์์ผ ํ๋ค. ์ด์ฒ๋ผ ์ฐ์์ ์ธ ๊ฐ์ ํ๋์์ ์๋ฏธ ์๋ 3D mesh์ ์ถ์ถํ๋ ์์ ์ด ํ์ํ๋ฉฐ, ์ด๋ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๋ํ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ด ๋ฐ๋ก Marching Cubes์ด๋ค.
๐ Marching Cubes๋?
Marching Cubes๋ 1987๋ ์ ๋ฐํ๋ ๊ณ ์ ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก, 3์ฐจ์ scalar field์์ isosurface๋ฅผ ์ถ์ถํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. ์ค์นผ๋ผ ํ๋๋, 3D ๊ณต๊ฐ์ ๊ฐ ์์น์ ์ค์ ๊ฐ(์: ๋ฐ๋, ๊ฑฐ๋ฆฌ ๋ฑ)์ด ์ ์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์๋ฏธํ๋ค. ๋ํ์ ์ธ ์๋ก๋ CT, MRI ๊ฐ์ ์๋ฃ ์์, 3D ์ค์บ, NeRF๋ SDF์์ ์์ฑ๋๋ density field ๋ฑ์ด ์๋ค.
Marching Cubes๋ ์ด๋ฌํ ์ค์นผ๋ผ ํ๋์์ ํน์ ๊ฐ(์๊ณ๊ฐ ๋๋ isovalue)์ ๊ธฐ์ค์ผ๋ก "ํ๋ฉด"์ด ๋ ์์น๋ฅผ ์ฐพ์๋ด์ด, ์ด๋ฅผ mesh ํํ๋ก ๊ทผ์ฌํ๋ ๋ฐฉ์์ด๋ค. ์ถ์ถ๋ mesh๋ ์๊ฐํ๋ 3D ๋ชจ๋ธ๋ง, ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์ ๋ฑ ๋ค์ํ ์์ฉ์ ํ์ฉ๋ ์ ์๋ค.
๐ ํต์ฌ ์์ด๋์ด
Marching Cubes๋ 3์ฐจ์ ๊ณต๊ฐ์ ์์ ๊ฒฉ์ ๋จ์๋ก ๋๋ ๋ค, ๊ฐ ์์ ์ ์ก๋ฉด์ฒด(cube) ์์์ ํ๋ฉด์ด ํต๊ณผํ ์์น๋ฅผ ๊ณ์ฐํ๋ค.
- ๊ฐ cube๋ 8๊ฐ์ ๊ผญ์ง์ ์ ๊ฐ์ง๋ฉฐ, ๊ฐ ๊ผญ์ง์ ์๋ ์ค์นผ๋ผ ๊ฐ์ด ์กด์ฌํ๋ค.
- ์ด ๊ฐ๋ค์ด ๊ธฐ์ค์ด ๋๋ isovalue๋ณด๋ค ํฐ์ง ์์์ง๋ฅผ ํ๋จํ์ฌ, ํ๋ฉด์ด ๊ทธ cube ๋ด๋ถ๋ฅผ ํต๊ณผํ๋์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ค.
- ์ด 8๊ฐ์ ๊ผญ์ง์ ์ 2๊ฐ์ ์ํ(inside ๋๋ outside)๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฏ๋ก, cube๋ง๋ค ์ด 256๊ฐ์ง ์กฐํฉ์ด ๊ฐ๋ฅํ๋ค.
- ์ด 256๊ฐ์ง ์กฐํฉ์ ๋ํด ์ฌ์ ์ ์ ์๋ mesh ํจํด ํ ์ด๋ธ(look-up table)์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉด์ ๊ทผ์ฌํ ์ ์๋ค.
- ํ๋ฉด์ ๊ตฌ์ฑํ๋ vertex๋ค์ cube์ edge ์์์ interpolation์ ํตํด ์์น๊ฐ ๊ณ์ฐ๋๋ค.
์ฝ๊ฒ ๋งํด, "์ด ๋ถ๋ถ์ด ๋ฌผ์ฒด ๋ด๋ถ์ธ์ง ์ธ๋ถ์ธ์ง"๋ฅผ ํ์ ํ๊ณ , ๊ทธ ๊ฒฝ๊ณ๋ฉด์ ๋ฐ๋ผ ์ผ๊ฐํ์ผ๋ก ์ด์ด์ฃผ๋ ๋ฐฉ์์ด๋ผ ๋ณผ ์ ์๋ค. ๋ํ density volume์ ํ๋ธ๋ก ๋๋์ด 3D mesh๋ฅผ ๊ทผ์ฌํ๊ธฐ ๋๋ฌธ์ ์ผ๋ง๋ ์ด์ดํ๊ฒ ํ๋ธ๋ฅผ ๋๋๋๋์ ๋ฐ๋ผ ์ผ๋ง๋ ์ ๋ฐํ mesh๋ฅผ ์ป์ ์ ์๋์ง๊ฐ ๋๋๊ฒ ๋๋ค. ๋น์ฐํ voxel์ด ๋ ์๊ณ ๋ง์์๋ก ๋ ์ธ๋ฐํ mesh๊ฐ ์์ฑ๋๋ค.
marching cubes ์๊ณ ๋ฆฌ์ฆ์ 2D ๋๋ฉ์ธ์์ ์๊ฐํํด๋ณด๋ฉด ์์ ๊ฐ๋ค.
๐ ์๊ณ ๋ฆฌ์ฆ ๊ณผ์ ์ ๋ฆฌ
- 3D ๋ณผ๋ฅจ ๋ฐ์ดํฐ๋ฅผ ๊ท ์ผํ ๊ฒฉ์(grid)๋ก ๋๋
- ๊ฐ ๊ฒฉ์ ์ (cube)์ ๋ํด 8๊ฐ์ ๊ผญ์ง์ ๊ฐ์ ํ์ธ
- ๊ฐ ๊ผญ์ง์ ์ด isovalue๋ณด๋ค ํฐ์ง ์์์ง๋ฅผ ์ด์ง ๊ฐ์ผ๋ก ๋ณํ
- ์: density > threshold → 1, ์๋๋ฉด 0
- ์ด์ง ๊ฐ์ ์กฐํฉํ์ฌ 8๋นํธ ์ฝ๋ (0~255)๋ฅผ ๋ง๋ฆ
- ์ด ๊ฐ์ ํด๋น cube์ ํ๋ฉด ํํ๋ฅผ ๊ฒฐ์ ํ๋ ํค๊ฐ ๋จ
- ์ฌ์ ์ ์๋ look-up table์ ์ฐธ์กฐํ์ฌ ์ผ๊ฐํ ๊ตฌ์ฑ ๋ฐฉ์์ ๊ฒฐ์
- cube์ edge ์์์ ํ๋ฉด ์ ์ ์์น๋ฅผ ๋ณด๊ฐํ์ฌ ๊ณ์ฐ
- ์ผ๊ฐํ๋ค์ ์ ์ฒด ๊ณต๊ฐ์ ๋ํด ์ด์ด๋ถ์ฌ ํ๋์ ์ฐ์๋ mesh๋ฅผ ๊ตฌ์ฑ
์ด๋ฌํ ๊ณผ์ ์ 3์ฐจ์ ๊ณต๊ฐ์ ๋ชจ๋ ๊ฒฉ์์ ๋ฐ๋ณต ์ ์ฉํ๋ฉด, ์ฃผ์ด์ง ๋ฐ๋ ํ๋๋ก๋ถํฐ ์ฐ์์ ์ธ 3D ํ๋ฉด์ ๊ตฌ์ฑํ ์ ์๋ค. ๊ฒฐ๊ณผ๋ ์ค์ ๋ก ์๊ฐํํ๊ฑฐ๋, .obj, .ply ๋ฑ์ผ๋ก ์ ์ฅํด ๋ค์ํ ๋ถ์ผ์์ ํ์ฉํ ์ ์๋ค.
๐ ์์
import numpy as np
import matplotlib.pyplot as plt
from skimage import measure
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import trimesh
# Step 1: NeRF-style volumetric density (Gaussian blob)
def generate_density(shape=(64, 64, 64), center=(32, 32, 32), radius=15):
Z, Y, X = np.indices(shape)
dist = np.sqrt((X - center[0])**2 + (Y - center[1])**2 + (Z - center[2])**2)
volume = np.exp(-(dist**2) / (2 * radius**2)) # Gaussian density
return volume
volume = generate_density()
# Step 2: Threshold for isosurface
iso_level = 0.1
# Step 3: Marching Cubes mesh extraction
verts, faces, normals, values = measure.marching_cubes(volume, level=iso_level)
# Step 4a: Voxel-based visualization (scatter plot of high-density points)
fig = plt.figure(figsize=(14, 6))
ax1 = fig.add_subplot(121, projection='3d')
threshold = 0.1
points = np.argwhere(volume > threshold)
ax1.scatter(points[:, 0], points[:, 1], points[:, 2], c='red', s=1, alpha=0.3)
ax1.set_title('Volumetric Density (Voxel View)')
ax1.set_xlim(0, 64)
ax1.set_ylim(0, 64)
ax1.set_zlim(0, 64)
# Step 4b: Mesh visualization using Marching Cubes
ax2 = fig.add_subplot(122, projection='3d')
mesh = Poly3DCollection(verts[faces], alpha=0.6)
mesh.set_facecolor([0.3, 0.7, 1])
ax2.add_collection3d(mesh)
ax2.set_title('Marching Cubes Mesh')
ax2.set_xlim(0, 64)
ax2.set_ylim(0, 64)
ax2.set_zlim(0, 64)
plt.tight_layout()
plt.show()
mesh = trimesh.Trimesh(vertices=verts, faces=faces)
mesh.export('output_mesh.obj')
mesh.export('output_mesh.ply')
์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ์์ density volume์ผ๋ก ๋ถํฐ marching cubes ์๊ณ ๋ฆฌ์ฆ์ผ๋ก 3D ๊ตฌ์ฒด mesh๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ์๊ฐํํ์ฌ ํ์ธ ํ ์ ์๋ค. ๋ํ obj ๋๋ ply ํฌ๋งท์ผ๋ก ์ ์ฅํ์ฌ ํ์ธํ ์๋ ์๋ค.