meaculpitt commited on
Commit
5abbca1
Β·
verified Β·
1 Parent(s): 6dddc98

scorevision: push artifact

Browse files
Files changed (2) hide show
  1. __pycache__/miner.cpython-312.pyc +0 -0
  2. miner.py +81 -29
__pycache__/miner.cpython-312.pyc ADDED
Binary file (98.5 kB). View file
 
miner.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
- Score Vision SN44 β€” Unified miner v3.16 (2026-04-03). YOLO12s + TRT + CLAHE.
3
- Dual-model: vehicle (YOLO11m INT8 1280, CUDA) + person (YOLO12s FP16 960 end2end, TRT).
4
  Pose model: YOLOv8n-pose FP16 640 for false-positive filtering + keypoint box refinement.
5
  Vehicle weights loaded from secondary HF repo (meaculpitt/ScoreVision-Vehicle).
6
  Person weights loaded from primary HF repo (template downloads automatically).
@@ -10,7 +10,7 @@ Vehicle model (vehicle_weights.onnx):
10
  Output: 1=car, 2=truck, 3=motorcycle. Bus (cls_id=4) SUPPRESSED β€” not scored by validator.
11
  Per-class confidence thresholds: car 0.45, truck 0.45, motorcycle 0.35.
12
  Per-class aspect ratio bounds for FP filtering.
13
- Flip TTA always enabled β€” compensates for higher confidence thresholds.
14
 
15
  Person model (person_weights.onnx):
16
  YOLO12s FP16 960px end2end [1,300,6]. Single class: 0=person.
@@ -293,6 +293,12 @@ PER_BLUR_CONF_PENALTY = 0.85 # multiply confs by this for blurry frames (redu
293
  PER_CLAHE_CLIP = 2.0 # mild CLAHE (was 12.0, too aggressive)
294
  PER_CLAHE_CONTRAST_THRESH = 40.0 # only apply CLAHE when L-channel std < this
295
 
 
 
 
 
 
 
296
  # ── Pose FP filter + box refinement config ──────────────────────────────────
297
  POSE_CONF_THRESH = 0.25 # Minimum confidence for pose detection
298
  POSE_NMS_IOU = 0.65 # NMS IoU threshold for pose detections
@@ -731,31 +737,19 @@ class Miner:
731
  return self._veh_decode(raw, ratio, pl, pt, ow, oh, conf_thresh)
732
 
733
  def _infer_vehicle(self, image_bgr):
734
- """Vehicle detection with flip TTA, per-class confidence, and aspect ratio filtering.
735
-
736
- Pipeline:
737
- 1. Original pass at VEH_CONF_THRES
738
- 2. Flip TTA pass at VEH_TTA_CONF (always enabled)
739
- 3. Remap classes, per-class NMS
740
- 4. Per-class confidence filter (higher thresholds reduce FP)
741
- 5. Per-class aspect ratio filter
742
- 6. Skip bus (cls_id=4, not scored by validator)
743
  """
744
  oh, ow = image_bgr.shape[:2]
745
 
746
- # Always run flip TTA for vehicle β€” compensates for higher per-class thresholds
747
- boxes1, confs1, cls1 = self._veh_run_pass(image_bgr, VEH_CONF_THRES)
748
- flipped = cv2.flip(image_bgr, 1)
749
- boxes2, confs2, cls2 = self._veh_run_pass(flipped, VEH_TTA_CONF)
750
- if len(boxes2):
751
- boxes2[:, 0], boxes2[:, 2] = ow - boxes2[:, 2], ow - boxes2[:, 0]
752
- parts = [(b, s, c) for b, s, c in
753
- [(boxes1, confs1, cls1), (boxes2, confs2, cls2)] if len(b)]
754
- if not parts:
755
- return []
756
- boxes = np.concatenate([p[0] for p in parts])
757
- confs = np.concatenate([p[1] for p in parts])
758
- cls_ids = np.concatenate([p[2] for p in parts])
759
 
760
  if len(boxes) == 0:
761
  return []
@@ -1239,6 +1233,51 @@ class Miner:
1239
  gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
1240
  return cv2.Laplacian(gray, cv2.CV_64F).var()
1241
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1242
  def _per_decode(self, raw, ratio, pl, pt, oh, ow, conf_thresh):
1243
  pred = raw[0]
1244
  if pred.ndim != 2:
@@ -1777,6 +1816,15 @@ class Miner:
1777
  all_boxes.append(boxes_flip)
