SuperBitDev commited on
Commit
a4ea9c5
·
verified ·
1 Parent(s): 50ea4d8

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. miner.py +88 -7
  2. weights.onnx +2 -2
miner.py CHANGED
@@ -71,7 +71,7 @@ class Miner:
71
  self.input_height = self._safe_dim(self.input_shape[2], default=1280)
72
  self.input_width = self._safe_dim(self.input_shape[3], default=1280)
73
 
74
- self.conf_thres = 0.1
75
  self.iou_thres = 0.6
76
  self.max_det = 300
77
  self.use_tta = True
@@ -223,6 +223,79 @@ class Miner:
223
  mask = scores > score_thresh
224
  return order[mask], scores[mask]
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  def _decode_final_dets(
227
  self,
228
  preds: np.ndarray,
@@ -420,7 +493,7 @@ class Miner:
420
  return self._postprocess(det_output, ratio, pad, orig_size)
421
 
422
  def _predict_tta(self, image: np.ndarray) -> list[BoundingBox]:
423
- """Horizontal-flip TTA: run inference on original + flipped, merge with Soft-NMS."""
424
  boxes_orig = self._predict_single(image)
425
 
426
  flipped = cv2.flip(image, 1)
@@ -444,15 +517,23 @@ class Miner:
444
  )
445
  scores = np.array([b.conf for b in all_boxes], dtype=np.float32)
446
 
447
- keep_idx, updated_scores = self._soft_nms(coords, scores)
 
 
 
 
 
448
 
449
  return [
450
  BoundingBox(
451
- x1=all_boxes[i].x1, y1=all_boxes[i].y1,
452
- x2=all_boxes[i].x2, y2=all_boxes[i].y2,
453
- cls_id=all_boxes[i].cls_id, conf=float(s),
 
 
 
454
  )
455
- for i, s in zip(keep_idx, updated_scores)
456
  ]
457
 
458
  def predict_batch(
 
71
  self.input_height = self._safe_dim(self.input_shape[2], default=1280)
72
  self.input_width = self._safe_dim(self.input_shape[3], default=1280)
73
 
74
+ self.conf_thres = 0.07
75
  self.iou_thres = 0.6
76
  self.max_det = 300
77
  self.use_tta = True
 
223
  mask = scores > score_thresh
224
  return order[mask], scores[mask]
225
 
226
+ @staticmethod
227
+ def _hard_nms(
228
+ boxes: np.ndarray,
229
+ scores: np.ndarray,
230
+ iou_thresh: float,
231
+ ) -> np.ndarray:
232
+ """
233
+ Standard NMS: keep one box per overlapping cluster (the one with highest score).
234
+ Returns indices of kept boxes (into the boxes/scores arrays).
235
+ """
236
+ N = len(boxes)
237
+ if N == 0:
238
+ return np.array([], dtype=np.intp)
239
+ boxes = np.asarray(boxes, dtype=np.float32)
240
+ scores = np.asarray(scores, dtype=np.float32)
241
+ order = np.argsort(scores)[::-1]
242
+ keep: list[int] = []
243
+ suppressed = np.zeros(N, dtype=bool)
244
+ for i in range(N):
245
+ idx = order[i]
246
+ if suppressed[idx]:
247
+ continue
248
+ keep.append(idx)
249
+ bi = boxes[idx]
250
+ for k in range(i + 1, N):
251
+ jdx = order[k]
252
+ if suppressed[jdx]:
253
+ continue
254
+ bj = boxes[jdx]
255
+ xx1 = max(bi[0], bj[0])
256
+ yy1 = max(bi[1], bj[1])
257
+ xx2 = min(bi[2], bj[2])
258
+ yy2 = min(bi[3], bj[3])
259
+ inter = max(0.0, xx2 - xx1) * max(0.0, yy2 - yy1)
260
+ area_i = (bi[2] - bi[0]) * (bi[3] - bi[1])
261
+ area_j = (bj[2] - bj[0]) * (bj[3] - bj[1])
262
+ iou = inter / (area_i + area_j - inter + 1e-7)
263
+ if iou > iou_thresh:
264
+ suppressed[jdx] = True
265
+ return np.array(keep)
266
+
267
+ @staticmethod
268
+ def _max_score_per_cluster(
269
+ coords: np.ndarray,
270
+ scores: np.ndarray,
271
+ keep_indices: np.ndarray,
272
+ iou_thresh: float,
273
+ ) -> np.ndarray:
274
+ """
275
+ For each kept box, return the max original score among itself and any
276
+ box that overlaps it with IOU >= iou_thresh (so TTA cluster keeps best conf).
277
+ """
278
+ n_keep = len(keep_indices)
279
+ if n_keep == 0:
280
+ return np.array([], dtype=np.float32)
281
+ out = np.empty(n_keep, dtype=np.float32)
282
+ coords = np.asarray(coords, dtype=np.float32)
283
+ scores = np.asarray(scores, dtype=np.float32)
284
+ for i in range(n_keep):
285
+ idx = keep_indices[i]
286
+ bi = coords[idx]
287
+ xx1 = np.maximum(bi[0], coords[:, 0])
288
+ yy1 = np.maximum(bi[1], coords[:, 1])
289
+ xx2 = np.minimum(bi[2], coords[:, 2])
290
+ yy2 = np.minimum(bi[3], coords[:, 3])
291
+ inter = np.maximum(0.0, xx2 - xx1) * np.maximum(0.0, yy2 - yy1)
292
+ area_i = (bi[2] - bi[0]) * (bi[3] - bi[1])
293
+ areas_j = (coords[:, 2] - coords[:, 0]) * (coords[:, 3] - coords[:, 1])
294
+ iou = inter / (area_i + areas_j - inter + 1e-7)
295
+ in_cluster = iou >= iou_thresh
296
+ out[i] = float(np.max(scores[in_cluster]))
297
+ return out
298
+
299
  def _decode_final_dets(
300
  self,
301
  preds: np.ndarray,
 
493
  return self._postprocess(det_output, ratio, pad, orig_size)
494
 
495
  def _predict_tta(self, image: np.ndarray) -> list[BoundingBox]:
496
+ """Horizontal-flip TTA: merge original + flipped via hard NMS."""
497
  boxes_orig = self._predict_single(image)
498
 
499
  flipped = cv2.flip(image, 1)
 
517
  )
518
  scores = np.array([b.conf for b in all_boxes], dtype=np.float32)
519
 
520
+ hard_keep = self._hard_nms(coords, scores, self.iou_thres)
521
+ if len(hard_keep) == 0:
522
+ return []
523
+
524
+ # _hard_nms already orders kept indices by descending score.
525
+ hard_keep = hard_keep[: self.max_det]
526
 
527
  return [
528
  BoundingBox(
529
+ x1=all_boxes[i].x1,
530
+ y1=all_boxes[i].y1,
531
+ x2=all_boxes[i].x2,
532
+ y2=all_boxes[i].y2,
533
+ cls_id=all_boxes[i].cls_id,
534
+ conf=float(scores[i]),
535
  )
536
+ for i in hard_keep
537
  ]
538
 
539
  def predict_batch(
weights.onnx CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:be6e4b7e468f655482d0f73509954721601eacb68d376d8191a14bdb7f3d3105
3
- size 19404973
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:31ee30943eda5c04c67b76a612dff96dd6f6fdb44ea7ea28dd425493ce63a5ab
3
+ size 19153171