AICODER009 commited on
Commit
2ef57b0
·
verified ·
1 Parent(s): f624498

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -43
app.py CHANGED
@@ -2,44 +2,76 @@ import os
2
  import glob
3
  import shutil
4
  import tempfile
 
5
  import gradio as gr
6
  import cv2
7
  from PIL import Image
8
  from ultralytics import YOLO
9
 
10
- # Keep Ultralytics config in writable location
 
 
11
  os.environ["YOLO_CONFIG_DIR"] = "/tmp/Ultralytics"
12
 
 
 
 
13
  model = YOLO("best.pt")
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  def segment(gallery_items, conf=0.25, imgsz=640):
16
  """
17
- gallery_items from gr.Gallery(type="pil") can be:
18
- - list[dict] where dict has {"data": PIL.Image, ...}
19
- - list[PIL.Image] depending on gradio version
20
- We handle both safely.
21
  """
22
 
23
  if not gallery_items:
24
  return []
25
 
26
- # Create temp workspace
 
 
27
  workdir = tempfile.mkdtemp(prefix="yolo_seg_")
28
  src_dir = os.path.join(workdir, "src")
29
  os.makedirs(src_dir, exist_ok=True)
30
 
31
- # Save incoming images
32
- saved_paths = []
33
- for i, item in enumerate(gallery_items):
34
- img = item["data"] if isinstance(item, dict) else item
35
- out_path = os.path.join(src_dir, f"img_{i}.jpg")
36
- img.save(out_path)
37
- saved_paths.append(out_path)
38
-
39
- print(f"[DEBUG] Saved {len(saved_paths)} images to: {src_dir}")
40
-
41
  try:
42
- # Run YOLO like your notebook
 
 
 
 
 
 
 
 
 
 
43
  preds = model.predict(
44
  source=src_dir,
45
  imgsz=int(imgsz),
@@ -48,41 +80,34 @@ def segment(gallery_items, conf=0.25, imgsz=640):
48
  save=True,
49
  project=workdir,
50
  name="preds",
51
- exist_ok=True
52
  )
53
 
54
- # Ultralytics will save overlays into:
55
- # {workdir}/preds/
56
  pred_dir = os.path.join(workdir, "preds")
57
- print(f"[DEBUG] pred_dir = {pred_dir}")
58
- print(f"[DEBUG] pred_dir exists? {os.path.exists(pred_dir)}")
59
-
60
- # Find overlay images YOLO saved
61
- files = []
62
- for ext in ("*.jpg", "*.png", "*.jpeg", "*.bmp"):
63
- files.extend(glob.glob(os.path.join(pred_dir, ext)))
64
-
65
- files = sorted(files)
66
- print(f"[DEBUG] overlays found: {len(files)}")
67
- print(f"[DEBUG] sample files: {files[:5]}")
68
 
69
- # Load overlays -> PIL
 
 
70
  outputs = []
71
- for f in files:
72
- im = cv2.imread(f)
73
- if im is None:
74
- print(f"[WARN] cv2 failed to read: {f}")
75
- continue
76
- im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
77
- outputs.append(Image.fromarray(im))
78
 
79
  return outputs
80
 
81
  finally:
82
- # Cleanup temp files
83
  shutil.rmtree(workdir, ignore_errors=True)
84
 
85
 
 
 
 
86
  demo = gr.Interface(
87
  fn=segment,
88
  inputs=[
@@ -90,8 +115,14 @@ demo = gr.Interface(
90
  gr.Slider(0.01, 0.9, value=0.25, step=0.01, label="Confidence"),
91
  gr.Slider(320, 1280, value=640, step=32, label="Image size"),
92
  ],
93
- outputs=gr.Gallery(label="Predicted overlays"),
94
- title="YOLOv8 Segmentation (Multi-Image) Notebook Equivalent",
 
95
  )
96
 
97
- demo.launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False)
 
 
 
 
 
 
2
  import glob
3
  import shutil
4
  import tempfile
5
+
6
  import gradio as gr
7
  import cv2
8
  from PIL import Image
9
  from ultralytics import YOLO
10
 
11
+ # ------------------------------------------------------------------
12
+ # HF Spaces requirement: Ultralytics config must be writable
13
+ # ------------------------------------------------------------------
14
  os.environ["YOLO_CONFIG_DIR"] = "/tmp/Ultralytics"
15
 
