nalin0503 commited on
Commit
68e417f
·
1 Parent(s): 9896f65
Files changed (1) hide show
  1. app.py +200 -82
app.py CHANGED
@@ -58,6 +58,9 @@ def main():
58
 
59
  if 'final_video_path' not in st.session_state:
60
  st.session_state.final_video_path = None
 
 
 
61
 
62
  # Restart function to reset session state
63
  def restart():
@@ -65,6 +68,7 @@ def main():
65
  st.session_state.process_complete = False
66
  st.session_state.temp_dir = None
67
  st.session_state.final_video_path = None
 
68
  st.rerun() # Use st.rerun() instead of experimental_rerun
69
 
70
  # ---------------- CUSTOM CSS FOR A PROFESSIONAL, DARK THEME ----------------
@@ -157,6 +161,62 @@ def main():
157
  padding-left: 1rem;
158
  margin-left: 1rem;
159
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  </style>
161
  """,
162
  unsafe_allow_html=True
@@ -223,6 +283,36 @@ def main():
223
  # Early return to not show the input forms again when we have a result
224
  return
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  # ---------------- SECTION 1: IMAGE & PROMPT INPUTS ----------------
227
  st.subheader("1. Upload Source Images & Prompts")
228
  st.markdown("**Note:** Your uploaded images must be of similar topology and same size to achieve the best results.")
@@ -358,98 +448,126 @@ def main():
358
 
359
  # Button is disabled during processing
360
  if st.button(button_text, key="run_pipeline", disabled=st.session_state.processing):
361
- if not (uploaded_image_A and uploaded_image_B):
362
- st.error("Please upload both images before running the morphing pipeline.")
363
- else:
364
- # Set the processing state to True to prevent multiple runs
365
- st.session_state.processing = True
366
- st.info("Processing your morphing request. Please wait...")
367
-
368
- # Create a temporary folder for processing
369
- temp_dir = create_temp_folder()
370
- st.session_state.temp_dir = temp_dir
371
-
372
- try:
373
- # Save uploaded images
374
- imgA_path = os.path.join(temp_dir, "imageA.png")
375
- imgB_path = os.path.join(temp_dir, "imageB.png")
376
- save_uploaded_file(uploaded_image_A, imgA_path)
377
- save_uploaded_file(uploaded_image_B, imgB_path)
378
-
379
- # Create output directories
380
- timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
381
- output_dir = os.path.join(temp_dir, f"morph_results_{timestamp}")
382
- film_output_dir = os.path.join(temp_dir, f"film_output_{timestamp}")
383
- os.makedirs(output_dir, exist_ok=True)
384
- os.makedirs(film_output_dir, exist_ok=True)
385
-
386
- actual_model_path = (
387
- "lykon/dreamshaper-7" if model_option == "Dreamshaper-7 (fine-tuned SD V1-5)"
388
- else "stabilityai/stable-diffusion-2-1-base" if model_option == "Base Stable Diffusion V2-1"
389
- else "sd-legacy/stable-diffusion-v1-5"
390
- )
391
-
392
- # Build the command for run_morphing.py
393
- cmd = [
394
- sys.executable, "run_morphing.py",
395
- "--model_path", actual_model_path,
396
- "--image_path_0", imgA_path,
397
- "--image_path_1", imgB_path,
398
- "--prompt_0", prompt_A,
399
- "--prompt_1", prompt_B,
400
- "--output_path", output_dir,
401
- "--film_output_folder", film_output_dir,
402
- "--num_frames", str(num_frames),
403
- "--fps", str(output_fps)
404
- ]
405
-
406
- if enable_lcm_lora:
407
- cmd.append("--use_lcm")
408
- if use_adain:
409
- cmd.append("--use_adain")
410
- if use_reschedule:
411
- cmd.append("--use_reschedule")
412
- if use_film:
413
- cmd.append("--use_film")
414
-
415
- # Add film recursion parameter
416
- cmd.extend(["--film_num_recursions", str(film_recursions)])
417
 
418
- # Run the morphing process
419
  try:
420
- subprocess.run(cmd, check=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
 
422
- # Check for output video
423
- video_found = False
424
- possible_outputs = [f for f in os.listdir(film_output_dir) if f.endswith(".mp4")]
425
- if possible_outputs:
426
- final_video_path = os.path.join(film_output_dir, possible_outputs[0])
427
- video_found = True
 
 
428
 
429
- if not video_found:
430
- possible_outputs = [f for f in os.listdir(output_dir) if f.endswith(".mp4")]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  if possible_outputs:
432
- final_video_path = os.path.join(output_dir, possible_outputs[0])
433
  video_found = True
434
-
435
- if video_found:
436
- st.session_state.final_video_path = final_video_path
437
- st.session_state.process_complete = True
438
- st.rerun() # This is crucial for showing the results page
439
- else:
440
- st.error("No output video was generated. Check logs for details.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  st.session_state.processing = False
442
  st.session_state.process_complete = False
443
-
444
- except subprocess.CalledProcessError as e:
445
- st.error(f"Error running morphing pipeline: {e}")
 
446
  st.session_state.processing = False
447
  st.session_state.process_complete = False
448
-
449
- except Exception as e:
450
- st.error(f"An error occurred during processing: {e}")
451
- st.session_state.processing = False
452
- st.session_state.process_complete = False
453
 
454
  if __name__ == "__main__":
455
  main()
 
58
 
59
  if 'final_video_path' not in st.session_state:
60
  st.session_state.final_video_path = None
61
+
62
+ if 'progress_stage' not in st.session_state:
63
+ st.session_state.progress_stage = 0
64
 
65
  # Restart function to reset session state
66
  def restart():
 
68
  st.session_state.process_complete = False
69
  st.session_state.temp_dir = None
70
  st.session_state.final_video_path = None
71
+ st.session_state.progress_stage = 0
72
  st.rerun() # Use st.rerun() instead of experimental_rerun
73
 
74
  # ---------------- CUSTOM CSS FOR A PROFESSIONAL, DARK THEME ----------------
 
161
  padding-left: 1rem;
162
  margin-left: 1rem;
163
  }
164
+ /* Processing status box */
165
+ .processing-box {
166
+ background: rgba(0, 0, 0, 0.6);
167
+ border-radius: 10px;
168
+ border: 1px solid rgba(142, 68, 173, 0.6);
169
+ padding: 20px;
170
+ margin: 20px 0;
171
+ box-shadow: 0 0 30px rgba(142, 68, 173, 0.4);
172
+ text-align: center;
173
+ }
174
+ .processing-title {
175
+ font-size: 1.5rem;
176
+ color: #ffffff;
177
+ margin-bottom: 15px;
178
+ font-weight: bold;
179
+ }
180
+ .processing-stage {
181
+ margin: 15px 0;
182
+ font-size: 1.1rem;
183
+ color: #f1f1f1;
184
+ }
185
+ .pulse {
186
+ animation: pulse 2s infinite;
187
+ }
188
+ @keyframes pulse {
189
+ 0% { opacity: 1; }
190
+ 50% { opacity: 0.6; }
191
+ 100% { opacity: 1; }
192
+ }
193
+ .progress-bar-container {
194
+ width: 100%;
195
+ background-color: rgba(255, 255, 255, 0.2);
196
+ border-radius: 5px;
197
+ margin: 15px 0;
198
+ overflow: hidden;
199
+ }
200
+ .progress-bar {
201
+ height: 10px;
202
+ background-image: linear-gradient(45deg, #8e44ad, #732d91);
203
+ border-radius: 5px;
204
+ transition: width 0.5s ease;
205
+ }
206
+ /* Rainbow spinner animation */
207
+ .spinner {
208
+ width: 40px;
209
+ height: 40px;
210
+ margin: 15px auto;
211
+ border: 4px solid transparent;
212
+ border-radius: 50%;
213
+ border-image: linear-gradient(45deg, purple, blue, cyan, green, yellow, orange, red) 1;
214
+ animation: spin 1s linear infinite;
215
+ }
216
+ @keyframes spin {
217
+ 0% { transform: rotate(0deg); }
218
+ 100% { transform: rotate(360deg); }
219
+ }
220
  </style>
221
  """,
