Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import numpy as np | |
| from PIL import Image | |
| import trimesh | |
| import tempfile | |
| import rembg | |
| def remove_background(input_image): | |
| input_image = Image.fromarray(input_image) | |
| output = rembg.remove(input_image) | |
| return np.array(output) | |
| def create_3d_model(input_image, thickness=0.05, size=3): | |
| # Convert numpy array to PIL Image | |
| image = Image.fromarray(input_image) | |
| # Get image dimensions | |
| width, height = image.size | |
| aspect_ratio = width / height | |
| # Create front and back planes | |
| vertices = np.array([ | |
| [-size, -size/aspect_ratio, thickness/2], | |
| [size, -size/aspect_ratio, thickness/2], | |
| [size, size/aspect_ratio, thickness/2], | |
| [-size, size/aspect_ratio, thickness/2], | |
| [-size, -size/aspect_ratio, -thickness/2], | |
| [size, -size/aspect_ratio, -thickness/2], | |
| [size, size/aspect_ratio, -thickness/2], | |
| [-size, size/aspect_ratio, -thickness/2] | |
| ]) | |
| faces = np.array([ | |
| [0, 1, 2], [0, 2, 3], # front | |
| [4, 6, 5], [4, 7, 6], # back | |
| [0, 4, 1], [1, 4, 5], # bottom | |
| [2, 6, 3], [3, 6, 7], # top | |
| [0, 3, 4], [3, 7, 4], # left | |
| [1, 5, 2], [2, 5, 6] # right | |
| ]) | |
| # Create texture coordinates (front and back are now identical) | |
| uvs = np.array([ | |
| [0, 0], [1, 0], [1, 1], [0, 1], # front | |
| [0, 0], [1, 0], [1, 1], [0, 1], # back (not flipped) | |
| [0, 1], [1, 1], [1, 0], [0, 0], # other sides | |
| [0, 1], [1, 1], [1, 0], [0, 0], | |
| [0, 1], [1, 1], [1, 0], [0, 0], | |
| [0, 1], [1, 1], [1, 0], [0, 0] | |
| ]) | |
| # Create the mesh with transparent material | |
| mesh = trimesh.Trimesh( | |
| vertices=vertices, | |
| faces=faces, | |
| visual=trimesh.visual.TextureVisuals( | |
| uv=uvs, | |
| material=trimesh.visual.material.PBRMaterial( | |
| baseColorTexture=trimesh.visual.TextureVisuals(image=image).material.image, | |
| alphaMode='BLEND', | |
| doubleSided=True | |
| ) | |
| ) | |
| ) | |
| # Create a scene with our textured mesh | |
| scene = trimesh.Scene(mesh) | |
| scene.ambient = [0.95, 0.95, 0.95] | |
| # Export as GLB | |
| with tempfile.NamedTemporaryFile(delete=False, suffix='.glb') as temp_file: | |
| scene.export(temp_file.name, file_type='glb') | |
| return temp_file.name | |
| def process_and_create_3d(input_image, thickness, size): | |
| # Remove background | |
| processed_image = remove_background(input_image) | |
| # Create 3D model | |
| model_path = create_3d_model(processed_image, thickness, size) | |
| return processed_image, model_path | |
| # Define Gradio interface | |
| iface = gr.Interface( | |
| fn=process_and_create_3d, | |
| inputs=[ | |
| gr.Image(label="Input Image"), | |
| gr.Slider(minimum=0.001, maximum=0.2, step=0.001, value=0.01, label="Thickness"), | |
| gr.Slider(minimum=1, maximum=5, step=0.1, value=3, label="Size") | |
| ], | |
| outputs=[ | |
| gr.Image(label="Processed Image (Background Removed)"), | |
| gr.Model3D(label="3D Model (GLB)" ,height=640) | |
| ], | |
| title="Image to 3D Model Converter", | |
| description="Upload an image to remove its background and convert it to a transparent 3D model. The model will have identical front and back sides with the same image orientation." | |
| ) | |
| # Launch the interface | |
| iface.launch() |