16
+ # ------------------------------------------------------------------
17
+ # Load YOLOv8 segmentation model (best.pt in same folder)
18
+ # ------------------------------------------------------------------
19
  model = YOLO("best.pt")
20
 
21
+
22
+ def unwrap_image(item):
23
+ """
24
+ Normalize Gradio Gallery item to a PIL.Image.
25
+
26
+ Gradio Gallery may return:
27
+ - PIL.Image
28
+ - dict with {"data": PIL.Image, ...}
29
+ - tuple (e.g., (PIL.Image, metadata) or (name, PIL.Image))
30
+ """
31
+ # Case 1: dict
32
+ if isinstance(item, dict):
33
+ return item["data"]
34
+
35
+ # Case 2: tuple
36
+ if isinstance(item, tuple):
37
+ for v in item:
38
+ if hasattr(v, "save"): # PIL.Image has .save()
39
+ return v
40
+ raise ValueError("Gallery tuple does not contain a PIL image")
41
+
42
+ # Case 3: already PIL.Image
43
+ return item
44
+
45
+
46
  def segment(gallery_items, conf=0.25, imgsz=640):
47
  """
48
+ Runs YOLOv8 segmentation on multiple images using the SAME
49
+ pipeline as the training notebook: model.predict(save=True).
50
+ Returns segmentation overlays as a flat list of PIL images.
 
51
  """
52
 
53
  if not gallery_items:
54
  return []
55
 
56
+ # ------------------------------------------------------------------
57
+ # Create a temporary working directory
58
+ # ------------------------------------------------------------------
59
  workdir = tempfile.mkdtemp(prefix="yolo_seg_")
60
  src_dir = os.path.join(workdir, "src")
61
  os.makedirs(src_dir, exist_ok=True)
62
 
 
 
 
 
 
 
 
 
 
 
63
  try:
64
+ # --------------------------------------------------------------
65
+ # Save uploaded images to disk
66
+ # --------------------------------------------------------------
67
+ for i, item in enumerate(gallery_items):
68
+ img = unwrap_image(item)
69
+ out_path = os.path.join(src_dir, f"img_{i}.jpg")
70
+ img.save(out_path)
71
+
72
+ # --------------------------------------------------------------
73
+ # Run YOLO prediction (NOTEBOOK-EQUIVALENT)
74
+ # --------------------------------------------------------------
75
  preds = model.predict(
76
  source=src_dir,
77
  imgsz=int(imgsz),
 
80
  save=True,
81
  project=workdir,
82
  name="preds",
83
+ exist_ok=True,
84
  )
85
 
86
+ # YOLO saves overlays into: {workdir}/preds/
 
87
  pred_dir = os.path.join(workdir, "preds")
 
 
 
 
 
 
 
 
 
 
 
88
 
89
+ # --------------------------------------------------------------
90
+ # Load saved overlay images
91
+ # --------------------------------------------------------------
92
  outputs = []
93
+ for ext in ("*.jpg", "*.png", "*.jpeg", "*.bmp"):
94
+ for f in sorted(glob.glob(os.path.join(pred_dir, ext))):
95
+ im = cv2.imread(f)
96
+ if im is None:
97
+ continue
98
+ im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
99
+ outputs.append(Image.fromarray(im))
100
 
101
  return outputs
102
 
103
  finally:
104
+ # Always clean up temp files
105
  shutil.rmtree(workdir, ignore_errors=True)
106
 
107
 
108
+ # ------------------------------------------------------------------
109
+ # Gradio Interface (HF-safe)
110
+ # ------------------------------------------------------------------
111
  demo = gr.Interface(
112
  fn=segment,
113
  inputs=[
 
115
  gr.Slider(0.01, 0.9, value=0.25, step=0.01, label="Confidence"),
116
  gr.Slider(320, 1280, value=640, step=32, label="Image size"),
117
  ],
118
+ outputs=gr.Gallery(label="YOLOv8 Segmentation Overlays"),
119
+ title="YOLOv8 Segmentation (Hugging Face Space)",
120
+ description="Multi-image YOLOv8 segmentation using the same predict(save=True) pipeline as training.",
121
  )
122
 
123
+ # IMPORTANT: disable SSR to avoid asyncio cleanup noise on HF
124
+ demo.launch(
125
+ server_name="0.0.0.0",
126
+ server_port=7860,
127
+ ssr_mode=False,
128
+ )