222
  unsafe_allow_html=True
 
283
  # Early return to not show the input forms again when we have a result
284
  return
285
 
286
+ # Show enhanced processing status if in processing mode
287
+ if st.session_state.processing:
288
+ # Define processing stages
289
+ stages = [
290
+ "Initializing the morphing pipeline...",
291
+ "Loading and processing images...",
292
+ "Generating keyframes with diffusion model...",
293
+ "Creating intermediate frames...",
294
+ "Finalizing your morphing video...",
295
+ ]
296
+
297
+ # Calculate progress percentage (artifically progressing based on time since start)
298
+ progress = min(st.session_state.progress_stage / len(stages), 1.0)
299
+
300
+ # Show processing status
301
+ st.markdown(
302
+ f"""
303
+ <div class="processing-box">
304
+ <div class="processing-title">🔮 Creating Your Morphing Video</div>
305
+ <div class="spinner"></div>
306
+ <div class="processing-stage pulse">{stages[st.session_state.progress_stage]}</div>
307
+ <div class="progress-bar-container">
308
+ <div class="progress-bar" style="width: {int(progress * 100)}%"></div>
309
+ </div>
310
+ <div class="processing-stage">Please wait while we work our magic...</div>
311
+ </div>
312
+ """,
313
+ unsafe_allow_html=True
314
+ )
315
+
316
  # ---------------- SECTION 1: IMAGE & PROMPT INPUTS ----------------
317
  st.subheader("1. Upload Source Images & Prompts")
318
  st.markdown("**Note:** Your uploaded images must be of similar topology and same size to achieve the best results.")
 
448
 
449
  # Button is disabled during processing
450
  if st.button(button_text, key="run_pipeline", disabled=st.session_state.processing):
