scorevision: push artifact
Browse files- __pycache__/miner.cpython-312.pyc +0 -0
- 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.
|
| 3 |
-
Dual-model: vehicle (YOLO11m INT8 1280,
|
| 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 |
-
|
| 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
|
| 735 |
-
|
| 736 |
-
Pipeline:
|
| 737 |
-
1.
|
| 738 |
-
2.
|
| 739 |
-
3.
|
| 740 |
-
4. Per-class
|
| 741 |
-
5.
|
| 742 |
-
6. Skip bus (cls_id=4, not scored by validator)
|
| 743 |
"""
|
| 744 |
oh, ow = image_bgr.shape[:2]
|
| 745 |
|
| 746 |
-
#
|
| 747 |
-
|
| 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 |
-
|
| 1870 |
-
|
| 1871 |
-
|
|
|
|
| 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.
|
|
|
|
| 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
|