Open3D 실습

deutan·2026년 1월 4일
post-thumbnail

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 결과 확인

profile
Visual Computing and Learning

2개의 댓글

comment-user-thumbnail
2026년 1월 6일

토깽이

1개의 답글