Stable-X commited on
Commit
4c75ed6
·
verified ·
1 Parent(s): 6c3ca0d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -15
app.py CHANGED
@@ -19,6 +19,8 @@ from trellis.utils import render_utils, postprocessing_utils
19
 
20
  MAX_SEED = np.iinfo(np.int32).max
21
  TMP_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tmp')
 
 
22
  os.makedirs(TMP_DIR, exist_ok=True)
23
 
24
  def start_session(req: gr.Request):
@@ -29,8 +31,6 @@ def start_session(req: gr.Request):
29
  def end_session(req: gr.Request):
30
  user_dir = os.path.join(TMP_DIR, str(req.session_hash))
31
  shutil.rmtree(user_dir)
32
-
33
- @spaces.GPU
34
  def preprocess_image(image: Image.Image) -> Image.Image:
35
  """
36
  Preprocess the input image for 3D generation.
@@ -48,7 +48,33 @@ def preprocess_image(image: Image.Image) -> Image.Image:
48
  processed_image = pipeline.preprocess_image(image)
49
  return processed_image
50
 
51
- @spaces.GPU
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  def preprocess_images(images: List[Tuple[Image.Image, str]]) -> List[Image.Image]:
53
  """
54
  Preprocess a list of input images for multi-image 3D generation.
@@ -124,7 +150,7 @@ def get_seed(randomize_seed: bool, seed: int) -> int:
124
  return np.random.randint(0, MAX_SEED) if randomize_seed else seed
125
 
126
 
