
How to get started with Image to 3D
System
OS: Ubuntu 24.04
GPU: RTX 4060
Python: 3.12.3
Etc. uv, open3D, numpy, matplotlib, 3D Viewer(MeshLab)
uv venv: 가상환경 생성
source .venv/bin/activate : 가상환경 실행
uv init : 현재 프로젝트를 uv 프로젝트로 초기화
uv add open3d numpy matplotlib : 필요 라이브러리 구성
import open3d as o3d
import numpy as np
import os
def main():
print("--- Phase 1: 3D Data Handling Practice ---")
# 1. 샘플 데이터 로드 (Stanford Bunny)
print("[1] Loading sample dataset...")
dataset = o3d.data.BunnyMesh()
mesh = o3d.io.read_triangle_mesh(dataset.path)
# 메시를 포인트 클라우드로 변환 (실습을 위해 10,000개의 점 추출)
pcd = mesh.sample_points_uniformly(number_of_points=10000)
# 2. 3D Literacy: 수치 데이터 확인 (터미널 출력)
# 데이터의 경계(Bounding Box)를 확인하여 스케일(단위) 파악
min_bound = pcd.get_min_bound()
max_bound = pcd.get_max_bound()
print(f" - Min Bound (X, Y, Z): {min_bound}")
print(f" - Max Bound (X, Y, Z): {max_bound}")
print(f" - Center: {pcd.get_center()}")
# 3. 데이터 가공: 법선(Normals) 추정 및 아웃라이어 제거
print("[2] Processing Point Cloud...")
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
# 통계적 방법으로 노이즈(Outlier) 제거
cl, ind = pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)
pcd_cleaned = pcd.select_by_index(ind)
# 4. 카메라 프러스텀(Frustum) 시각화 데이터 생성
print("[3] Creating Camera Frustum...")
# 원점 근처에 카메라를 배치 (약간 뒤로 뺌)
intrinsic = np.array([[500, 0, 320], [0, 500, 240], [0, 0, 1]])
extrinsic = np.array([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, -0.5], # Z축 방향으로 -0.5 이동
[0, 0, 0, 1]])
frustum = o3d.geometry.LineSet.create_camera_visualization(
view_width_px=640, view_height_px=480,
intrinsic=intrinsic, extrinsic=extrinsic)
frustum.paint_uniform_color([1, 0, 0]) # 빨간색 프러스텀
# 5. 결과 저장
print("[4] Saving results to files...")
# 결과 폴더 생성
if not os.path.exists("outputs"):
os.makedirs("outputs")
# 포인트 클라우드 저장
o3d.io.write_point_cloud("outputs/cleaned_bunny.ply", pcd_cleaned)
# 카메라 프러스텀 저장 (LineSet이므로 .ply로 저장 가능)
o3d.io.write_line_set("outputs/camera_frustum.ply", frustum)
# 좌표축 생성 및 저장
axes = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.1)
o3d.io.write_triangle_mesh("outputs/axes.obj", axes)
print("--- Done! Check the 'outputs' folder. ---")
print("Files created: outputs/cleaned_bunny.ply, outputs/camera_frustum.ply, outputs/axes.obj")
if __name__ == "__main__":
main()
MeshLab으로 cleaned bunny, axis 및 camera frustum 결과 확인

토깽이