Spaces:
Runtime error
Runtime error
File size: 4,557 Bytes
4e31b1a aaa6458 829dfd4 aaa6458 8505235 b33bab2 8505235 81914fc aaa6458 1087492 8505235 b33bab2 8505235 829dfd4 8505235 388cf5c 8505235 aaa6458 8505235 aaa6458 829dfd4 aaa6458 829dfd4 8505235 829dfd4 8505235 829dfd4 8505235 b33bab2 8505235 829dfd4 8505235 829dfd4 b33bab2 829dfd4 8505235 aaa6458 8505235 06be9c8 8505235 aaa6458 06be9c8 829dfd4 388cf5c 8505235 388cf5c 829dfd4 8505235 829dfd4 aaa6458 829dfd4 388cf5c aaa6458 8505235 aaa6458 829dfd4 06be9c8 aaa6458 8505235 06be9c8 aaa6458 1087492 aaa6458 48056a7 aaa6458 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
import os
import torch
import gradio as gr
import numpy as np
from PIL import Image
import tempfile
from skimage import measure
import trimesh
import torch.nn.functional as F
import torchvision.transforms as transforms
# Check if CUDA is available, otherwise use CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
# Define a simple neural network to extract depth from images
class SimpleDepthNet(torch.nn.Module):
def __init__(self):
super(SimpleDepthNet, self).__init__()
self.conv1 = torch.nn.Conv2d(3, 32, kernel_size=3, padding=1)
self.conv2 = torch.nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.conv3 = torch.nn.Conv2d(64, 128, kernel_size=3, padding=1)
self.conv4 = torch.nn.Conv2d(128, 1, kernel_size=3, padding=1)
self.pool = torch.nn.MaxPool2d(2, 2)
self.upsample = torch.nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
def forward(self, x):
# Encoder
x = F.relu(self.conv1(x))
x = self.pool(x)
x = F.relu(self.conv2(x))
x = self.pool(x)
# Decoder
x = self.upsample(x)
x = F.relu(self.conv3(x))
x = self.upsample(x)
x = torch.sigmoid(self.conv4(x))
return x
# Initialize the model
model = SimpleDepthNet().to(device)
# Define transformation for input images
transform = transforms.Compose([
transforms.Resize((256, 256)),
transforms.ToTensor(),
])
def image_to_3d(image):
"""
Convert a single image to a 3D model using a simple depth extraction approach
"""
if image is None:
return None, "No image provided"
try:
# Preprocess image
img_tensor = transform(image).unsqueeze(0).to(device)
# Generate depth map
with torch.no_grad():
depth = model(img_tensor)[0, 0].cpu().numpy()
# Convert depth map to 3D points
h, w = depth.shape
y, x = np.meshgrid(np.arange(h), np.arange(w), indexing='ij')
# Normalize coordinates
x = (x - w/2) / max(w, h)
y = (y - h/2) / max(w, h)
z = depth - 0.5 # Center around zero
# Create point cloud
points = np.stack([x.flatten(), y.flatten(), z.flatten()], axis=1)
# Get colors from original image
img_np = np.array(image.resize((w, h))) / 255.0
colors = img_np.reshape(-1, 3)
# Create a mesh from the point cloud (using marching cubes on the depth map)
verts, faces, _, _ = measure.marching_cubes(depth, 0.5)
mesh = trimesh.Trimesh(vertices=verts, faces=faces)
# Save as OBJ
with tempfile.NamedTemporaryFile(suffix='.obj', delete=False) as obj_file:
obj_path = obj_file.name
mesh.export(obj_path)
# Also save as PLY for better compatibility with Unity
with tempfile.NamedTemporaryFile(suffix='.ply', delete=False) as ply_file:
ply_path = ply_file.name
mesh.export(ply_path)
return [obj_path, ply_path], "3D model generated successfully!"
except Exception as e:
return None, f"Error: {str(e)}"
def process_image(image):
try:
if image is None:
return None, None, "Please upload an image first."
results, message = image_to_3d(image)
if results:
return results[0], results[1], message
else:
return None, None, message
except Exception as e:
return None, None, f"Error: {str(e)}"
# Create Gradio interface
with gr.Blocks(title="Simple Image to 3D Converter") as demo:
gr.Markdown("# Simple Image to 3D Converter")
gr.Markdown("Upload an image to convert it to a simple 3D model that you can use in Unity or other engines.")
with gr.Row():
with gr.Column(scale=1):
input_image = gr.Image(type="pil", label="Input Image")
submit_btn = gr.Button("Convert to 3D")
with gr.Column(scale=1):
obj_file = gr.File(label="OBJ File (for editing)")
ply_file = gr.File(label="PLY File (for Unity)")
output_message = gr.Textbox(label="Output Message")
submit_btn.click(
fn=process_image,
inputs=[input_image],
outputs=[obj_file, ply_file, output_message]
)
# Launch the app
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860) |