127
- @spaces.GPU
128
  def generate_and_extract_glb(
129
  multiimages: List[Tuple[Image.Image, str]],
130
  seed: int,
@@ -264,13 +290,31 @@ def split_image(image: Image.Image) -> List[Image.Image]:
264
  images.append(Image.fromarray(image[:, s:e+1]))
265
  return [preprocess_image(image) for image in images]
266
 
267
-
268
- with gr.Blocks(delete_cache=(600, 600)) as demo:
 
 
 
 
 
 
 
 
 
 
269
  gr.Markdown("""
270
- ## Multi-view images to 3D Asset with [ReconViaGen](https://jiahao620.github.io/reconviagen/)
271
- * Upload an image and click "Generate & Extract GLB" to create a 3D asset and automatically extract the GLB file.
272
- * If you want the Gaussian file as well, click "Extract Gaussian" after generation.
273
- * If the image has alpha channel, it will be used as the mask. Otherwise, we use `rembg` to remove the background.
 
 
 
 
 
 
 
 
274
 
275
  ✨This demo is partial. We will release the whole model later. Stay tuned!✨
276
  """)
@@ -278,11 +322,14 @@ with gr.Blocks(delete_cache=(600, 600)) as demo:
278
  with gr.Row():
279
  with gr.Column():
280
  with gr.Tabs() as input_tabs:
281
- with gr.Tab(label="Multiple Images", id=0) as multiimage_input_tab:
 
282
  image_prompt = gr.Image(label="Image Prompt", format="png", visible=False, image_mode="RGBA", type="pil", height=300)
283
  multiimage_prompt = gr.Gallery(label="Image Prompt", format="png", type="pil", height=300, columns=3)
284
  gr.Markdown("""
285
  Input different views of the object in separate images.
 
 
286
  """)
287
 
288
  with gr.Accordion(label="Generation Settings", open=False):
@@ -333,6 +380,11 @@ with gr.Blocks(delete_cache=(600, 600)) as demo:
333
  demo.load(start_session)
334
  demo.unload(end_session)
335
 
 
 
 
 
 
336
 
337
  multiimage_prompt.upload(
338
  preprocess_images,
@@ -345,10 +397,6 @@ with gr.Blocks(delete_cache=(600, 600)) as demo:
345
  inputs=[randomize_seed, seed],
346
  outputs=[seed],
347
  ).then(
348
- # lambda: [None, None, None, None], # 先清空 video_output
349
- # inputs=[],
350
- # outputs=[video_output, model_output, download_glb, download_gs],
351
- # ).then(
352
  generate_and_extract_glb,
353
  inputs=[multiimage_prompt, seed, ss_guidance_strength, ss_sampling_steps, slat_guidance_strength, slat_sampling_steps, multiimage_algo, mesh_simplify, texture_size],
354
  outputs=[output_buf, video_output, model_output, download_glb],
 
19
 
20
  MAX_SEED = np.iinfo(np.int32).max
21
  TMP_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'tmp')
22
+ # TMP_DIR = "tmp/Trellis-demo"
23
+ # os.environ['GRADIO_TEMP_DIR'] = 'tmp'
24
  os.makedirs(TMP_DIR, exist_ok=True)
25
 
26
  def start_session(req: gr.Request):
 
31
  def end_session(req: gr.Request):
32
  user_dir = os.path.join(TMP_DIR, str(req.session_hash))
33
  shutil.rmtree(user_dir)
 
 
34
  def preprocess_image(image: Image.Image) -> Image.Image:
35
  """
36
  Preprocess the input image for 3D generation.
 
48
  processed_image = pipeline.preprocess_image(image)
49
  return processed_image
50
 
51
+ def preprocess_videos(video: str) -> List[Tuple[Image.Image, str]]:
52
+ """
53
+ Preprocess the input video for multi-image 3D generation.
54
+
55
+ This function is called when a user uploads a video.
56
+ It extracts frames from the video and processes each frame to prepare them
57
+ for the multi-image 3D generation pipeline.
58
+
59
+ Args:
60
+ video (str): The path to the input video file
61
+
62
+ Returns:
63
+ List[Tuple[Image.Image, str]]: The list of preprocessed images ready for 3D generation
64
+ """
65
+ vid = imageio.get_reader(video, 'ffmpeg')
66
+ fps = vid.get_meta_data()['fps']
67
+ images = []
68
+ for i, frame in enumerate(vid):
69
+ if i % max(int(fps * 1), 1) == 0:
70
+ img = Image.fromarray(frame)
71
+ W, H = img.size
72
+ img = img.resize((int(W / H * 512), 512))
73
+ images.append(img)
74
+ vid.close()
75
+ processed_images = [pipeline.preprocess_image(image) for image in images]
76
+ return processed_images
77
+
78
  def preprocess_images(images: List[Tuple[Image.Image, str]]) -> List[Image.Image]:
79
  """
80
  Preprocess a list of input images for multi-image 3D generation.
 
150
  return np.random.randint(0, MAX_SEED) if randomize_seed else seed
151
 
152
 
153
+ @spaces.GPU(duration=120)
154
  def generate_and_extract_glb(
155
  multiimages: List[Tuple[Image.Image, str]],
156
  seed: int,
 
290
  images.append(Image.fromarray(image[:, s:e+1]))
291
  return [preprocess_image(image) for image in images]
292
 
293
+ # Create interface
294
+ demo = gr.Blocks(
295
+ title="ReconViaGen",
296
+ css="""
297
+ .slider .inner { width: 5px; background: #FFF; }
298
+ .viewport { aspect-ratio: 4/3; }
299
+ .tabs button.selected { font-size: 20px !important; color: crimson !important; }
300
+ h1, h2, h3 { text-align: center; display: block; }
301
+ .md_feedback li { margin-bottom: 0px !important; }
302
+ """
303
+ )
304
+ with demo:
305
  gr.Markdown("""
306
+ # 💻 ReconViaGen
307
+ <p align="center">
308
+ <a title="Github" href="https://github.com/GAP-LAB-CUHK-SZ/ReconViaGen" target="_blank" rel="noopener noreferrer" style="display: inline-block;">
309
+ <img src="https://img.shields.io/github/stars/GAP-LAB-CUHK-SZ/ReconViaGen?label=GitHub%20%E2%98%85&logo=github&color=C8C" alt="badge-github-stars">
310
+ </a>
311
+ <a title="Website" href="https://jiahao620.github.io/reconviagen/" target="_blank" rel="noopener noreferrer" style="display: inline-block;">
312
+ <img src="https://www.obukhov.ai/img/badges/badge-website.svg">
313
+ </a>
314
+ <a title="arXiv" href="https://jiahao620.github.io/reconviagen/" target="_blank" rel="noopener noreferrer" style="display: inline-block;">
315
+ <img src="https://www.obukhov.ai/img/badges/badge-pdf.svg">
316
+ </a>
317
+ </p>
318
 
319
  ✨This demo is partial. We will release the whole model later. Stay tuned!✨
320
  """)
 
322
  with gr.Row():
323
  with gr.Column():
324
  with gr.Tabs() as input_tabs:
325
+ with gr.Tab(label="Input Video or Images", id=0) as multiimage_input_tab:
326
+ input_video = gr.Video(label="Upload Video", interactive=True, height=300)
327
  image_prompt = gr.Image(label="Image Prompt", format="png", visible=False, image_mode="RGBA", type="pil", height=300)
328
  multiimage_prompt = gr.Gallery(label="Image Prompt", format="png", type="pil", height=300, columns=3)
329
  gr.Markdown("""
330
  Input different views of the object in separate images.
331
+
332
+ *NOTE: this is an experimental algorithm without training a specialized model. It may not produce the best results for all images, especially those having different poses or inconsistent details.*
333
  """)
334
 
335
  with gr.Accordion(label="Generation Settings", open=False):
 
380
  demo.load(start_session)
381
  demo.unload(end_session)
382
 
383
+ input_video.upload(
384
+ preprocess_videos,
385
+ inputs=[input_video],
386
+ outputs=[multiimage_prompt],
387
+ )
388
 
389
  multiimage_prompt.upload(
390
  preprocess_images,
 
397
  inputs=[randomize_seed, seed],
398
  outputs=[seed],
399
  ).then(
 
 
 
 
400
  generate_and_extract_glb,
401
  inputs=[multiimage_prompt, seed, ss_guidance_strength, ss_sampling_steps, slat_guidance_strength, slat_sampling_steps, multiimage_algo, mesh_simplify, texture_size],
402
  outputs=[output_buf, video_output, model_output, download_glb],