Shengxiao0709 commited on
Commit
e8de836
·
verified ·
1 Parent(s): e46e94b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -96
app.py CHANGED
@@ -1,96 +1,103 @@
1
- import gradio as gr
2
- from gradio_bbox_annotator import BBoxAnnotator
3
- from PIL import Image
4
- import numpy as np
5
-
6
- # 你已有的推理代码
7
- from inference import load_model, get_embedding, run
8
-
9
- # ---- 仅加载一次模型 ----
10
- model, device = load_model("medsam_vit_b.pth")
11
- def predict(value):
12
- # value: (image_path, [(xmin, ymin, xmax, ymax, label), ...])
13
- return value # 直接回显
14
-
15
- def make_example(path):
16
- return [path, []]
17
-
18
- def parse_first_bbox(bboxes):
19
- """
20
- 从 annot 的 bboxes 里取第一个框,返回 (xmin, ymin, xmax, ymax)
21
- 兼容两种格式:
22
- - dict: {"x":..,"y":..,"width":..,"height":..}
23
- - list: [xmin, ymin, xmax, ymax, ...]
24
- """
25
- if not bboxes:
26
- return None
27
- b = bboxes[0]
28
- if isinstance(b, dict):
29
- x, y = float(b["x"]), float(b["y"])
30
- w, h = float(b["width"]), float(b["height"])
31
- return x, y, x + w, y + h
32
- if isinstance(b, (list, tuple)) and len(b) >= 4:
33
- return float(b[0]), float(b[1]), float(b[2]), float(b[3])
34
- return None
35
-
36
- def segment(annot_value):
37
- """
38
- annot_value 形如 [image_path, bboxes]
39
- - image_path: 字符串
40
- - bboxes: 框列表
41
- """
42
- if annot_value is None or len(annot_value) < 1:
43
- return None, "请先在上方上传图片并拖一个矩形框。"
44
-
45
- img_path = annot_value[0]
46
- bboxes = annot_value[1] if len(annot_value) > 1 else []
47
-
48
- if not bboxes:
49
- return None, "未检测到矩形框,请在标注区按住左键拖拽一个框。"
50
-
51
- # 读取图片
52
- img = Image.open(img_path).convert("RGB")
53
- img_np = np.array(img)
54
- H, W, _ = img_np.shape
55
-
56
- # 取第一个框
57
- box = parse_first_bbox(bboxes)
58
- if box is None:
59
- return None, "解析矩形框失败,请重画。"
60
-
61
- xmin, ymin, xmax, ymax = box
62
-
63
- # 归一化到 1024 并推理
64
- box_np = np.array([[xmin, ymin, xmax, ymax]], dtype=float)
65
- box_1024 = box_np / np.array([W, H, W, H]) * 1024.0
66
-
67
- embedding = get_embedding(model, img_np, device)
68
- mask = run(model, embedding, box_1024, H, W) # (H, W) 0/1
69
-
70
- # 黑白 mask(白=前景)
71
- mask_rgb = np.stack([mask * 255] * 3, axis=-1).astype(np.uint8)
72
- bbox_text = f"xmin={int(xmin)}, ymin={int(ymin)}, xmax={int(xmax)}, ymax={int(ymax)}"
73
-
74
- return Image.fromarray(mask_rgb), bbox_text
75
-
76
- # --- 构造一个可用的示例值(让画布里有图可直接拖) ---
77
- example = ("003_img.png", [(50, 60, 120, 150, "cell")])
78
-
79
- demo = gr.Interface(
80
- fn=segment, # ← 调你的推理函数
81
- inputs=BBoxAnnotator(
82
- value=example, # 默认示例;组件里自带“上传”按钮,可以换图
83
- categories=["cell", "nucleus"],
84
- label="upload"
85
- ),
86
- outputs=[
87
- gr.Image(type="pil", label="Mask result"),
88
- gr.Textbox(label="location")
89
- ],
90
- examples=[[example]],
91
- cache_examples=False
92
- )
93
-
94
- if __name__ == "__main__":
95
- demo.launch(server_port=7860)
96
-
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from gradio_bbox_annotator import BBoxAnnotator
3
+ from PIL import Image
4
+ import numpy as np
5
+
6
+ # 你已有的推理代码
7
+ from inference import load_model, get_embedding, run
8
+
9
+ # ---- 仅加载一次模型 ----
10
+ model, device = load_model("medsam_vit_b.pth")
11
+ def predict(value):
12
+ # value: (image_path, [(xmin, ymin, xmax, ymax, label), ...])
13
+ return value # 直接回显
14
+
15
+ def make_example(path):
16
+ return [path, []]
17
+
18
+ def parse_first_bbox(bboxes):
19
+ """
20
+ 从 annot 的 bboxes 里取第一个框,返回 (xmin, ymin, xmax, ymax)
21
+ 兼容两种格式:
22
+ - dict: {"x":..,"y":..,"width":..,"height":..}
23
+ - list: [xmin, ymin, xmax, ymax, ...]
24
+ """
25
+ if not bboxes:
26
+ return None
27
+ b = bboxes[0]
28
+ if isinstance(b, dict):
29
+ x, y = float(b["x"]), float(b["y"])
30
+ w, h = float(b["width"]), float(b["height"])
31
+ return x, y, x + w, y + h
32
+ if isinstance(b, (list, tuple)) and len(b) >= 4:
33
+ return float(b[0]), float(b[1]), float(b[2]), float(b[3])
34
+ return None
35
+
36
+ def segment(annot_value):
37
+ """
38
+ annot_value 形如 [image_path, bboxes]
39
+ - image_path: 字符串
40
+ - bboxes: 框列表
41
+ """
42
+ if annot_value is None or len(annot_value) < 1:
43
+ return None, "请先在上方上传图片并拖一个矩形框。"
44
+
45
+ img_path = annot_value[0]
46
+ bboxes = annot_value[1] if len(annot_value) > 1 else []
47
+
48
+ if not bboxes:
49
+ return None, "未检测到矩形框,请在标注区按住左键拖拽一个框。"
50
+
51
+ # 读取图片
52
+ img = Image.open(img_path).convert("RGB")
53
+ img_np = np.array(img)
54
+ H, W, _ = img_np.shape
55
+
56
+ # 取第一个框
57
+ box = parse_first_bbox(bboxes)
58
+ if box is None:
59
+ return None, "解析矩形框失败,请重画。"
60
+
61
+ xmin, ymin, xmax, ymax = box
62
+
63
+ # 归一化到 1024 并推理
64
+ box_np = np.array([[xmin, ymin, xmax, ymax]], dtype=float)
65
+ box_1024 = box_np / np.array([W, H, W, H]) * 1024.0
66
+
67
+ embedding = get_embedding(model, img_np, device)
68
+ mask = run(model, embedding, box_1024, H, W) # (H, W) 0/1
69
+
70
+ # 黑白 mask(白=前景)
71
+ mask_rgb = np.stack([mask * 255] * 3, axis=-1).astype(np.uint8)
72
+ bbox_text = f"xmin={int(xmin)}, ymin={int(ymin)}, xmax={int(xmax)}, ymax={int(ymax)}"
73
+
74
+ return Image.fromarray(mask_rgb), bbox_text
75
+
76
+ # --- 构造一个可用的示例值(让画布里有图可直接拖) ---
77
+ example = ("003_img.png", [(50, 60, 120, 150, "cell")])
78
+
79
+ demo = gr.Interface(
80
+ fn=segment, # ← 调你的推理函数
81
+ inputs=BBoxAnnotator(
82
+ value=example, # 默认示例;组件里自带“上传”按钮,可以换图
83
+ categories=["cell", "nucleus"],
84
+ label="upload"
85
+ ),
86
+ outputs=[
87
+ gr.Image(type="pil", label="Mask result"),
88
+ gr.Textbox(label="location")
89
+ ],
90
+ examples=[[example]],
91
+ cache_examples=False
92
+ )
93
+
94
+ if __name__ == "__main__":
95
+ demo.queue(concurrency_count=2).launch(
96
+ server_name="0.0.0.0",
97
+ server_port=7860,
98
+ share=False, # 不需要 public link,HF 会自动映射
99
+ show_error=True,
100
+ ssr_mode=False # 关闭 SSR(这个是触发崩溃的常见元凶)
101
+ )
102
+
103
+