Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,54 @@ python -m visualize.render_mesh --input_path /path/to/mp4/stick/figure/file
1. A more straightforward way is using the mesh data itself. All meshes have the same topology (SMPL), so you just need to keyframe vertex locations.
Since the OBJs are not preserving vertices order, we also save this data to the `sample##_rep##_smpl_params.npy` file for your convenience.


## Convert SMPL human mesh into image

<summary><b>Create Images from .obj Files</b></summary>

### Generate images from .obj files

```shell
python pymesh.py /path/to/obj/files /path/to/output/images
```

**This script outputs:**
* `frame##.png` - Rendered images of the mesh from `.obj` files.

**Notes:**
* Ensure the `.obj` files are located in the specified input directory.
* The output directory will contain the rendered images for each frame.
* The `.obj` files can be integrated into Blender/Maya/3DS-MAX and rendered using them.

**Customizing Viewing Angles:**
* To see the right side of the body, change the code to:
```python
ax.view_init(elev=0, azim=90)
```
![example](assets/human_mesh_right.png)


* To see the back side of the body, change the code to:
```python
ax.view_init(elev=-90, azim=90)
```
![example](assets/human_mesh_back.png)

* To see the front side of the body, change the code to:
```python
ax.view_init(elev=90, azim=270)
```
![example](assets/human_mesh_front.png)

**Important:**
* The `matplotlib` backend is set to `Agg` to avoid conflicts with GUI-based backends.
* Ensure you have the required dependencies installed:
```shell
pip install pymeshlab trimesh matplotlib tqdm imageio
```



## Motion Editing

* This feature is available for text-to-motion datasets (HumanML3D and KIT).
Expand Down
Binary file added assets/human_mesh_back.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/human_mesh_front.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/human_mesh_right.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 82 additions & 0 deletions utils/pymesh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#python
# call program : /home/blinkdrive/Documents/Projects/Summer2024/motion-diffusion-model/utils/pymesh.py

# Input object[SMPL] : /home/blinkdrive/Documents/Projects/Summer2024/motion-diffusion-model/save/humanml_trans_enc_512/samples_humanml_trans_enc_512_000200000_seed10_example_text_prompts/sample03_rep00_obj/

#Output folder : /home/blinkdrive/Documents/Projects/Summer2024/motion-diffusion-model/save/images/



import pymeshlab
import trimesh
import matplotlib
matplotlib.use('Agg') # Use the Agg backend to avoid Qt conflicts
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import sys
import os
import imageio.v2 as imageio # Updated to handle deprecation warning
from tqdm import tqdm

def rotate_and_save_frame(obj_file_path, output_image_path):
# Create a new MeshSet
ms = pymeshlab.MeshSet()

# Load the .obj file into the MeshSet
ms.load_new_mesh(obj_file_path)

# Extract the mesh
mesh = ms.current_mesh()

# Convert to Trimesh for visualization
vertices = mesh.vertex_matrix()
faces = mesh.face_matrix()

tri_mesh = trimesh.Trimesh(vertices=vertices, faces=faces)

# Plot the mesh using Matplotlib
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# Rotate the view to face forward with custom angles for front view
ax.view_init(elev=0, azim=0) # Adjust these values for a custom view angle

ax.plot_trisurf(tri_mesh.vertices[:, 0], tri_mesh.vertices[:, 1], tri_mesh.vertices[:, 2], triangles=tri_mesh.faces, cmap='viridis', lw=1)
plt.axis('off')

# Save the plot as an image file
plt.savefig(output_image_path, bbox_inches='tight', pad_inches=0)
plt.close()

def create_images_from_folder(input_folder, output_image_folder):
obj_files = sorted([file_name for file_name in os.listdir(input_folder) if file_name.endswith('.obj')])
total_files = len(obj_files)

# Create the output folder if it does not exist
if not os.path.exists(output_image_folder):
os.makedirs(output_image_folder)

for idx, file_name in enumerate(tqdm(obj_files, desc="Processing files", unit="file")):
obj_file_path = os.path.join(input_folder, file_name)
output_image_path = os.path.join(output_image_folder, f'frame{idx}.png')
rotate_and_save_frame(obj_file_path, output_image_path)

print(f"Images saved to {output_image_folder}")

def main():
if len(sys.argv) != 3:
print("Usage: python pymesh.py <input_folder> <output_image_folder>")
sys.exit(1)

input_folder = sys.argv[1]
output_image_folder = sys.argv[2]

if not os.path.isdir(input_folder):
print(f"Error: The folder '{input_folder}' does not exist.")
sys.exit(1)

create_images_from_folder(input_folder, output_image_folder)

if __name__ == "__main__":
main()