muk42 commited on
Commit
9531418
·
1 Parent(s): 027526f

marginalized blobs with marginalized tiles

Browse files
inference_tab/helpers.py CHANGED
@@ -235,15 +235,12 @@ def processYOLOBoxes(iou):
235
  boxes_full = [b["bbox"] for b in box_data] # Format: [x1, y1, x2, y2]
236
  return boxes_full
237
 
238
- def prepare_tiles(image_path, boxes_full, tile_size=1024, overlap=50, iou=0.5, c_th=0.75, edge_margin=10, tile_margin=300):
239
  """
240
  Tiles the image and prepares per-tile metadata including filtered boxes and point prompts.
241
  Returns full image size H, W.
242
  """
243
 
244
- full_img = cv2.imread(image_path)
245
- H_full, W_full, _ = full_img.shape
246
-
247
  tiles, (H, W, _) = tile_image_with_overlap(image_path, tile_size, overlap)
248
  os.makedirs("tmp/tiles", exist_ok=True)
249
  meta = []
@@ -253,14 +250,6 @@ def prepare_tiles(image_path, boxes_full, tile_size=1024, overlap=50, iou=0.5, c
253
  tile_array = cv2.cvtColor(tile_array, cv2.COLOR_BGR2RGB)
254
  Image.fromarray(tile_array).save(tile_path)
255
 
256
- my1 = max(0, y_offset - tile_margin)
257
- my2 = min(H_full, y_offset + tile_size + tile_margin)
258
- mx1 = max(0, x_offset - tile_margin)
259
- mx2 = min(W_full, x_offset + tile_size + tile_margin)
260
- tile_with_margin = full_img[my1:my2, mx1:mx2]
261
- cv2.imwrite(f"tiles/tile_{idx}_margin.png", tile_with_margin)
262
-
263
-
264
  tile_h, tile_w, _ = tile_array.shape
265
 
266
  # Select boxes overlapping this tile
@@ -342,7 +331,6 @@ def prepare_tiles(image_path, boxes_full, tile_size=1024, overlap=50, iou=0.5, c
342
 
343
 
344
 
345
-
346
  def merge_tile_masks(H, W):
347
  """
348
  Merge predicted tile masks into a full-size image.
 
235
  boxes_full = [b["bbox"] for b in box_data] # Format: [x1, y1, x2, y2]
236
  return boxes_full
237
 
238
+ def prepare_tiles(image_path, boxes_full, tile_size=1024, overlap=256, iou=0.5, c_th=0.75, edge_margin=10):
239
  """
240
  Tiles the image and prepares per-tile metadata including filtered boxes and point prompts.
241
  Returns full image size H, W.
242
  """
243
 
 
 
 
244
  tiles, (H, W, _) = tile_image_with_overlap(image_path, tile_size, overlap)
245
  os.makedirs("tmp/tiles", exist_ok=True)
246
  meta = []
 
250
  tile_array = cv2.cvtColor(tile_array, cv2.COLOR_BGR2RGB)
251
  Image.fromarray(tile_array).save(tile_path)
252
 
 
 
 
 
 
 
 
 
253
  tile_h, tile_w, _ = tile_array.shape
254
 
255
  # Select boxes overlapping this tile
 
331
 
332
 
333
 
 
334
  def merge_tile_masks(H, W):
335
  """
336
  Merge predicted tile masks into a full-size image.
inference_tab/inference_logic.py CHANGED
@@ -37,11 +37,12 @@ _trocr_device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
37
 
38
 
39
 
 
40
  def run_inference(tile_dict, gcp_path,user_crs, city_name, score_th, hist_th, hist_dic):
41
  IMAGE_FOLDER = os.path.join(OUTPUT_DIR, "blobs")
42
  CSV_FILE = os.path.join(OUTPUT_DIR, "annotations.csv")
43
  MASK_FILE = os.path.join(OUTPUT_DIR, "mask.tif")
44
-
45
 
46
  if os.path.exists(IMAGE_FOLDER):
47
  shutil.rmtree(IMAGE_FOLDER)
@@ -89,7 +90,7 @@ def run_inference(tile_dict, gcp_path,user_crs, city_name, score_th, hist_th, hi
89
  if stop_pipeline:
90
  yield log + "Pipeline stopped: no text segments found.\n", None
91
  return
92
-
93
  for msg in extractSegments(image_path):
94
  log += msg + "\n"
95
  yield log, None
@@ -275,7 +276,7 @@ def getSegments(image_path,iou=0.5,c_th=0.75,edge_margin=10):
275
  with open(BOXES_PATH, "r") as f:
276
  box_data = json.load(f)
277
  boxes = [b["bbox"] for b in box_data]
278
- yield "Prepare tiles..."
279
  H,W = prepare_tiles(image_path, boxes, tile_size=1024, overlap=50, iou=iou, c_th=c_th, edge_margin=edge_margin)
280
  yield "Run inference on tiles..."
281
  for msg in run_tile_inference():
@@ -283,23 +284,16 @@ def getSegments(image_path,iou=0.5,c_th=0.75,edge_margin=10):
283
  if "Stopping inference" in msg:
284
  yield "No labels detected – halting getSegments."
285
  return
286
- yield "Marge predicted masks into image..."
287
  merge_tile_masks(H,W)
288
 
289
  MASK_PATH = os.path.join(OUTPUT_DIR,"mask.tif")
290
  yield f"{MASK_PATH}"
291
-
292
 
293
 
294
  def extractSegments(image_path, min_size=500, margin=150):
295
  image = cv2.imread(image_path)
296
 
297
- margin_path = image_path.replace(".png", "_margin.png")
298
- image_margin_tile = cv2.imread(margin_path)
299
- if image_margin_tile is None:
300
- yield f"Error: Could not load margin tile at {margin_path}"
301
-
302
-
303
  MASK_PATH = os.path.join(OUTPUT_DIR, "mask.tif")
304
  mask = cv2.imread(MASK_PATH, cv2.IMREAD_UNCHANGED)
305
 
@@ -337,22 +331,47 @@ def extractSegments(image_path, min_size=500, margin=150):
337
  y_max_m = min(height, y_max + margin)
338
 
339
  cropped_image_margin = image[y_min_m:y_max_m, x_min_m:x_max_m]
340
- cropped_mask_margin = blob_mask[y_min_m:y_max_m, x_min_m:x_max_m]'''
341
-
342
- cropped_image_margin = image_margin_tile[y_min : y_max + 2*margin,
343
- x_min : x_max + 2*margin]
344
- cropped_mask_margin = np.zeros(cropped_image_margin.shape[:2], dtype=np.uint8)
345
- cropped_mask_margin[margin : margin + (y_max-y_min),
346
- margin : margin + (x_max-x_min)] = blob_mask[y_min:y_max, x_min:x_max]
347
 
348
  shaded_margin = cropped_image_margin.copy()
349
  overlay_margin = cropped_image_margin.copy()
350
  overlay_margin[cropped_mask_margin == 1] = (255, 200, 100)
351
  shaded_margin = cv2.addWeighted(overlay_margin, 0.35, shaded_margin, 0.65, 0)
352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  BLOB_PATH_MARGIN = os.path.join(OUTPUT_DIR, "blobs", f"{blob_id}_margin.png")
354
  cv2.imwrite(BLOB_PATH_MARGIN, shaded_margin)
355
 
 
356
  yield f"Done."
357
 
358
 
 
37
 
38
 
39
 
40
+
41
  def run_inference(tile_dict, gcp_path,user_crs, city_name, score_th, hist_th, hist_dic):
42
  IMAGE_FOLDER = os.path.join(OUTPUT_DIR, "blobs")
43
  CSV_FILE = os.path.join(OUTPUT_DIR, "annotations.csv")
44
  MASK_FILE = os.path.join(OUTPUT_DIR, "mask.tif")
45
+
46
 
47
  if os.path.exists(IMAGE_FOLDER):
48
  shutil.rmtree(IMAGE_FOLDER)
 
90
  if stop_pipeline:
91
  yield log + "Pipeline stopped: no text segments found.\n", None
92
  return
93
+
94
  for msg in extractSegments(image_path):
95
  log += msg + "\n"
96
  yield log, None
 
276
  with open(BOXES_PATH, "r") as f:
277
  box_data = json.load(f)
278
  boxes = [b["bbox"] for b in box_data]
279
+ yield f"Prepare tiles for {image_path}..."
280
  H,W = prepare_tiles(image_path, boxes, tile_size=1024, overlap=50, iou=iou, c_th=c_th, edge_margin=edge_margin)
281
  yield "Run inference on tiles..."
282
  for msg in run_tile_inference():
 
284
  if "Stopping inference" in msg:
285
  yield "No labels detected – halting getSegments."
286
  return
287
+ yield "Merge predicted masks into image..."
288
  merge_tile_masks(H,W)
289
 
290
  MASK_PATH = os.path.join(OUTPUT_DIR,"mask.tif")
291
  yield f"{MASK_PATH}"
 
292
 
293
 
294
  def extractSegments(image_path, min_size=500, margin=150):
295
  image = cv2.imread(image_path)
296
 
 
 
 
 
 
 
297
  MASK_PATH = os.path.join(OUTPUT_DIR, "mask.tif")
298
  mask = cv2.imread(MASK_PATH, cv2.IMREAD_UNCHANGED)
299
 
 
331
  y_max_m = min(height, y_max + margin)
332
 
333
  cropped_image_margin = image[y_min_m:y_max_m, x_min_m:x_max_m]
334
+ cropped_mask_margin = blob_mask[y_min_m:y_max_m, x_min_m:x_max_m]
 
 
 
 
 
 
335
 
336
  shaded_margin = cropped_image_margin.copy()
337
  overlay_margin = cropped_image_margin.copy()
338
  overlay_margin[cropped_mask_margin == 1] = (255, 200, 100)
339
  shaded_margin = cv2.addWeighted(overlay_margin, 0.35, shaded_margin, 0.65, 0)
340
 
341
+ BLOB_PATH_MARGIN = os.path.join(OUTPUT_DIR, "blobs", f"{blob_id}_margin.png")
342
+ cv2.imwrite(BLOB_PATH_MARGIN, shaded_margin)'''
343
+
344
+ # ---- MARGINALIZED NEW (with mask/shading) ----
345
+ base, ext = os.path.splitext(image_path)
346
+ margin_tile_path = f"{base}_margin{ext}"
347
+ margin_img = cv2.imread(margin_tile_path)
348
+ h_m, w_m = margin_img.shape[:2]
349
+
350
+ x1_m = max(0, x_min)
351
+ y1_m = max(0, y_min)
352
+ x2_m = min(w_m, x_max + (2 * margin))
353
+ y2_m = min(h_m, y_max + (2 * margin))
354
+ cropped = margin_img[y1_m:y2_m, x1_m:x2_m]
355
+
356
+ padded_blob_mask = cv2.copyMakeBorder(
357
+ blob_mask,
358
+ margin, margin, margin, margin,
359
+ borderType=cv2.BORDER_CONSTANT,
360
+ value=0
361
+ )
362
+
363
+ cropped_mask = padded_blob_mask[y1_m:y2_m, x1_m:x2_m]
364
+
365
+ shaded_margin = cropped.copy()
366
+ overlay_margin = cropped.copy()
367
+
368
+ overlay_margin[cropped_mask == 1] = (255, 200, 100)
369
+ shaded_margin = cv2.addWeighted(overlay_margin, 0.35, shaded_margin, 0.65, 0)
370
+
371
  BLOB_PATH_MARGIN = os.path.join(OUTPUT_DIR, "blobs", f"{blob_id}_margin.png")
372
  cv2.imwrite(BLOB_PATH_MARGIN, shaded_margin)
373
 
374
+
375
  yield f"Done."
376
 
377
 
inference_tab/inference_setup.py CHANGED
@@ -5,6 +5,7 @@ from PIL import Image
5
  import os
6
 
7
  TILE_SIZE = 1024
 
8
  TILE_FOLDER = "tiles"
9
  os.makedirs(TILE_FOLDER, exist_ok=True)
10
  tiles_cache = {"tiles": [], "selected_tile": None}
@@ -29,13 +30,27 @@ def make_tiles(image, tile_size=TILE_SIZE):
29
  def create_tiles(image_file):
30
  img = Image.open(image_file.name).convert("RGB")
31
  img = np.array(img)
 
32
 
33
  annotated, tiles = make_tiles(img, TILE_SIZE)
34
  tiles_cache["tiles"] = []
35
 
36
  for idx, (coords, tile) in enumerate(tiles):
 
 
37
  tile_path = os.path.join(TILE_FOLDER, f"tile_{idx}.png")
38
  Image.fromarray(tile).save(tile_path)
 
 
 
 
 
 
 
 
 
 
 
39
  tiles_cache["tiles"].append((coords, tile_path)) # store path instead of array
40
 
41
  tiles_cache["selected_tile"] = None
 
5
  import os
6
 
7
  TILE_SIZE = 1024
8
+ MARGIN_TILE = 150
9
  TILE_FOLDER = "tiles"
10
  os.makedirs(TILE_FOLDER, exist_ok=True)
11
  tiles_cache = {"tiles": [], "selected_tile": None}
 
30
  def create_tiles(image_file):
31
  img = Image.open(image_file.name).convert("RGB")
32
  img = np.array(img)
33
+ H, W, _ = img.shape
34
 
35
  annotated, tiles = make_tiles(img, TILE_SIZE)
36
  tiles_cache["tiles"] = []
37
 
38
  for idx, (coords, tile) in enumerate(tiles):
39
+ x, y, x_end, y_end = coords
40
+
41
  tile_path = os.path.join(TILE_FOLDER, f"tile_{idx}.png")
42
  Image.fromarray(tile).save(tile_path)
43
+
44
+ # Marginalized tile
45
+ x_m = max(0, x - MARGIN_TILE)
46
+ y_m = max(0, y - MARGIN_TILE)
47
+ x_end_m = min(W, x_end + MARGIN_TILE)
48
+ y_end_m = min(H, y_end + MARGIN_TILE)
49
+ tile_margin = img[y_m:y_end_m, x_m:x_end_m]
50
+ tile_margin_path = os.path.join(TILE_FOLDER, f"tile_{idx}_margin.png")
51
+ Image.fromarray(tile_margin).save(tile_margin_path)
52
+
53
+
54
  tiles_cache["tiles"].append((coords, tile_path)) # store path instead of array
55
 
56
  tiles_cache["selected_tile"] = None