wuhp commited on
Commit
bdfc440
·
verified ·
1 Parent(s): af85bba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -65
app.py CHANGED
@@ -3,7 +3,7 @@ import json
3
  import random
4
  import shutil
5
  import tempfile
6
- import time # ← added for polling
7
  from urllib.parse import urlparse
8
 
9
  import cv2
@@ -32,11 +32,11 @@ def convert_seg_to_bbox(api_key: str, dataset_url: str, split_ratios=(0.8, 0.1,
32
  3) Split into train/valid/test
33
  4) Return before/after visuals plus (dataset_path, detection_slug)
34
  """
35
- rf = Roboflow(api_key=api_key)
36
  ws, proj_name, ver = parse_roboflow_url(dataset_url)
37
- version_obj = rf.workspace(ws).project(proj_name).version(ver)
38
- dataset = version_obj.download("coco-segmentation")
39
- root = dataset.location
40
 
41
  # find the COCO JSON
42
  ann_file = None
@@ -50,9 +50,9 @@ def convert_seg_to_bbox(api_key: str, dataset_url: str, split_ratios=(0.8, 0.1,
50
  if not ann_file:
51
  raise FileNotFoundError(f"No JSON found under {root}")
52
 
53
- coco = json.load(open(ann_file, 'r'))
54
  images_info = {img['id']: img for img in coco['images']}
55
- cat_ids = sorted(c['id'] for c in coco.get('categories', []))
56
  id_to_index = {cid: idx for idx, cid in enumerate(cat_ids)}
57
 
58
  # build YOLO bboxes
@@ -71,13 +71,8 @@ def convert_seg_to_bbox(api_key: str, dataset_url: str, split_ratios=(0.8, 0.1,
71
  )
72
  annos.setdefault(img_id, []).append(line)
73
 
74
- # copy and write out flat images + labels
75
  out_root = tempfile.mkdtemp(prefix="yolov8_")
76
- flat_img = os.path.join(out_root, "flat_images")
77
- flat_lbl = os.path.join(out_root, "flat_labels")
78
- os.makedirs(flat_img, exist_ok=True)
79
- os.makedirs(flat_lbl, exist_ok=True)
80
-
81
  name_to_id = {img['file_name']: img['id'] for img in coco['images']}
82
  file_paths = {
83
  f: os.path.join(dp, f)
@@ -86,17 +81,8 @@ def convert_seg_to_bbox(api_key: str, dataset_url: str, split_ratios=(0.8, 0.1,
86
  if f in name_to_id
87
  }
88
 
89
- for fname, img_id in name_to_id.items():
90
- src = file_paths.get(fname)
91
- if not src:
92
- continue
93
- shutil.copy(src, os.path.join(flat_img, fname))
94
- lbl_path = os.path.join(flat_lbl, fname.rsplit('.',1)[0] + ".txt")
95
- with open(lbl_path, 'w') as lf:
96
- lf.write("\n".join(annos.get(img_id, [])))
97
-
98
- # split filenames
99
- all_files = [f for f in os.listdir(flat_img) if f.lower().endswith(('.jpg','.png','.jpeg'))]
100
  random.shuffle(all_files)
101
  n = len(all_files)
102
  n_train = max(1, int(n * split_ratios[0]))
@@ -108,27 +94,26 @@ def convert_seg_to_bbox(api_key: str, dataset_url: str, split_ratios=(0.8, 0.1,
108
  "test": all_files[n_train+n_valid:]
109
  }
110
 
111
- # move into final folder structure
112
  for split, files in splits.items():
113
- img_dir = os.path.join(out_root, "images", split)
114
- lbl_dir = os.path.join(out_root, "labels", split)
115
  os.makedirs(img_dir, exist_ok=True)
116
  os.makedirs(lbl_dir, exist_ok=True)
117
- for fn in files:
118
- shutil.move(os.path.join(flat_img, fn), os.path.join(img_dir, fn))
119
- lbl = fn.rsplit('.',1)[0] + ".txt"
120
- shutil.move(os.path.join(flat_lbl, lbl), os.path.join(lbl_dir, lbl))
121
-
122
- shutil.rmtree(flat_img)
123
- shutil.rmtree(flat_lbl)
124
-
125
- # prepare a few before/after images for display
126
  before, after = [], []
127
- sample = random.sample(list(name_to_id.keys()), min(5, len(name_to_id)))
128
  for fname in sample:
129
  img = cv2.cvtColor(cv2.imread(file_paths[fname]), cv2.COLOR_BGR2RGB)
130
 
131
- # original segmentation overlay
132
  seg_vis = img.copy()
133
  for anno in coco['annotations']:
134
  if anno['image_id'] != name_to_id[fname]:
@@ -136,7 +121,6 @@ def convert_seg_to_bbox(api_key: str, dataset_url: str, split_ratios=(0.8, 0.1,
136
  pts = np.array(anno['segmentation'][0], np.int32).reshape(-1,2)
137
  cv2.polylines(seg_vis, [pts], True, (255,0,0), 2)
138
 
139
- # bbox overlay
140
  box_vis = img.copy()
141
  for line in annos.get(name_to_id[fname], []):
142
  _, cxn, cyn, wnorm, hnorm = map(float, line.split())
@@ -168,7 +152,7 @@ def upload_and_train_detection(
168
  rf = Roboflow(api_key=api_key)
169
  ws = rf.workspace()
170
 
171
- # 1) get-or-create project
172
  try:
173
  proj = ws.project(detection_slug)
174
  except Exception as e:
@@ -182,7 +166,7 @@ def upload_and_train_detection(
182
  else:
183
  raise
184
 
185
- # 2) extract real slug from proj.id and upload
186
  _, real_slug = proj.id.rsplit("/", 1)
187
  ws.upload_dataset(
188
  dataset_path,
@@ -191,16 +175,12 @@ def upload_and_train_detection(
191
  project_type=project_type
192
  )
193
 
194
- # 3) generate a new version
195
  try:
196
- version_num = proj.generate_version(settings={
197
- "augmentation": {},
198
- "preprocessing": {}
199
- })
200
  except RuntimeError as e:
201
  msg = str(e).lower()
202
  if "unsupported request" in msg or "does not exist" in msg:
203
- # bump slug and retry
204
  new_slug = real_slug + "-v2"
205
  proj = ws.create_project(
206
  new_slug,
@@ -208,20 +188,14 @@ def upload_and_train_detection(
208
  project_type=project_type,
209
  project_license=project_license
210
  )
211
- ws.upload_dataset(
212
- dataset_path,
213
- new_slug,
214
- project_license=project_license,
215
- project_type=project_type
216
- )
217
- version_num = proj.generate_version(settings={
218
- "augmentation": {},
219
- "preprocessing": {}
220
- })
221
  else:
222
  raise
223
 
224
- # 4) wait until the dataset version is done generating, then train
225
  for _ in range(20):
226
  try:
227
  model = proj.version(str(version_num)).train()
@@ -241,12 +215,12 @@ def upload_and_train_detection(
241
  with gr.Blocks() as app:
242
  gr.Markdown("## 🔄 Seg→BBox + Auto‑Upload/Train")
243
 
244
- api_input = gr.Textbox(label="Roboflow API Key", type="password")
245
- url_input = gr.Textbox(label="Segmentation Dataset URL")
246
- run_btn = gr.Button("Convert to BBoxes")
247
- before_g = gr.Gallery(columns=5, label="Before")
248
- after_g = gr.Gallery(columns=5, label="After")
249
- ds_state = gr.Textbox(visible=False, label="Converted Dataset Path")
250
  slug_state = gr.Textbox(visible=False, label="Detection Project Slug")
251
 
252
  run_btn.click(
@@ -257,7 +231,7 @@ with gr.Blocks() as app:
257
 
258
  gr.Markdown("## 🚀 Upload & Train Detection Model")
259
  train_btn = gr.Button("Upload & Train")
260
- url_out = gr.Textbox(label="Hosted Model Endpoint URL")
261
 
262
  train_btn.click(
263
  upload_and_train_detection,
 
3
  import random
4
  import shutil
5
  import tempfile
6
+ import time
7
  from urllib.parse import urlparse
8
 
9
  import cv2
 
32
  3) Split into train/valid/test
33
  4) Return before/after visuals plus (dataset_path, detection_slug)
34
  """