1778
  all_confs.append(confs_flip)
1779
 
 
 
 
 
 
 
 
 
 
1780
  if not all_boxes:
1781
  return []
1782
 
@@ -1800,6 +1848,9 @@ class Miner:
1800
  if is_blurry:
1801
  merged_s = merged_s * PER_BLUR_CONF_PENALTY
1802
 
 
 
 
1803
  # Sanity filters
1804
  img_area = float(oh * ow)
1805
  out = []
@@ -1866,9 +1917,10 @@ class Miner:
1866
  return self._infer_person(image_bgr)
1867
 
1868
  if element_hint == 'vehicle':
1869
- vehicle_boxes = self._infer_vehicle(image_bgr)
1870
- vehicle_boxes = self._vehicle_parts_confirm(vehicle_boxes, [], image_bgr)
1871
- return vehicle_boxes
 
1872
 
1873
  # Fallback: run both (original behavior)
1874
  if ENABLE_PARALLEL:
@@ -1986,4 +2038,4 @@ class Miner:
1986
  ).start()
1987
 
1988
  return results
1989
- # Miner v3.18 β€” element detection + per-step timing β€” background TRT engine build + CUDA-first fallback 20260402
 
1
  """
2
+ Score Vision SN44 β€” Unified miner v3.19 (2026-04-04). YOLO12s + TRT + element detect.
3
+ Dual-model: vehicle (YOLO11m INT8 1280, 1-pass) + person (YOLO12s FP16 960 end2end, TRT).
4
  Pose model: YOLOv8n-pose FP16 640 for false-positive filtering + keypoint box refinement.
5
  Vehicle weights loaded from secondary HF repo (meaculpitt/ScoreVision-Vehicle).
6
  Person weights loaded from primary HF repo (template downloads automatically).
 
10
  Output: 1=car, 2=truck, 3=motorcycle. Bus (cls_id=4) SUPPRESSED β€” not scored by validator.
11
  Per-class confidence thresholds: car 0.45, truck 0.45, motorcycle 0.35.
12
  Per-class aspect ratio bounds for FP filtering.
13
+ Single-pass (v3.19) β€” flip TTA removed for RTF improvement.
14
 
15
  Person model (person_weights.onnx):
16
  YOLO12s FP16 960px end2end [1,300,6]. Single class: 0=person.
 
293
  PER_CLAHE_CLIP = 2.0 # mild CLAHE (was 12.0, too aggressive)
294
  PER_CLAHE_CONTRAST_THRESH = 40.0 # only apply CLAHE when L-channel std < this
295
 
296
+ # ── Perspective scaling confidence penalty ─────────────────────────────────
297
+ PERSP_DEVIATION_THRESH = 3.0 # ratio >3x or <1/3x triggers penalty
298
+ PERSP_CONF_PENALTY = 0.85 # multiply conf by this for perspective violations
299
+ PERSP_MIN_DETECTIONS = 3 # need β‰₯3 detections to estimate model
300
+ PERSP_MIN_Y_SPREAD = 0.15 # min y-spread as fraction of image height
301
+
302
  # ── Pose FP filter + box refinement config ──────────────────────────────────
303
  POSE_CONF_THRESH = 0.25 # Minimum confidence for pose detection
304
  POSE_NMS_IOU = 0.65 # NMS IoU threshold for pose detections
 
737
  return self._veh_decode(raw, ratio, pl, pt, ow, oh, conf_thresh)
738
 
739
  def _infer_vehicle(self, image_bgr):
740
+ """Vehicle detection: single-pass 1280px, per-class NMS + confidence + aspect filter.
741
+
742
+ Pipeline (v3.19 β€” TTA removed for RTF, saves ~9ms/frame Γ— 274 frames):
743
+ 1. Single pass at VEH_CONF_THRES
744
+ 2. Remap classes, per-class NMS
745
+ 3. Per-class confidence filter (higher thresholds reduce FP)
746
+ 4. Per-class aspect ratio filter
747
+ 5. Skip bus (cls_id=4, not scored by validator)
 
