dragonSwing commited on
Commit
294db91
1 Parent(s): 9c55eca

Fix bool conversion error

Browse files
Files changed (2) hide show
  1. annotate_anything.py +54 -5
  2. app.py +12 -7
annotate_anything.py CHANGED
@@ -1,9 +1,11 @@
1
  import argparse
 
2
  import json
3
  import os
4
  import sys
5
  import tempfile
6
 
 
7
  import numpy as np
8
  import supervision as sv
9
  from groundingdino.util.inference import Model as DinoModel
@@ -33,6 +35,8 @@ def process(
33
  box_threshold,
34
  text_threshold,
35
  iou_threshold,
 
 
36
  device="cuda",
37
  output_dir=None,
38
  save_ann=True,
@@ -49,6 +53,7 @@ def process(
49
  image = Image.open(image_path)
50
  image_pil = image.convert("RGB")
51
  image = np.array(image_pil)
 
52
 
53
  # Extract image metadata
54
  filename = os.path.basename(image_path)
@@ -101,27 +106,51 @@ def process(
101
 
102
  # Segmentation
103
  if task in ["auto", "segment"]:
 
 
 
104
  if detections:
105
  masks, scores = segment(
106
- sam_predictor, image=image, boxes=detections.xyxy
107
  )
 
 
 
 
 
 
 
 
 
108
  detections.mask = masks
 
 
 
109
  else:
110
- masks = sam_automask_generator.generate(image)
111
  sorted_generated_masks = sorted(
112
  masks, key=lambda x: x["area"], reverse=True
113
  )
114
 
115
  xywh = np.array([mask["bbox"] for mask in sorted_generated_masks])
116
- mask = np.array(
117
- [mask["segmentation"] for mask in sorted_generated_masks]
118
- )
119
  scores = np.array(
120
  [mask["predicted_iou"] for mask in sorted_generated_masks]
121
  )
 
 
 
 
 
 
 
 
 
 
 
122
  detections = sv.Detections(
123
  xyxy=xywh_to_xyxy(boxes_xywh=xywh), mask=mask
124
  )
 
125
 
126
  # Save annotated image
127
  if output_dir and save_ann:
@@ -138,6 +167,13 @@ def process(
138
  np.save(mask_enc_path, res)
139
  metadata["assets"]["mask_enc"] = mask_enc_path
140
 
 
 
 
 
 
 
 
141
  annotated_image_path = os.path.join(
142
  output_dir, basename + "_annotate.png"
143
  )
@@ -372,6 +408,19 @@ if __name__ == "__main__":
372
  parser.add_argument(
373
  "--iou-threshold", type=float, default=0.5, help="iou threshold"
374
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
375
 
376
  parser.add_argument(
377
  "--no-save-ann",
 
1
  import argparse
2
+ import functools
3
  import json
4
  import os
5
  import sys
6
  import tempfile
7
 
8
+ import cv2
9
  import numpy as np
10
  import supervision as sv
11
  from groundingdino.util.inference import Model as DinoModel
 
35
  box_threshold,
36
  text_threshold,
37
  iou_threshold,
38
+ kernel_size=2,
39
+ expand_mask=False,
40
  device="cuda",
41
  output_dir=None,
42
  save_ann=True,
 
53
  image = Image.open(image_path)
54
  image_pil = image.convert("RGB")
55
  image = np.array(image_pil)
56
+ orig_image = image.copy()
57
 
58
  # Extract image metadata
59
  filename = os.path.basename(image_path)
 
106
 
107
  # Segmentation
108
  if task in ["auto", "segment"]:
109
+ kernel = cv2.getStructuringElement(
110
+ cv2.MORPH_ELLIPSE, (2 * kernel_size + 1, 2 * kernel_size + 1)
111
+ )
112
  if detections:
113
  masks, scores = segment(
114
+ sam_predictor, image=orig_image, boxes=detections.xyxy
115
  )
116
+ if expand_mask:
117
+ masks = [
118
+ cv2.dilate(mask.astype(np.uint8), kernel) for mask in masks
119
+ ]
120
+ else:
121
+ masks = [
122
+ cv2.morphologyEx(mask.astype(np.uint8), cv2.MORPH_CLOSE, kernel)
123
+ for mask in masks
124
+ ]
125
  detections.mask = masks
126
+ binary_mask = functools.reduce(
127
+ lambda x, y: x + y, detections.mask
128
+ ).astype(np.bool)
129
  else:
130
+ masks = sam_automask_generator.generate(orig_image)
131
  sorted_generated_masks = sorted(
132
  masks, key=lambda x: x["area"], reverse=True
133
  )
134
 
135
  xywh = np.array([mask["bbox"] for mask in sorted_generated_masks])
 
 
 
136
  scores = np.array(
137
  [mask["predicted_iou"] for mask in sorted_generated_masks]
138
  )
139
+ if expand_mask:
140
+ mask = np.array(
141
+ [
142
+ cv2.dilate(mask["segmentation"].astype(np.uint8), kernel)
143
+ for mask in sorted_generated_masks
144
+ ]
145
+ )
146
+ else:
147
+ mask = np.array(
148
+ [mask["segmentation"] for mask in sorted_generated_masks]
149
+ )
150
  detections = sv.Detections(
151
  xyxy=xywh_to_xyxy(boxes_xywh=xywh), mask=mask
152
  )
153
+ binary_mask = None
154
 
155
  # Save annotated image
156
  if output_dir and save_ann:
 
167
  np.save(mask_enc_path, res)
168
  metadata["assets"]["mask_enc"] = mask_enc_path
169
 
170
+ if binary_mask is not None:
171
+ cutout_image = np.expand_dims(binary_mask, axis=-1) * orig_image
172
+ cutout_image_path = os.path.join(
173
+ output_dir, basename + "_cutout.png"
174
+ )
175
+ Image.fromarray(cutout_image).save(cutout_image_path)
176
+
177
  annotated_image_path = os.path.join(
178
  output_dir, basename + "_annotate.png"
179
  )
 
408
  parser.add_argument(
409
  "--iou-threshold", type=float, default=0.5, help="iou threshold"
410
  )
411
+ parser.add_argument(
412
+ "--kernel-size",
413
+ type=int,
414
+ default=2,
415
+ choices=range(1, 6),
416
+ help="kernel size use for smoothing/expanding segment masks",
417
+ )
418
+ parser.add_argument(
419
+ "--expand-mask",
420
+ action="store_true",
421
+ default=False,
422
+ help="If True, expanding segment masks for smoother output.",
423
+ )
424
 
425
  parser.add_argument(
426
  "--no-save-ann",
app.py CHANGED
@@ -175,7 +175,7 @@ def process(
175
  detections.mask = masks
176
  binary_mask = functools.reduce(
177
  lambda x, y: x + y, detections.mask
178
- ).astype(np.bool)
179
  else:
180
  masks = sam_automask_generator.generate(orig_image)
181
  sorted_generated_masks = sorted(
@@ -183,15 +183,20 @@ def process(
183
  )
184
 
185
  xywh = np.array([mask["bbox"] for mask in sorted_generated_masks])
186
- mask = np.array(
187
- [
188
- cv2.dilate(mask["segmentation"].astype(np.uint8), kernel)
189
- for mask in sorted_generated_masks
190
- ]
191
- )
192
  scores = np.array(
193
  [mask["predicted_iou"] for mask in sorted_generated_masks]
194
  )
 
 
 
 
 
 
 
 
 
 
 
195
  detections = sv.Detections(
196
  xyxy=xywh_to_xyxy(boxes_xywh=xywh), mask=mask
197
  )
 
175
  detections.mask = masks
176
  binary_mask = functools.reduce(
177
  lambda x, y: x + y, detections.mask
178
+ ).astype(bool)
179
  else:
180
  masks = sam_automask_generator.generate(orig_image)
181
  sorted_generated_masks = sorted(
 
183
  )
184
 
185
  xywh = np.array([mask["bbox"] for mask in sorted_generated_masks])
 
 
 
 
 
 
186
  scores = np.array(
187
  [mask["predicted_iou"] for mask in sorted_generated_masks]
188
  )
189
+ if expand_mask:
190
+ mask = np.array(
191
+ [
192
+ cv2.dilate(mask["segmentation"].astype(np.uint8), kernel)
193
+ for mask in sorted_generated_masks
194
+ ]
195
+ )
196
+ else:
197
+ mask = np.array(
198
+ [mask["segmentation"] for mask in sorted_generated_masks]
199
+ )
200
  detections = sv.Detections(
201
  xyxy=xywh_to_xyxy(boxes_xywh=xywh), mask=mask
202
  )