Prashanthsrn's picture
Update app.py
4c41f2c verified
import gradio as gr
import cv2
import mediapipe as mp
import numpy as np
import time
from pathlib import Path
import tempfile
import os
from face_reconstruction_main import FaceMeshDetector
import plotly.graph_objects as go
import json
# Initialize the detector
detector = FaceMeshDetector()
def process_frame(frame):
"""Process a single frame and return the image with face mesh overlay"""
if frame is None:
return None
img, faces = detector.detect_faces(frame)
return img, faces
def create_3d_plot(vertices):
"""Create a 3D plotly figure from vertices"""
x, y, z = zip(*vertices)
fig = go.Figure(data=[go.Scatter3d(
x=x, y=y, z=z,
mode='markers',
marker=dict(
size=2,
color=z,
colorscale='Viridis',
)
)])
fig.update_layout(
scene=dict(
xaxis_title='X',
yaxis_title='Y',
zaxis_title='Z',
aspectmode='cube'
),
margin=dict(l=0, r=0, b=0, t=0),
showlegend=False
)
return fig
def save_obj_and_display(frame):
"""Save frame as OBJ and return both file path and 3D visualization"""
try:
if frame is None:
return None, None, "No frame provided"
img, faces = process_frame(frame)
if not faces:
return None, None, "No face detected in the frame"
# Scale vertices
vertices = np.array(faces[0]) * 150
# Create temporary directory if it doesn't exist
temp_dir = Path('temp')
temp_dir.mkdir(exist_ok=True)
# Generate timestamp
timestamp = time.strftime("%Y%m%d-%H%M%S")
filename = f"face_mesh_{timestamp}"
# Save OBJ file
obj_path = temp_dir / f"{filename}.obj"
success = detector.save_obj_file(vertices, filename)
if not success:
return None, None, "Failed to save OBJ file"
# Create 3D visualization
fig = create_3d_plot(vertices)
return str(obj_path), fig, "Model generated successfully"
except Exception as e:
return None, None, f"Error: {str(e)}"
def cleanup_old_files():
"""Remove files older than 1 hour"""
temp_dir = Path('temp')
if temp_dir.exists():
current_time = time.time()
for file in temp_dir.glob('*.obj'):
if current_time - file.stat().st_mtime > 3600: # 1 hour
file.unlink()
def create_interface():
"""Create the Gradio interface"""
with gr.Blocks() as interface:
gr.Markdown("""
# 3D Face Reconstruction
Upload an image or use your webcam to generate a 3D face model.
Instructions:
1. Upload an image or use the webcam
2. Click 'Generate 3D Model'
3. View the 3D model in the interactive viewer
4. Download the OBJ file for use in 3D software
""")
with gr.Row():
with gr.Column():
# Input methods - using webcam and image input
with gr.Tab("Webcam"):
input_webcam = gr.Image(
label="Webcam Input",
type="numpy",
sources="webcam"
)
with gr.Tab("Upload"):
input_image = gr.Image(
label="Upload Image",
type="numpy"
)
generate_button = gr.Button("Generate 3D Model")
with gr.Column():
# Output displays
obj_file = gr.File(label="Download OBJ File")
plot_3d = gr.Plot(label="3D Preview")
status_text = gr.Textbox(label="Status")
# Set up event handlers for both webcam and uploaded image
generate_button.click(
fn=save_obj_and_display,
inputs=[input_webcam],
outputs=[obj_file, plot_3d, status_text]
)
generate_button.click(
fn=save_obj_and_display,
inputs=[input_image],
outputs=[obj_file, plot_3d, status_text]
)
# Example section
gr.Markdown("""
## Tips for Best Results
- Ensure good lighting
- Face the camera directly
- Keep a neutral expression
- Avoid extreme head rotations
- Stay within arm's length of the camera
""")
# Cleanup old files periodically
cleanup_old_files()
return interface
# Create and launch the interface
interface = create_interface()
# Launch locally for testing
if __name__ == "__main__":
interface.launch()