748
  """
749
  oh, ow = image_bgr.shape[:2]
750
 
751
+ # Single pass β€” flip TTA removed in v3.19 (RTF 0.89β†’0.65 for 274 frames)
752
+ boxes, confs, cls_ids = self._veh_run_pass(image_bgr, VEH_CONF_THRES)
 
 
 
 
 
 
 
 
 
 
 
753
 
754
  if len(boxes) == 0:
755
  return []
 
1233
  gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
1234
  return cv2.Laplacian(gray, cv2.CV_64F).var()
1235
 
1236
+ @staticmethod
1237
+ def _perspective_penalty(boxes, confs, image_h):
1238
+ """Apply confidence penalty to perspective-anomalous person detections.
1239
+
1240
+ Model: expected_height(y) = alpha * (y_foot - y_vp), where y_vp = image_h / 3.
1241
+ Alpha is estimated from the median height/distance ratio across detections.
1242
+ Detections deviating >3x from expected get conf *= 0.85.
1243
+ Fails open (returns confs unchanged) when model can't be estimated.
1244
+ """
1245
+ n = len(boxes)
1246
+ if n < PERSP_MIN_DETECTIONS:
1247
+ return confs
1248
+
1249
+ y_vp = image_h / 3.0
1250
+ y_feet = boxes[:, 3]
1251
+ heights = boxes[:, 3] - boxes[:, 1]
1252
+
1253
+ valid = y_feet > (y_vp + 10)
1254
+ if valid.sum() < PERSP_MIN_DETECTIONS:
1255
+ return confs
1256
+
1257
+ valid_y = y_feet[valid]
1258
+ valid_h = heights[valid]
1259
+
1260
+ y_spread = (valid_y.max() - valid_y.min()) / image_h
1261
+ if y_spread < PERSP_MIN_Y_SPREAD:
1262
+ return confs
1263
+
1264
+ alpha = float(np.median(valid_h / (valid_y - y_vp)))
1265
+ if alpha <= 0.01:
1266
+ return confs
1267
+
1268
+ new_confs = confs.copy()
1269
+ for i in range(n):
1270
+ if y_feet[i] <= y_vp:
1271
+ continue
1272
+ expected_h = alpha * (y_feet[i] - y_vp)
1273
+ if expected_h <= 0:
1274
+ continue
1275
+ ratio = heights[i] / expected_h
1276
+ if ratio > PERSP_DEVIATION_THRESH or ratio < (1.0 / PERSP_DEVIATION_THRESH):
1277
+ new_confs[i] *= PERSP_CONF_PENALTY
1278
+
1279
+ return new_confs
1280
+
1281
  def _per_decode(self, raw, ratio, pl, pt, oh, ow, conf_thresh):
1282
  pred = raw[0]
1283
  if pred.ndim != 2:
 
1816
  all_boxes.append(boxes_flip)
1817
  all_confs.append(confs_flip)
1818
 
1819
+ # Pass 3: CLAHE enhanced pass (low-contrast frames only, time-gated)
1820
+ if time.monotonic() - t_start < PER_RTF_BUDGET * 0.5:
1821
+ enhanced = self._per_enhance(image_bgr)
1822
+ if enhanced is not image_bgr: # CLAHE was applied (low contrast)
1823
+ boxes_enh, confs_enh = self._per_run_pass(enhanced, PER_CONF_LOW)
1824
+ if len(boxes_enh) > 0:
1825
+ all_boxes.append(boxes_enh)
1826
+ all_confs.append(confs_enh)
1827
+
1828
  if not all_boxes:
1829
  return []
1830
 
 
1848
  if is_blurry:
1849
  merged_s = merged_s * PER_BLUR_CONF_PENALTY
1850
 
1851
+ # Perspective scaling penalty β€” reduce conf for size-anomalous detections
1852
+ merged_s = self._perspective_penalty(merged_b, merged_s, oh)
1853
+
1854
  # Sanity filters
1855
  img_area = float(oh * ow)
1856
  out = []
 
1917
  return self._infer_person(image_bgr)
1918
 
1919
  if element_hint == 'vehicle':
1920
+ # Skip _vehicle_parts_confirm β€” it needs person_boxes for driver/rider
1921
+ # confirmation which aren't available in vehicle-only mode. Without person
1922
+ # detections, large vehicles with conf < 0.55 get falsely suppressed.
1923
+ return self._infer_vehicle(image_bgr)
1924
 
1925
  # Fallback: run both (original behavior)
1926
  if ENABLE_PARALLEL:
 
2038
  ).start()
2039
 
2040
  return results
2041
+ # Miner v3.19 β€” 1-pass vehicle + CLAHE pass + parts_confirm fix β€” element detection + per-step timing β€” background TRT engine build + CUDA-first fallback 20260402