Spaces:
Runtime error
Runtime error
from fastapi import FastAPI | |
import gradio as gr | |
from PIL import Image | |
import numpy as np | |
import torch | |
from transformers import pipeline | |
import cv2 # cv2๋ ์ด๋ฏธ์ง ๋ก๋/์ ์ฅ/์ ์ฒ๋ฆฌ ๋ฑ์ ์ฌ์ฉ๋ ์ ์์ง๋ง, ํ์ฌ ์ฝ๋์์๋ PIL๋ง์ผ๋ก๋ ์ถฉ๋ถํฉ๋๋ค. | |
app = FastAPI() | |
# ๋ฅ๋ฌ๋ ๋ชจ๋ธ ๋ก๋ (Depth Anything) | |
# ๋ชจ๋ธ ๋ก๋ฉ์ ์ฑ ์์ ์ ํ ๋ฒ๋ง ํ๋๋ก ๊ธ๋ก๋ฒ ๋ณ์๋ก ์ค์ | |
print("Loading Depth Anything model...") | |
try: | |
# ๐๐๐ ๋ชจ๋ธ ์ด๋ฆ ์์ : ์ ํํ Depth Anything v2 Large ๋ชจ๋ธ ID ๐๐๐ | |
# ๋ ์์ ๋ชจ๋ธ์ ์ํ์๋ฉด "LiangNX/depth-anything-v2-base-nyu" ๋ก ๋ณ๊ฒฝํ์ธ์. | |
depth_estimator = pipeline(task="depth-estimation", model="LiangNX/depth-anything-v2-large-nyu", device="cpu") # GPU ์ฌ์ฉ ์ device="cuda" | |
print("Depth Anything model loaded successfully.") | |
except Exception as e: | |
print(f"Error loading Depth Anything model: {e}") | |
depth_estimator = None # ๋ชจ๋ธ ๋ก๋ ์คํจ ์ None์ผ๋ก ์ค์ | |
def process_image_for_depth(image_path_or_pil_image): | |
""" | |
๋จ์ผ ์ด๋ฏธ์ง์์ ๋์ค ๋งต์ ์ถ์ถํ๋ ํจ์. | |
""" | |
if depth_estimator is None: | |
return None, "Error: Depth Anything model not loaded. Check server logs." | |
# Gradio๋ PIL Image ๊ฐ์ฒด๋ก ์ด๋ฏธ์ง๋ฅผ ์ ๋ฌํฉ๋๋ค. | |
if isinstance(image_path_or_pil_image, str): | |
# ํ์ผ ๊ฒฝ๋ก๋ก ์ด๋ฏธ์ง๊ฐ ์ ๋ฌ๋ ๊ฒฝ์ฐ (์: Gradio์ `filepath` ํ์ ) | |
image = Image.open(image_path_or_pil_image).convert("RGB") | |
else: | |
# PIL Image ๊ฐ์ฒด๊ฐ ์ง์ ์ ๋ฌ๋ ๊ฒฝ์ฐ | |
image = image_path_or_pil_image.convert("RGB") | |
try: | |
# Depth Anything ๋ชจ๋ธ ์ถ๋ก | |
# result๋ ๋์ ๋๋ฆฌ๋ก, 'depth' (PIL Image)์ 'depth_npy' (numpy array)๋ฅผ ํฌํจํฉ๋๋ค. | |
result = depth_estimator(image) | |
# ๋์ค ๋งต (PIL Image) - ์ด PIL ์ด๋ฏธ์ง๋ ์ด๋ฏธ ์๊ฐํํ๊ธฐ ์ข์ ํํ๋ก ๋์ด ์์ต๋๋ค. | |
depth_image_pil = result["depth"] | |
# ๋์ค ๋งต (Numpy Array) - ํ์ํ๋ค๋ฉด ์ถ๊ฐ ์ฒ๋ฆฌ (์: ์ ๊ทํ, ๋ค๋ฅธ ํ์์ผ๋ก ๋ณํ) | |
# ํ์ฌ๋ ํ๋ฐฑ ์ด๋ฏธ์ง๋ก ๋ฐ๋ก ์ฌ์ฉํด๋ ์ถฉ๋ถํ๋ฏ๋ก, ์๋ ์ฝ๋๋ ์ ํ ์ฌํญ์ ๋๋ค. | |
# depth_np = result["depth_npy"] | |
# normalized_depth_np = (depth_np - depth_np.min()) / (depth_np.max() - depth_np.min()) * 255 | |
# normalized_depth_np = normalized_depth_np.astype(np.uint8) | |
# depth_grayscale_pil = Image.fromarray(normalized_depth_np) | |
return depth_image_pil, None # ๋์ค ๋งต PIL Image ๋ฐํ | |
except Exception as e: | |
import traceback | |
traceback.print_exc() # ์๋ฌ ๋ฐ์ ์ ์์ธ ํธ๋ ์ด์ค๋ฐฑ ์ถ๋ ฅ | |
return None, f"Error processing image for depth: {e}" | |
# Gradio ์ธํฐํ์ด์ค ์ ์ | |
with gr.Blocks() as demo: | |
gr.Markdown("# ๐งโ๐ป ์ผ๊ตด ๋์ค ๋งต ์ถ์ถ๊ธฐ") | |
gr.Markdown("์ฌ๋ฌ ์ฅ์ ์ผ๊ตด ์ฌ์ง์ ์ ๋ก๋ํ๋ฉด ๊ฐ ์ฌ์ง์์ ๋ฅ๋ฌ๋์ ํตํด ๋์ค ๋งต(๊น์ด ์ ๋ณด)์ ์ถ์ถํฉ๋๋ค.") | |
gr.Markdown("โ ๏ธ **์ฐธ๊ณ :** ๋ฌด๋ฃ CPU ํ๊ฒฝ์์๋ ๋ชจ๋ธ ๋ก๋ฉ ๋ฐ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ์๊ฐ์ด ๋งค์ฐ ์ค๋ ๊ฑธ๋ฆด ์ ์์ต๋๋ค.") | |
with gr.Row(): | |
# file_count="multiple"๋ก ์ฌ๋ฌ ํ์ผ ์ ๋ก๋ ๊ฐ๋ฅํ๊ฒ ์ค์ | |
# type="filepath"๋ก ์ค์ ํ์ฌ Gradio๊ฐ ํ์ผ์ ์์ ๊ฒฝ๋ก์ ์ ์ฅํ๋๋ก ํจ | |
input_images = gr.File(label="์ผ๊ตด ์ฌ์ง ์ ๋ก๋ (์ต๋ 10์ฅ ๊ถ์ฅ)", file_count="multiple", type="filepath") | |
output_gallery = gr.Gallery(label="์๋ณธ ์ด๋ฏธ์ง ๋ฐ ๋์ค ๋งต", columns=[2], rows=[1], object_fit="contain", height="auto") | |
process_button = gr.Button("๋์ค ๋งต ์ถ์ถ ์์") | |
def process_all_images(image_paths): | |
""" | |
์ ๋ก๋๋ ๋ชจ๋ ์ด๋ฏธ์ง์ ๋ํด ๋์ค ๋งต ์ถ์ถ์ ์ํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ํจ์. | |
""" | |
if not image_paths: | |
return [(None, "์ด๋ฏธ์ง๋ฅผ ์ ๋ก๋ํด์ฃผ์ธ์.")] | |
results_for_gallery = [] # Gradio Gallery์ ํ์ํ (PIL Image, Label) ํํ ๋ฆฌ์คํธ | |
for i, path in enumerate(image_paths): | |
try: | |
original_image = Image.open(path).convert("RGB") | |
depth_map_pil, error = process_image_for_depth(original_image) | |
# ์๋ณธ ์ด๋ฏธ์ง๋ฅผ ๋จผ์ ์ถ๊ฐ | |
results_for_gallery.append((original_image, f"์๋ณธ ์ด๋ฏธ์ง {i+1}")) | |
if error: | |
print(f"Error processing image {i+1}: {error}") | |
# ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ๋์ค ๋งต ๋์ ์ค๋ฅ ๋ฉ์์ง ํ์ | |
# ์ด ๋ถ๋ถ์ Gradio Gallery๊ฐ (Image, Label)์ ๊ธฐ๋ํ๋ฏ๋ก, | |
# ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ ์คํธ ์ด๋ฏธ์ง๋ก ๋ง๋ค๊ฑฐ๋, ์ค๋ฅ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. | |
# ์ฌ๊ธฐ์๋ ๊ฐ๋จํ ๋น ์ด๋ฏธ์ง์ ํจ๊ป ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ํ๋๋ก ํฉ๋๋ค. | |
dummy_error_image = Image.new('RGB', original_image.size, color = 'red') | |
results_for_gallery.append((dummy_error_image, f"์ค๋ฅ ๋ฐ์: {error}")) | |
else: | |
results_for_gallery.append((depth_map_pil, f"๋์ค ๋งต {i+1}")) | |
except Exception as e: | |
# ํ์ผ ์์ฒด๋ฅผ ์ฌ๋ ๋ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ | |
print(f"Failed to open or process file {path}: {e}") | |
dummy_error_image = Image.new('RGB', (200, 200), color = 'red') # ์์ ์๋ฌ ์ด๋ฏธ์ง | |
results_for_gallery.append((dummy_error_image, f"ํ์ผ ์ฒ๋ฆฌ ์ค๋ฅ: {e}")) | |
return results_for_gallery | |
# ๋ฒํผ ํด๋ฆญ ์ ํจ์ ์ฐ๊ฒฐ | |
process_button.click( | |
fn=process_all_images, | |
inputs=input_images, | |
outputs=output_gallery | |
) | |
# Gradio ์ฑ์ FastAPI์ ๋ง์ดํธ | |
# ๊ธฐ๋ณธ ๊ฒฝ๋ก (path="/")์ Gradio ์ฑ์ ๋ง์ดํธํ์ฌ ์น ํ์ด์ง ์ ์ ์ ๋ฐ๋ก UI๊ฐ ๋ณด์ด๋๋ก ํฉ๋๋ค. | |
app = gr.mount_gradio_app(app, demo, path="/") | |
# FastAPI ๊ธฐ๋ณธ ์๋ํฌ์ธํธ (์ ํ ์ฌํญ, Gradio ์ฑ์ด ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ฅผ ์ ์ ํจ) | |
# ์ด ์๋ํฌ์ธํธ๋ /api ๊ฒฝ๋ก๋ก ์ ์ํ์ ๋๋ง ์๋ํฉ๋๋ค. | |
def read_root(): | |
return {"message": "Welcome to the Face Depth Map Extractor! Visit / for the UI."} |