35
+ rf = Roboflow(api_key=api_key)
36
  ws, proj_name, ver = parse_roboflow_url(dataset_url)
37
+ version_obj = rf.workspace(ws).project(proj_name).version(ver)
38
+ dataset = version_obj.download("coco-segmentation")
39
+ root = dataset.location
40
 
41
  # find the COCO JSON
42
  ann_file = None
 
50
  if not ann_file:
51
  raise FileNotFoundError(f"No JSON found under {root}")
52
 
53
+ coco = json.load(open(ann_file, 'r'))
54
  images_info = {img['id']: img for img in coco['images']}
55
+ cat_ids = sorted(c['id'] for c in coco.get('categories', []))
56
  id_to_index = {cid: idx for idx, cid in enumerate(cat_ids)}
57
 
58
  # build YOLO bboxes
 
71
  )
72
  annos.setdefault(img_id, []).append(line)
73
 
74
+ # prepare temporary split folder
75
  out_root = tempfile.mkdtemp(prefix="yolov8_")
 
 
 
 
 
76
  name_to_id = {img['file_name']: img['id'] for img in coco['images']}
77
  file_paths = {
78
  f: os.path.join(dp, f)
 
81
  if f in name_to_id
82
  }
83
 
84
+ # determine splits
85
+ all_files = list(name_to_id.keys())
 
 
 
 
 
 
 
 
 
