TK156 commited on
Commit
8217c26
·
verified ·
1 Parent(s): 7d2a98b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -91
app.py CHANGED
@@ -1,91 +1,92 @@
1
- import gradio as gr
2
- import torch
3
- from transformers import AutoImageProcessor, AutoModelForDepthEstimation
4
- import numpy as np
5
- from PIL import Image
6
- import cv2
7
- import base64
8
- import io
9
-
10
- class DepthEstimationAPI:
11
- def __init__(self):
12
- self.device = "cuda" if torch.cuda.is_available() else "cpu"
13
- print(f"Using device: {self.device}")
14
-
15
- model_name = "depth-anything/Depth-Anything-V2-Small-hf"
16
- self.processor = AutoImageProcessor.from_pretrained(model_name)
17
- self.model = AutoModelForDepthEstimation.from_pretrained(model_name)
18
- self.model.to(self.device)
19
- self.model.eval()
20
- print("Model loaded successfully")
21
-
22
- def predict(self, image_input):
23
- """Process image and return depth map"""
24
- try:
25
- # Handle different input types
26
- if isinstance(image_input, str):
27
- # Base64 encoded image
28
- if image_input.startswith('data:image'):
29
- header, encoded = image_input.split(',', 1)
30
- image_bytes = base64.b64decode(encoded)
31
- image = Image.open(io.BytesIO(image_bytes)).convert('RGB')
32
- else:
33
- # File path
34
- image = Image.open(image_input).convert('RGB')
35
- else:
36
- # PIL Image
37
- image = image_input.convert('RGB') if hasattr(image_input, 'convert') else image_input
38
-
39
- # Process image
40
- inputs = self.processor(images=image, return_tensors="pt")
41
- inputs = {k: v.to(self.device) for k, v in inputs.items()}
42
-
43
- with torch.no_grad():
44
- outputs = self.model(**inputs)
45
- depth = outputs.predicted_depth.squeeze().cpu().numpy()
46
-
47
- # Create depth visualization
48
- depth_normalized = ((depth - depth.min()) / (depth.max() - depth.min()) * 255).astype(np.uint8)
49
- depth_colored = cv2.applyColorMap(depth_normalized, cv2.COLORMAP_VIRIDIS)
50
- depth_colored = cv2.cvtColor(depth_colored, cv2.COLOR_BGR2RGB)
51
- depth_image = Image.fromarray(depth_colored)
52
-
53
- # Clean up
54
- del inputs, outputs, depth, depth_normalized, depth_colored
55
- if torch.cuda.is_available():
56
- torch.cuda.empty_cache()
57
-
58
- return [image, depth_image]
59
-
60
- except Exception as e:
61
- print(f"Error in prediction: {e}")
62
- return [None, None]
63
-
64
- # Initialize API
65
- api = DepthEstimationAPI()
66
-
67
- # Create Gradio interface with API support
68
- with gr.Blocks() as demo:
69
- gr.Markdown("# Depth Estimation API")
70
- gr.Markdown("AI-powered depth estimation using DepthAnything V2")
71
-
72
- with gr.Row():
73
- with gr.Column():
74
- input_image = gr.Image(type="pil", label="Upload Image")
75
- submit_btn = gr.Button("Generate Depth Map", variant="primary")
76
-
77
- with gr.Column():
78
- output_original = gr.Image(type="pil", label="Original Image")
79
- output_depth = gr.Image(type="pil", label="Depth Map")
80
-
81
- # Define the API endpoint
82
- submit_btn.click(
83
- fn=api.predict,
84
- inputs=input_image,
85
- outputs=[output_original, output_depth],
86
- api_name="predict" # This creates the /api/predict endpoint
87
- )
88
-
89
- # Launch with proper settings for Hugging Face Spaces
90
- if __name__ == "__main__":
91
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
 
1
+ import gradio as gr
2
+ import torch
3
+ from transformers import AutoImageProcessor,
4
+ AutoModelForDepthEstimation
5
+ import numpy as np
6
+ from PIL import Image
7
+ import cv2
8
+
9
+ class DepthEstimationAPI:
10
+ def __init__(self):
11
+ self.device = "cpu" # Hugging Face Spacesは無料版でCPUのみ
12
+ print(f"Using device: {self.device}")
13
+
14
+ model_name = "depth-anything/Depth-Anything-V2-Small-hf"
15
+ self.processor = AutoImageProcessor.from_pretrained(model_name)
16
+ self.model =
17
+ AutoModelForDepthEstimation.from_pretrained(model_name)
18
+ self.model.to(self.device)
19
+ self.model.eval()
20
+ print("Model loaded successfully")
21
+
22
+ def predict(self, image_input):
23
+ """Process image and return depth map"""
24
+ if image_input is None:
25
+ return None, None
26
+
27
+ try:
28
+ # PILイメージに変換
29
+ if hasattr(image_input, 'convert'):
30
+ image = image_input.convert('RGB')
31
+ else:
32
+ image = Image.open(image_input).convert('RGB')
33
+
34
+ # サイズ調整(メモリ節約)
35
+ max_size = 256
36
+ if max(image.size) > max_size:
37
+ ratio = max_size / max(image.size)
38
+ new_size = tuple(int(dim * ratio) for dim in
39
+ image.size)
40
+ image = image.resize(new_size,
41
+ Image.Resampling.LANCZOS)
42
+
43
+ # 深度推定
44
+ inputs = self.processor(images=image, return_tensors="pt")
45
+
46
+ with torch.no_grad():
47
+ outputs = self.model(**inputs)
48
+ depth = outputs.predicted_depth.squeeze().cpu().numpy()
49
+
50
+ # 深度マップ可視化
51
+ depth_normalized = ((depth - depth.min()) / (depth.max() -
52
+ depth.min()) * 255).astype(np.uint8)
53
+ depth_colored = cv2.applyColorMap(depth_normalized,
54
+ cv2.COLORMAP_VIRIDIS)
55
+ depth_colored = cv2.cvtColor(depth_colored,
56
+ cv2.COLOR_BGR2RGB)
57
+ depth_image = Image.fromarray(depth_colored)
58
+
59
+ return image, depth_image
60
+
61
+ except Exception as e:
62
+ print(f"Error in prediction: {e}")
63
+ return image_input, None
64
+
65
+ # APIインスタンス初期化
66
+ api = DepthEstimationAPI()
67
+
68
+ # Gradioインターフェース作成
69
+ with gr.Blocks(title="Depth Estimation API") as demo:
70
+ gr.Markdown("# 深度推定 API")
71
+ gr.Markdown("DepthAnything V2を使用したAI深度推定")
72
+
73
+ with gr.Row():
74
+ with gr.Column():
75
+ input_image = gr.Image(type="pil",
76
+ label="画像をアップロード")
77
+ submit_btn = gr.Button("深度マップ生成", variant="primary")
78
+
79
+ with gr.Column():
80
+ output_original = gr.Image(type="pil", label="元画像")
81
+ output_depth = gr.Image(type="pil", label="深度マップ")
82
+
83
+ # ボタンクリックで処理実行
84
+ submit_btn.click(
85
+ fn=api.predict,
86
+ inputs=[input_image],
87
+ outputs=[output_original, output_depth]
88
+ )
89
+
90
+ # Hugging Face Spaces用起動設定
91
+ if __name__ == "__main__":
92
+ demo.launch()