You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python将Nifty(.nii)转成.obj文件用于Unity?

Solution for Converting NIfTI (.nii) Files to .obj with Python (for Unity)

Hey there! I totally get where you're coming from—getting the marching cubes output from scikit-image is half the battle, but saving that data to a usable .obj file for Unity can feel like a missing piece. Let's walk through a complete workflow that includes loading your NIfTI data, running marching cubes, writing a custom save function, and fixing those import issues you're stuck on.

Step 1: Set Up Dependencies & Load NIfTI Data

First, make sure you have the required libraries installed. Run this in your terminal if you haven't already:

pip install nibabel scikit-image numpy

Then load your .nii file using nibabel (the standard library for NIfTI handling):

import nibabel as nib
import numpy as np
from skimage.measure import marching_cubes

# Load your NIfTI file
nii_img = nib.load("your_input_file.nii")
nii_data = nii_img.get_fdata()

# Optional: Apply a threshold to isolate your target structure (adjust value as needed)
threshold = 0.5
nii_data = np.where(nii_data > threshold, nii_data, 0)

Step 2: Extract Mesh Data with Marching Cubes

Use scikit-image's marching_cubes to pull out vertices, faces, normals, and scalar values from your volume data:

# Run marching cubes (use your threshold value here)
vertices, faces, normals, values = marching_cubes(nii_data, level=threshold, allow_degenerate=False)

# Critical: Apply NIfTI affine to fix spatial orientation
# This ensures your mesh matches the real-world coordinates of the original scan
affine = nii_img.affine
vertices = nib.affines.apply_affine(affine, vertices)

Step 3: Custom .obj Saving Function

Since there's no built-in function for this, let's write a simple one that follows .obj format rules (Unity expects this exact structure):

def save_mesh_to_obj(filename, vertices, faces, normals):
    with open(filename, 'w') as obj_file:
        # Write vertices (format: v x y z)
        for v in vertices:
            obj_file.write(f"v {v[0]:.6f} {v[1]:.6f} {v[2]:.6f}\n")
        # Write normals (format: vn x y z)
        for n in normals:
            obj_file.write(f"vn {n[0]:.6f} {n[1]:.6f} {n[2]:.6f}\n")
        # Write faces (note: .obj uses 1-based indexing, so add 1 to each index)
        for face in faces:
            face_entries = ' '.join([f"{idx+1}//{idx+1}" for idx in face])
            obj_file.write(f"f {face_entries}\n")

# Save your mesh to an .obj file
save_mesh_to_obj("unity_ready_model.obj", vertices, faces, normals)

Troubleshooting Unity Import Issues

If you're hitting snags importing the .obj into Unity, here are the most common fixes:

  • 1-Based Indexing: .obj files require 1-based indices for vertices/normals—our function handles this by adding +1 to each face index. Double-check that your custom code didn't skip this step (it's a super common mistake!).
  • Coordinate System Mismatch: Unity uses a left-handed coordinate system, while NIfTI files typically use right-handed. Fix this by flipping an axis before saving:
    # Flip Z-axis to match Unity's space (adjust if needed for your scan)
    vertices[:, 2] = -vertices[:, 2]
    
  • Degenerate Faces: The allow_degenerate=False flag in marching_cubes prevents invalid faces, but if you still see errors, use Unity's built-in Mesh Cleanup tool (Window > Modeling > Mesh Cleanup) after importing.
  • File Encoding: Ensure your .obj is saved in UTF-8. Our function uses the default write mode which handles this, but if you run into issues, add encoding='utf-8' to the open() call.

Final Notes

This workflow will give you a clean, Unity-compatible .obj file. The key pieces are applying the NIfTI affine for accurate spatial positioning, following .obj format rules, and adjusting the coordinate system to match Unity's expectations.

内容的提问来源于stack exchange,提问作者Diego Orellana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:59:17