451
+ # Set processing state to True immediately
452
+ st.session_state.processing = True
453
+ st.rerun() # Force a refresh to apply the disabled state to all UI elements
454
+ else:
455
+ # This will run after the refresh
456
+ if st.session_state.processing:
457
+ # Check if both images are uploaded
458
+ if not (uploaded_image_A and uploaded_image_B):
459
+ st.error("Please upload both images before running the morphing pipeline.")
460
+ st.session_state.processing = False # Reset processing state
461
+ st.rerun() # Refresh again to enable UI elements
462
+ else:
463
+ # Increment progress stage periodically
464
+ # In a real implementation, these stage updates would be triggered by actual progress
465
+ # Here we simulate progress for demonstration
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
 
467
+ # Create a temporary folder for processing
468
  try:
469
+ temp_dir = create_temp_folder()
470
+ st.session_state.temp_dir = temp_dir
471
+
472
+ # Save uploaded images
473
+ imgA_path = os.path.join(temp_dir, "imageA.png")
474
+ imgB_path = os.path.join(temp_dir, "imageB.png")
475
+ save_uploaded_file(uploaded_image_A, imgA_path)
476
+ save_uploaded_file(uploaded_image_B, imgB_path)
477
+
478
+ # Update progress stage
479
+ st.session_state.progress_stage = 1
480
+ st.rerun() # Refresh to update progress
481
+
482
+ # Create output directories
483
+ timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
484
+ output_dir = os.path.join(temp_dir, f"morph_results_{timestamp}")
485
+ film_output_dir = os.path.join(temp_dir, f"film_output_{timestamp}")
486
+ os.makedirs(output_dir, exist_ok=True)
487
+ os.makedirs(film_output_dir, exist_ok=True)
488
+
489
+ actual_model_path = (
490
+ "lykon/dreamshaper-7" if model_option == "Dreamshaper-7 (fine-tuned SD V1-5)"
491
+ else "stabilityai/stable-diffusion-2-1-base" if model_option == "Base Stable Diffusion V2-1"
492
+ else "sd-legacy/stable-diffusion-v1-5"
493
+ )
494
+
495
+ # Build the command for run_morphing.py
496
+ cmd = [
497
+ sys.executable, "run_morphing.py",
498
+ "--model_path", actual_model_path,
499
+ "--image_path_0", imgA_path,
500
+ "--image_path_1", imgB_path,
501
+ "--prompt_0", prompt_A,
502
+ "--prompt_1", prompt_B,
503
+ "--output_path", output_dir,
504
+ "--film_output_folder", film_output_dir,
505
+ "--num_frames", str(num_frames),
506
+ "--fps", str(output_fps)
507
+ ]
508
 
509
+ if enable_lcm_lora:
510
+ cmd.append("--use_lcm")
511
+ if use_adain:
512
+ cmd.append("--use_adain")
513
+ if use_reschedule:
514
+ cmd.append("--use_reschedule")
515
+ if use_film:
516
+ cmd.append("--use_film")
517
 
518
+ # Add film recursion parameter
519
+ cmd.extend(["--film_num_recursions", str(film_recursions)])
520
+
521
+ # Update progress stage - Start generating keyframes
522
+ st.session_state.progress_stage = 2
523
+ st.rerun() # Refresh to update progress
524
+
525
+ # Run the morphing process
526
+ try:
527
+ subprocess.run(cmd, check=True)
528
+
529
+ # Update progress stage - Creating intermediate frames
530
+ st.session_state.progress_stage = 3
531
+ st.rerun() # Refresh to update progress
532
+
533
+ # Check for output video
534
+ video_found = False
535
+ possible_outputs = [f for f in os.listdir(film_output_dir) if f.endswith(".mp4")]
536
  if possible_outputs:
537
+ final_video_path = os.path.join(film_output_dir, possible_outputs[0])
538
  video_found = True
539
+
540
+ if not video_found:
541
+ possible_outputs = [f for f in os.listdir(output_dir) if f.endswith(".mp4")]
542
+ if possible_outputs:
543
+ final_video_path = os.path.join(output_dir, possible_outputs[0])
544
+ video_found = True
545
+
546
+ # Update progress stage - Finalizing video
547
+ st.session_state.progress_stage = 4
548
+ st.rerun() # Refresh to update progress
549
+
550
+ if video_found:
551
+ st.session_state.final_video_path = final_video_path
552
+ st.session_state.process_complete = True
553
+ st.rerun() # Show the results page
554
+ else:
555
+ st.error("No output video was generated. Check logs for details.")
556
+ st.session_state.processing = False
557
+ st.session_state.process_complete = False
558
+ st.rerun() # Reset the interface
559
+
560
+ except subprocess.CalledProcessError as e:
561
+ st.error(f"Error running morphing pipeline: {e}")
562
  st.session_state.processing = False
563
  st.session_state.process_complete = False
564
+ st.rerun() # Reset the interface
565
+
566
+ except Exception as e:
567
+ st.error(f"An error occurred during processing: {e}")
568
  st.session_state.processing = False
569
  st.session_state.process_complete = False
570
+ st.rerun() # Reset the interface
 
 
 
 
571
 
572
  if __name__ == "__main__":
573
  main()