86
  random.shuffle(all_files)
87
  n = len(all_files)
88
  n_train = max(1, int(n * split_ratios[0]))
 
94
  "test": all_files[n_train+n_valid:]
95
  }
96
 
97
+ # create Roboflow‐style folders
98
  for split, files in splits.items():
99
+ img_dir = os.path.join(out_root, split, "images")
100
+ lbl_dir = os.path.join(out_root, split, "labels")
101
  os.makedirs(img_dir, exist_ok=True)
102
  os.makedirs(lbl_dir, exist_ok=True)
103
+ for fname in files:
104
+ # copy image
105
+ shutil.copy(file_paths[fname], os.path.join(img_dir, fname))
106
+ # write label
107
+ txt = "\n".join(annos.get(name_to_id[fname], []))
108
+ with open(os.path.join(lbl_dir, fname.rsplit('.',1)[0] + ".txt"), 'w') as f:
109
+ f.write(txt)
110
+
111
+ # prepare display examples
112
  before, after = [], []
113
+ sample = random.sample(all_files, min(5, len(all_files)))
114
  for fname in sample:
115
  img = cv2.cvtColor(cv2.imread(file_paths[fname]), cv2.COLOR_BGR2RGB)
116
 
 
117
  seg_vis = img.copy()
118
  for anno in coco['annotations']:
119
  if anno['image_id'] != name_to_id[fname]:
 
121
  pts = np.array(anno['segmentation'][0], np.int32).reshape(-1,2)
122
  cv2.polylines(seg_vis, [pts], True, (255,0,0), 2)
123
 
 
124
  box_vis = img.copy()
125
  for line in annos.get(name_to_id[fname], []):
126
  _, cxn, cyn, wnorm, hnorm = map(float, line.split())
 
152
  rf = Roboflow(api_key=api_key)
153
  ws = rf.workspace()
154
 
155
+ # get-or-create project
156
  try:
157
  proj = ws.project(detection_slug)
158
  except Exception as e:
 
166
  else:
167
  raise
168
 
169
+ # upload entire split folder
170
  _, real_slug = proj.id.rsplit("/", 1)
171
  ws.upload_dataset(
172
  dataset_path,
 
175
  project_type=project_type
176
  )
177
 
178
+ # generate new version (with fallback)
179
  try:
180
+ version_num = proj.generate_version(settings={"augmentation": {}, "preprocessing": {}})
 
 
 
181
  except RuntimeError as e:
182
  msg = str(e).lower()
183
  if "unsupported request" in msg or "does not exist" in msg:
 
184
  new_slug = real_slug + "-v2"
185
  proj = ws.create_project(
186
  new_slug,
 
188
  project_type=project_type,
189
  project_license=project_license
190
  )
191
+ ws.upload_dataset(dataset_path, new_slug,
192
+ project_license=project_license,
193
+ project_type=project_type)
194
+ version_num = proj.generate_version(settings={"augmentation": {}, "preprocessing": {}})
 
 
 
 
 
 
195
  else:
196
  raise
197
 
198
+ # wait until ready, then train
199
  for _ in range(20):
200
  try:
201
  model = proj.version(str(version_num)).train()
 
215
  with gr.Blocks() as app:
216
  gr.Markdown("## 🔄 Seg→BBox + Auto‑Upload/Train")
217
 
218
+ api_input = gr.Textbox(label="Roboflow API Key", type="password")
219
+ url_input = gr.Textbox(label="Segmentation Dataset URL")
220
+ run_btn = gr.Button("Convert to BBoxes")
221
+ before_g = gr.Gallery(columns=5, label="Before")
222
+ after_g = gr.Gallery(columns=5, label="After")
223
+ ds_state = gr.Textbox(visible=False, label="Converted Dataset Path")
224
  slug_state = gr.Textbox(visible=False, label="Detection Project Slug")
225
 
226
  run_btn.click(
 
231
 
232
  gr.Markdown("## 🚀 Upload & Train Detection Model")
233
  train_btn = gr.Button("Upload & Train")
234
+ url_out = gr.Textbox(label="Hosted Model Endpoint URL")
235
 
236
  train_btn.click(
237
  upload_and_train_detection,