Spaces:
Paused
Paused
Ali Mohsin
commited on
Commit
·
e7860b2
1
Parent(s):
7c3fde0
more changes
Browse files
app.py
CHANGED
|
@@ -236,16 +236,14 @@ DEFAULT_CONFIG = {
|
|
| 236 |
'log_light_power': 3.0
|
| 237 |
}
|
| 238 |
|
| 239 |
-
def process_garment(input_type, text_prompt, base_text_prompt,
|
| 240 |
"""
|
| 241 |
Main function to process garment generation
|
| 242 |
|
| 243 |
Args:
|
| 244 |
-
input_type: Either "Text"
|
| 245 |
text_prompt: Text description of target garment (for text mode)
|
| 246 |
base_text_prompt: Text description of base garment (for text mode)
|
| 247 |
-
target_image: Image of target garment style (for image mode)
|
| 248 |
-
base_image: Optional image of base garment (for image mode)
|
| 249 |
mesh_target_image: Image for generating a 3D mesh (for image to mesh mode)
|
| 250 |
source_mesh_type: Type of source mesh to use as starting point (for image to mesh mode)
|
| 251 |
custom_mesh: Optional custom source mesh file (.obj)
|
|
@@ -278,7 +276,7 @@ def process_garment(input_type, text_prompt, base_text_prompt, target_image, bas
|
|
| 278 |
mesh_target_image.save(target_mesh_image_path)
|
| 279 |
else:
|
| 280 |
print(f"Unsupported image type: {type(mesh_target_image)}")
|
| 281 |
-
return
|
| 282 |
|
| 283 |
print(f"Target mesh image saved to {target_mesh_image_path}")
|
| 284 |
|
|
@@ -295,71 +293,6 @@ def process_garment(input_type, text_prompt, base_text_prompt, target_image, bas
|
|
| 295 |
'fashion_text': False,
|
| 296 |
})
|
| 297 |
|
| 298 |
-
elif input_type == "Image" and target_image is not None:
|
| 299 |
-
# Image-based processing
|
| 300 |
-
progress(0.05, desc="Preparing image inputs...")
|
| 301 |
-
|
| 302 |
-
# Save target image to temp directory
|
| 303 |
-
target_image_path = os.path.join(temp_dir, "target_image.jpg")
|
| 304 |
-
|
| 305 |
-
# Handle different possible image formats from Gradio
|
| 306 |
-
if target_image is None:
|
| 307 |
-
return None
|
| 308 |
-
|
| 309 |
-
print(f"Target image type: {type(target_image)}")
|
| 310 |
-
|
| 311 |
-
if isinstance(target_image, str):
|
| 312 |
-
# Image is a file path
|
| 313 |
-
print(f"Copying image from path: {target_image}")
|
| 314 |
-
shutil.copy(target_image, target_image_path)
|
| 315 |
-
elif isinstance(target_image, np.ndarray):
|
| 316 |
-
# Image is a numpy array from Gradio
|
| 317 |
-
print(f"Converting numpy array image with shape: {target_image.shape}")
|
| 318 |
-
# Make sure the array is in RGB format (convert if grayscale)
|
| 319 |
-
if len(target_image.shape) == 2:
|
| 320 |
-
target_image = np.stack([target_image] * 3, axis=2)
|
| 321 |
-
elif target_image.shape[2] == 4: # RGBA
|
| 322 |
-
target_image = target_image[:,:,:3] # Drop alpha channel
|
| 323 |
-
|
| 324 |
-
img = Image.fromarray(target_image.astype(np.uint8))
|
| 325 |
-
img.save(target_image_path)
|
| 326 |
-
print(f"Saved numpy array as image to: {target_image_path}")
|
| 327 |
-
elif hasattr(target_image, 'save'):
|
| 328 |
-
# Image is a PIL image
|
| 329 |
-
print("Saving PIL image")
|
| 330 |
-
target_image.save(target_image_path)
|
| 331 |
-
else:
|
| 332 |
-
print(f"Unsupported image type: {type(target_image)}")
|
| 333 |
-
return None
|
| 334 |
-
|
| 335 |
-
print(f"Target image saved to {target_image_path}")
|
| 336 |
-
|
| 337 |
-
# Save base image if provided, or use default
|
| 338 |
-
if base_image is not None:
|
| 339 |
-
base_image_path = os.path.join(temp_dir, "base_image.jpg")
|
| 340 |
-
if isinstance(base_image, str):
|
| 341 |
-
shutil.copy(base_image, base_image_path)
|
| 342 |
-
elif isinstance(base_image, np.ndarray):
|
| 343 |
-
img = Image.fromarray(base_image)
|
| 344 |
-
img.save(base_image_path)
|
| 345 |
-
elif hasattr(base_image, 'save'):
|
| 346 |
-
base_image.save(base_image_path)
|
| 347 |
-
else:
|
| 348 |
-
# If format is unsupported, use target image
|
| 349 |
-
base_image_path = target_image_path
|
| 350 |
-
print(f"Base image saved to {base_image_path}")
|
| 351 |
-
else:
|
| 352 |
-
# If no base image, use a placeholder or default
|
| 353 |
-
base_image_path = target_image_path
|
| 354 |
-
print("No base image provided, using target image as base")
|
| 355 |
-
|
| 356 |
-
# Configure for image-based processing
|
| 357 |
-
config.update({
|
| 358 |
-
'image_prompt': target_image_path,
|
| 359 |
-
'base_image_prompt': base_image_path,
|
| 360 |
-
'fashion_image': True,
|
| 361 |
-
'fashion_text': False
|
| 362 |
-
})
|
| 363 |
else:
|
| 364 |
# Text-based processing
|
| 365 |
if not text_prompt or len(text_prompt.strip()) == 0:
|
|
@@ -416,37 +349,26 @@ def process_garment(input_type, text_prompt, base_text_prompt, target_image, bas
|
|
| 416 |
try:
|
| 417 |
# Check if loop is available
|
| 418 |
if loop is None:
|
| 419 |
-
error_message = "Error: The garment generation engine could not be loaded due to dependency issues."
|
| 420 |
print(error_message)
|
| 421 |
-
|
| 422 |
-
error_file = os.path.join(temp_dir, "error_report.txt")
|
| 423 |
-
with open(error_file, 'w') as f:
|
| 424 |
-
f.write("Garment3DGen Error Report\n\n")
|
| 425 |
-
f.write(error_message + "\n\n")
|
| 426 |
-
f.write("This is likely due to compatibility issues between PyTorch and torchvision.")
|
| 427 |
-
return error_file
|
| 428 |
|
| 429 |
# Run the loop with error handling
|
| 430 |
loop(config)
|
| 431 |
except RuntimeError as e:
|
| 432 |
print(f"Runtime error during processing: {e}")
|
| 433 |
if "operator torchvision::nms does not exist" in str(e):
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
f.write("Please check that you have compatible versions of PyTorch and torchvision installed.")
|
| 442 |
-
return error_file
|
| 443 |
except Exception as e:
|
| 444 |
print(f"Error during processing: {e}")
|
| 445 |
-
|
| 446 |
-
|
| 447 |
-
f.write("Garment3DGen Error Report\n\n")
|
| 448 |
-
f.write(f"Error: {str(e)}")
|
| 449 |
-
return error_file
|
| 450 |
|
| 451 |
progress(0.9, desc="Processing complete, preparing output...")
|
| 452 |
|
|
@@ -526,18 +448,17 @@ def create_interface():
|
|
| 526 |
that can be used for virtual try-on applications.
|
| 527 |
|
| 528 |
## How to use:
|
| 529 |
-
1. Choose **Text
|
| 530 |
2. For **Text** mode: Enter descriptions of your target and base garment styles
|
| 531 |
-
3. For **Image** mode: Upload an image
|
| 532 |
-
4.
|
| 533 |
-
5. Click "Generate 3D Garment" to create your 3D mesh file
|
| 534 |
""")
|
| 535 |
|
| 536 |
with gr.Row():
|
| 537 |
with gr.Column():
|
| 538 |
# Input type selector
|
| 539 |
input_type = gr.Radio(
|
| 540 |
-
choices=["Text", "Image
|
| 541 |
value="Text",
|
| 542 |
label="Generation Method"
|
| 543 |
)
|
|
@@ -556,23 +477,7 @@ def create_interface():
|
|
| 556 |
value="simple t-shirt"
|
| 557 |
)
|
| 558 |
|
| 559 |
-
|
| 560 |
-
with gr.Group(visible=False) as image_group:
|
| 561 |
-
target_image = gr.Image(
|
| 562 |
-
label="Target Garment Image",
|
| 563 |
-
sources=["upload", "webcam"],
|
| 564 |
-
type="numpy",
|
| 565 |
-
interactive=True
|
| 566 |
-
)
|
| 567 |
-
gr.Markdown("*Upload an image of the desired garment style*")
|
| 568 |
-
|
| 569 |
-
base_image = gr.Image(
|
| 570 |
-
label="Base Garment Image (Optional)",
|
| 571 |
-
sources=["upload", "webcam"],
|
| 572 |
-
type="numpy",
|
| 573 |
-
interactive=True
|
| 574 |
-
)
|
| 575 |
-
gr.Markdown("*Upload a base garment image (optional)*")
|
| 576 |
|
| 577 |
# Image to Mesh inputs (hidden by default)
|
| 578 |
with gr.Group(visible=False) as image_to_mesh_group:
|
|
@@ -643,9 +548,9 @@ def create_interface():
|
|
| 643 |
gr.Markdown("""
|
| 644 |
## Tips:
|
| 645 |
|
| 646 |
-
- For text mode: Be specific in your descriptions
|
| 647 |
-
- For image mode: Use clear, front-facing garment images
|
| 648 |
-
-
|
| 649 |
- Higher epochs = better quality but longer processing time
|
| 650 |
- Output files can be downloaded by clicking on them
|
| 651 |
|
|
@@ -658,20 +563,16 @@ def create_interface():
|
|
| 658 |
# Define a function to handle mode changes with clearer UI feedback
|
| 659 |
def update_mode(mode):
|
| 660 |
text_visibility = mode == "Text"
|
| 661 |
-
image_visibility = mode == "Image"
|
| 662 |
image_to_mesh_visibility = mode == "Image to Mesh"
|
| 663 |
status_msg = f"Mode changed to {mode}. "
|
| 664 |
|
| 665 |
if text_visibility:
|
| 666 |
status_msg += "Enter garment descriptions and click Generate."
|
| 667 |
-
elif image_visibility:
|
| 668 |
-
status_msg += "Upload garment images and click Generate."
|
| 669 |
else:
|
| 670 |
status_msg += "Upload a garment image and select mesh type, then click Generate."
|
| 671 |
|
| 672 |
return (
|
| 673 |
gr.Group.update(visible=text_visibility),
|
| 674 |
-
gr.Group.update(visible=image_visibility),
|
| 675 |
gr.Group.update(visible=image_to_mesh_visibility),
|
| 676 |
status_msg
|
| 677 |
)
|
|
@@ -682,7 +583,10 @@ def create_interface():
|
|
| 682 |
result = process_garment(*args)
|
| 683 |
if result is None:
|
| 684 |
return None, "Processing failed. Please check the logs for details."
|
| 685 |
-
|
|
|
|
|
|
|
|
|
|
| 686 |
except Exception as e:
|
| 687 |
import traceback
|
| 688 |
print(f"Error in interface: {str(e)}")
|
|
@@ -693,7 +597,7 @@ def create_interface():
|
|
| 693 |
input_type.change(
|
| 694 |
fn=update_mode,
|
| 695 |
inputs=[input_type],
|
| 696 |
-
outputs=[text_group,
|
| 697 |
)
|
| 698 |
|
| 699 |
# Connect the button to the processing function with error handling
|
|
@@ -703,8 +607,6 @@ def create_interface():
|
|
| 703 |
input_type,
|
| 704 |
text_prompt,
|
| 705 |
base_text_prompt,
|
| 706 |
-
target_image,
|
| 707 |
-
base_image,
|
| 708 |
mesh_target_image,
|
| 709 |
source_mesh_type,
|
| 710 |
custom_mesh,
|
|
|
|
| 236 |
'log_light_power': 3.0
|
| 237 |
}
|
| 238 |
|
| 239 |
+
def process_garment(input_type, text_prompt, base_text_prompt, mesh_target_image, source_mesh_type, custom_mesh, epochs, learning_rate, clip_weight, delta_clip_weight, progress=gr.Progress()):
|
| 240 |
"""
|
| 241 |
Main function to process garment generation
|
| 242 |
|
| 243 |
Args:
|
| 244 |
+
input_type: Either "Text" or "Image to Mesh" to determine the processing mode
|
| 245 |
text_prompt: Text description of target garment (for text mode)
|
| 246 |
base_text_prompt: Text description of base garment (for text mode)
|
|
|
|
|
|
|
| 247 |
mesh_target_image: Image for generating a 3D mesh (for image to mesh mode)
|
| 248 |
source_mesh_type: Type of source mesh to use as starting point (for image to mesh mode)
|
| 249 |
custom_mesh: Optional custom source mesh file (.obj)
|
|
|
|
| 276 |
mesh_target_image.save(target_mesh_image_path)
|
| 277 |
else:
|
| 278 |
print(f"Unsupported image type: {type(mesh_target_image)}")
|
| 279 |
+
return "Error: Could not process the uploaded image. Please try a different image format."
|
| 280 |
|
| 281 |
print(f"Target mesh image saved to {target_mesh_image_path}")
|
| 282 |
|
|
|
|
| 293 |
'fashion_text': False,
|
| 294 |
})
|
| 295 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
else:
|
| 297 |
# Text-based processing
|
| 298 |
if not text_prompt or len(text_prompt.strip()) == 0:
|
|
|
|
| 349 |
try:
|
| 350 |
# Check if loop is available
|
| 351 |
if loop is None:
|
| 352 |
+
error_message = "Error: The garment generation engine could not be loaded due to dependency issues. This is likely due to compatibility issues between PyTorch and torchvision in the current environment."
|
| 353 |
print(error_message)
|
| 354 |
+
return error_message
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
|
| 356 |
# Run the loop with error handling
|
| 357 |
loop(config)
|
| 358 |
except RuntimeError as e:
|
| 359 |
print(f"Runtime error during processing: {e}")
|
| 360 |
if "operator torchvision::nms does not exist" in str(e):
|
| 361 |
+
error_message = "Error: PyTorch/torchvision version incompatibility detected. This is a known issue in some environments."
|
| 362 |
+
print(error_message)
|
| 363 |
+
return error_message
|
| 364 |
+
else:
|
| 365 |
+
error_message = f"Runtime error during processing: {str(e)}"
|
| 366 |
+
print(error_message)
|
| 367 |
+
return error_message
|
|
|
|
|
|
|
| 368 |
except Exception as e:
|
| 369 |
print(f"Error during processing: {e}")
|
| 370 |
+
error_message = f"Error during processing: {str(e)}"
|
| 371 |
+
return error_message
|
|
|
|
|
|
|
|
|
|
| 372 |
|
| 373 |
progress(0.9, desc="Processing complete, preparing output...")
|
| 374 |
|
|
|
|
| 448 |
that can be used for virtual try-on applications.
|
| 449 |
|
| 450 |
## How to use:
|
| 451 |
+
1. Choose **Text** or **Image to Mesh** input mode using the radio button below
|
| 452 |
2. For **Text** mode: Enter descriptions of your target and base garment styles
|
| 453 |
+
3. For **Image to Mesh** mode: Upload an image to generate a 3D mesh directly and select a base mesh type
|
| 454 |
+
4. Click "Generate 3D Garment" to create your 3D mesh file
|
|
|
|
| 455 |
""")
|
| 456 |
|
| 457 |
with gr.Row():
|
| 458 |
with gr.Column():
|
| 459 |
# Input type selector
|
| 460 |
input_type = gr.Radio(
|
| 461 |
+
choices=["Text", "Image to Mesh"],
|
| 462 |
value="Text",
|
| 463 |
label="Generation Method"
|
| 464 |
)
|
|
|
|
| 477 |
value="simple t-shirt"
|
| 478 |
)
|
| 479 |
|
| 480 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
|
| 482 |
# Image to Mesh inputs (hidden by default)
|
| 483 |
with gr.Group(visible=False) as image_to_mesh_group:
|
|
|
|
| 548 |
gr.Markdown("""
|
| 549 |
## Tips:
|
| 550 |
|
| 551 |
+
- For text mode: Be specific in your descriptions (e.g., "red leather jacket with zippers")
|
| 552 |
+
- For image to mesh mode: Use clear, front-facing garment images to generate a 3D mesh directly
|
| 553 |
+
- Choose the appropriate base mesh type that matches your target garment
|
| 554 |
- Higher epochs = better quality but longer processing time
|
| 555 |
- Output files can be downloaded by clicking on them
|
| 556 |
|
|
|
|
| 563 |
# Define a function to handle mode changes with clearer UI feedback
|
| 564 |
def update_mode(mode):
|
| 565 |
text_visibility = mode == "Text"
|
|
|
|
| 566 |
image_to_mesh_visibility = mode == "Image to Mesh"
|
| 567 |
status_msg = f"Mode changed to {mode}. "
|
| 568 |
|
| 569 |
if text_visibility:
|
| 570 |
status_msg += "Enter garment descriptions and click Generate."
|
|
|
|
|
|
|
| 571 |
else:
|
| 572 |
status_msg += "Upload a garment image and select mesh type, then click Generate."
|
| 573 |
|
| 574 |
return (
|
| 575 |
gr.Group.update(visible=text_visibility),
|
|
|
|
| 576 |
gr.Group.update(visible=image_to_mesh_visibility),
|
| 577 |
status_msg
|
| 578 |
)
|
|
|
|
| 583 |
result = process_garment(*args)
|
| 584 |
if result is None:
|
| 585 |
return None, "Processing failed. Please check the logs for details."
|
| 586 |
+
elif isinstance(result, str) and result.startswith("Error:"):
|
| 587 |
+
return None, result
|
| 588 |
+
else:
|
| 589 |
+
return result, "Processing completed successfully! Download your 3D garment file below."
|
| 590 |
except Exception as e:
|
| 591 |
import traceback
|
| 592 |
print(f"Error in interface: {str(e)}")
|
|
|
|
| 597 |
input_type.change(
|
| 598 |
fn=update_mode,
|
| 599 |
inputs=[input_type],
|
| 600 |
+
outputs=[text_group, image_to_mesh_group, status_output]
|
| 601 |
)
|
| 602 |
|
| 603 |
# Connect the button to the processing function with error handling
|
|
|
|
| 607 |
input_type,
|
| 608 |
text_prompt,
|
| 609 |
base_text_prompt,
|
|
|
|
|
|
|
| 610 |
mesh_target_image,
|
| 611 |
source_mesh_type,
|
| 612 |
custom_mesh,
|