Spaces:
Build error
Build error
| import cv2 | |
| from ultralytics import YOLO | |
| from deep_sort_realtime.deepsort_tracker import DeepSort | |
| import os | |
| from datetime import datetime | |
| model = YOLO("C:\\Users\\PC\\Desktop\\GazCounter\\models\\best (10).pt") | |
| tracker = DeepSort( | |
| max_age=30, | |
| n_init=3, | |
| max_iou_distance=0.7, | |
| embedder="mobilenet", | |
| half=True, | |
| embedder_gpu=True, | |
| ) | |
| video_path = "C:\\Users\\PC\\Desktop\\GazCounter\\data\\WhatsApp Video 2025-10-02 at 11.29.11.mp4" | |
| cap = cv2.VideoCapture(video_path) | |
| # ββ OUTPUT SETUP ββββββββββββββββββββββββββββββββββββββββ | |
| width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) | |
| height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) | |
| fps = int(cap.get(cv2.CAP_PROP_FPS)) | |
| output_dir = "C:\\Users\\PC\\Desktop\\GazCounter\\results" | |
| os.makedirs(output_dir, exist_ok=True) | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| output_video = os.path.join(output_dir, f"result_{timestamp}.mp4") | |
| output_txt = os.path.join(output_dir, f"result_{timestamp}.txt") | |
| writer = cv2.VideoWriter( | |
| output_video, | |
| cv2.VideoWriter_fourcc(*"mp4v"), | |
| fps, (width, height) | |
| ) | |
| # ββ STATE βββββββββββββββββββββββββββββββββββββββββββββββ | |
| count_per_brand = {} | |
| detected_ids = set() | |
| id_to_box = {} | |
| id_to_class = {} | |
| IOU_THRESHOLD = 0.5 | |
| def iou(boxA, boxB): | |
| xA = max(boxA[0], boxB[0]) | |
| yA = max(boxA[1], boxB[1]) | |
| xB = min(boxA[2], boxB[2]) | |
| yB = min(boxA[3], boxB[3]) | |
| inter = max(0, xB - xA) * max(0, yB - yA) | |
| if inter == 0: | |
| return 0.0 | |
| areaA = (boxA[2]-boxA[0]) * (boxA[3]-boxA[1]) | |
| areaB = (boxB[2]-boxB[0]) * (boxB[3]-boxB[1]) | |
| return inter / float(areaA + areaB - inter) | |
| # ββ MAIN LOOP βββββββββββββββββββββββββββββββββββββββββββ | |
| while True: | |
| ret, frame = cap.read() | |
| if not ret: | |
| break | |
| # ββ Step 1: YOLO detect (no tracking) βββββββββββββββ | |
| results = model.predict(frame, conf=0.4, verbose=False) | |
| detections = [] | |
| cls_map = {} # index β class name | |
| for r in results: | |
| if r.boxes is None: | |
| continue | |
| for i, box in enumerate(r.boxes): | |
| x1, y1, x2, y2 = map(int, box.xyxy[0].cpu().numpy()) | |
| conf = float(box.conf[0]) | |
| cls_id = int(box.cls[0]) | |
| cls_name = r.names[cls_id] | |
| # DeepSORT format: ([x1,y1,w,h], conf, class_name) | |
| w = x2 - x1 | |
| h = y2 - y1 | |
| detections.append(([x1, y1, w, h], conf, cls_name)) | |
| # ββ Step 2: DeepSORT update ββββββββββββββββββββββββββ | |
| tracks = tracker.update_tracks(detections, frame=frame) | |
| for track in tracks: | |
| if not track.is_confirmed(): | |
| continue | |
| track_id = track.track_id | |
| cls_name = track.get_det_class() | |
| ltrb = track.to_ltrb() # (x1, y1, x2, y2) | |
| x1, y1, x2, y2 = map(int, ltrb) | |
| curr_box = (x1, y1, x2, y2) | |
| if cls_name is None: | |
| continue | |
| # Draw | |
| cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) | |
| cv2.putText( | |
| frame, | |
| f"{cls_name} #{track_id}", | |
| (x1, y1 - 10), | |
| cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2 | |
| ) | |
| # ββ Unique count with IoU dedup ββββββββββββββββββ | |
| if track_id not in detected_ids: | |
| is_duplicate = False | |
| for known_id, known_box in id_to_box.items(): | |
| if known_id not in detected_ids: | |
| continue | |
| if iou(curr_box, known_box) > IOU_THRESHOLD: | |
| is_duplicate = True | |
| break | |
| if not is_duplicate: | |
| detected_ids.add(track_id) | |
| count_per_brand[cls_name] = count_per_brand.get(cls_name, 0) + 1 | |
| id_to_box[track_id] = curr_box | |
| id_to_class[track_id] = cls_name | |
| # ββ Overlay panel ββββββββββββββββββββββββββββββββββββ | |
| overlay = frame.copy() | |
| panel_h = 30 + len(count_per_brand) * 28 | |
| cv2.rectangle(overlay, (5, 5), (300, panel_h), (0, 0, 0), -1) | |
| cv2.addWeighted(overlay, 0.4, frame, 0.6, 0, frame) | |
| for i, (brand, count) in enumerate(sorted(count_per_brand.items())): | |
| cv2.putText( | |
| frame, f"{brand}: {count}", | |
| (10, 28 + i * 28), | |
| cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 255, 255), 2 | |
| ) | |
| total = sum(count_per_brand.values()) | |
| cv2.putText( | |
| frame, f"TOTAL: {total} bouteilles", | |
| (10, frame.shape[0] - 10), | |
| cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 2 | |
| ) | |
| writer.write(frame) | |
| cv2.imshow("GazCounter", frame) | |
| if cv2.waitKey(1) & 0xFF == ord('q'): | |
| break | |
| cap.release() | |
| writer.release() | |
| cv2.destroyAllWindows() | |
| # ββ Save report ββββββββββββββββββββββββββββββββββββββββββ | |
| with open(output_txt, "w") as f: | |
| f.write(f"GazCounter Results - {timestamp}\n") | |
| f.write("=" * 40 + "\n") | |
| for brand, count in sorted(count_per_brand.items()): | |
| f.write(f" {brand}: {count} bouteille(s)\n") | |
| f.write("=" * 40 + "\n") | |
| f.write(f" TOTAL: {sum(count_per_brand.values())} bouteilles\n") | |
| print("\n" + "=" * 40) | |
| print(f"Video β {output_video}") | |
| print(f"Report β {output_txt}") | |
| print("=" * 40) | |
| for brand, count in sorted(count_per_brand.items()): | |
| print(f" {brand}: {count} bouteille(s)") | |
| print(f" TOTAL: {sum(count_per_brand.values())} bouteilles") |