قابلیت reid این کد را قوی کن و یک کد کامل بنویس و ...

생성일: 2025년 2월 8일

답변에 사용된 모델 O1 by Chat01

질문

قابلیت reid این کد را قوی کن و یک کد کامل بنویس و کامل توضیح بده

import cv2
import torch
from ultralytics import YOLO
from deep_sort_realtime.deepsort_tracker import DeepSort
import os
import sys

def load_model(model_path):
model = YOLO(model_path)
device = 'cuda' if torch.cuda.is_available() else 'cpu'
model.to(device)
return model

def process_frame(model, frame):
results = model(frame)
detections = results[0].boxes.xyxy.cpu().numpy()
confidences = results[0].boxes.conf.cpu().numpy()
class_ids = results[0].boxes.cls.cpu().numpy()
return detections, confidences, class_ids

def draw_detections(frame, detections, confidences, confidence_threshold=0.3):
bboxes = []
scores = []
for i, box in enumerate(detections):
x1, y1, x2, y2 = map(int, box[:4])
confidence = confidences[i]
if confidence > confidence_threshold:
bboxes.append([x1, y1, x2, y2])
scores.append(confidence)
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
return bboxes, scores

def track_objects(deepsort, frame, bboxes, scores):
# Convert bboxes and scores to the format expected by DeepSORT
detections = []
for bbox, score in zip(bboxes, scores):
x1, y1, x2, y2 = bbox
detections.append(([x1, y1, x2 - x1, y2 - y1], score, None)) # (bbox, confidence, feature)

text
# Update tracks trackers = deepsort.update_tracks(detections, frame=frame) # Draw tracking results for track in trackers: if not track.is_confirmed(): continue track_id = track.track_id ltrb = track.to_ltrb() x1, y1, x2, y2 = map(int, ltrb) cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2) # Draw trackers label = f"ID {track_id}" cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 2)

def detect_and_track(video_path, model_path):
try:
model = load_model(model_path)
deepsort = DeepSort(max_age=100, n_init=1, nms_max_overlap=1.0, embedder_gpu=True, embedder='mobilenet')

text
cap = cv2.VideoCapture(video_path) if not cap.isOpened(): print(f"Error: Unable to open video file {video_path}") return frame_count = 0 while cap.isOpened(): ret, frame = cap.read() if not ret: print("End of video stream") break frame_count += 1 print(f"Processing frame {frame_count}") detections, confidences, class_ids = process_frame(model, frame) bboxes, scores = draw_detections(frame, detections, confidences) if bboxes: track_objects(deepsort, frame, bboxes, scores) cv2.imshow("YOLO Detection and DeepSORT Tracking", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() except Exception as e: print(f"An error occurred: {e}") import traceback traceback.print_exc()

def main():
video_path = 'cropped_output.mp4'
model_path = '/media/rayfan/d/behavior analysis/model/best-yolov11.pt'

text
if not os.path.exists(video_path): print(f"Video file not found: {video_path}") return if not os.path.exists(model_path): print(f"Model file not found: {model_path}") return detect_and_track(video_path, model_path)

if name == "main":
main()

사고

Enhancing reID approach

I'm thinking through strengthening the reID with YOLO and deep_sort_realtime, possibly by integrating better embeddings like "osnet_x0_25" or "osnet_x1_0", and exploring new deep_sort_realtime or strongsort features.

Enhancing reID with specific models

Setting "embedder_model_name" to 'osnet_x0_25' or 'osnet_x1_0' can significantly improve reID. Adjusting parameters like "max_dist", "nn_budget", and "max_iou_distance" also boosts performance, considering advanced features and Persian explanation.

Reasoned for 5 seconds

답변

در این نمونه‌کد ما از YOLO برای آشکارسازی اشیا و از کتابخانهٔ deep_sort_realtime برای ردگیری (Tracking) و بهبود ReID (بازشناسایی مجدد) استفاده می‌کنیم. ایدهٔ اصلی برای قوی‌تر کردن ReID این است که از مدل تعبیه (Embedder) قوی‌تری استفاده شود و همچنین برخی پارامترهای مرتبط با deep_sort را که بر دقت و پایداری شناسه (ID) تأثیر می‌گذارند، به درستی تنظیم کنیم.

در deep_sort_realtime چندین انتخاب برای Embedder وجود دارد (همچون mobilenet، osnet_x0_25، osnet_x0_5، osnet_x0_75، osnet_x1_0، osnet_x1_0_simplified و غیره). مدل‌های مبتنی بر OSNet عموماً عملکرد بهتری در مبحث ReID دارند. همچنین تنظیماتی مثل max_dist، nn_budget، و غیره در ردیاب DeepSORT اثر گذارند.

نمونه کد زیر، کدی کامل‌تر از نظر ReID است. در این کد از YOLO برای تشخیص اشیا استفاده شده و برای ردیابی با DeepSORT، از مدل OSNet (مثلاً osnet_x0_25) جهت استخراج ویژگی‌ها (ReID embedding) استفاده می‌گردد. همچنین چند پارامتر مهم DeepSORT تنظیم شده است:

  1. embedder: نام مدل تعبیهٔ ما برای ReID.
  2. max_dist: بیشینه فاصلهٔ مجاز بین تعبیه‌ها (Embedding) برای یکی در نظر گرفتن دو جعبه (BBox) در فریم‌های مختلف. هرچه این مقدار کمتر باشد، مدل سخت‌گیرانه‌تر عمل می‌کند و احتمال جابه‌جا شدن IDها کمتر می‌شود، اما ممکن است ID گم شود.
  3. nn_budget: اندازهٔ بافر نزدیک‌ترین همسایه‌ها در هنگام محاسبهٔ شباهت تعبیه‌ها. هرچه بیشتر باشد، حافظهٔ تاریخی بلندمدت‌تر می‌شود.
  4. max_age: تعداد فریم‌هایی که اگر یک Track در آن ظاهر نشود، از دست می‌رود.
  5. n_init: تعداد فریم‌های ابتدایی که نیاز است یک Track تأیید (confirm) شود تا عنوان «تأییدشده» بگیرد.

همچنین برای ارتقاء سرعت می‌توانیم از GPU استفاده کنیم (در صورت وجود) و پارامتر half=True را در برخی مدل‌ها فعال کنیم، به‌خصوص اگر در دستگاهی با پشتیبانی FP16 مانند کارت‌های گرافیکی NVIDIA باشیم.

python
import cv2 import torch from ultralytics import YOLO from deep_sort_realtime.deepsort_tracker import DeepSort import os import traceback def load_model(model_path): """ مدل YOLO را از مسیر داده شده بارگذاری می‌کند. در صورت وجود CUDA (کارت گرافیک سازگار با NVIDIA)، از GPU استفاده می‌کند. """ model = YOLO(model_path) device = 'cuda' if torch.cuda.is_available() else 'cpu' model.to(device) return model def process_frame(model, frame): """ روی هر فریم مدل YOLO را اجرا می‌کند و خروجی شامل مختصات جعبه‌های مکان‌یاب، اعتماد مدل (confidence) و شناسهٔ کلاس را برمی‌گرداند. """ results = model(frame) detections = results[0].boxes.xyxy.cpu().numpy() # مختصات bbox به شکل [x1, y1, x2, y2] confidences = results[0].boxes.conf.cpu().numpy() # لیست confidence برای هر bbox class_ids = results[0].boxes.cls.cpu().numpy() # لیست شناسه کلاس برای هر bbox return detections, confidences, class_ids def draw_detections(frame, detections, confidences, confidence_threshold=0.3): """ جعبه‌های مکان‌یاب را روی تصویر رسم می‌کند و فقط آن‌هایی که اعتماد بالاتر از threshold دارند نگه می‌دارد. خروجی: بایندینگ‌باکس‌ها و اسکورهایی که برای DeepSORT نیاز داریم. """ bboxes = [] scores = [] for i, box in enumerate(detections): x1, y1, x2, y2 = map(int, box[:4]) confidence = confidences[i] if confidence > confidence_threshold: bboxes.append([x1, y1, x2, y2]) scores.append(confidence) # رسم جعبه سبزرنگ برای آشکارسازی YOLO cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) return bboxes, scores def track_objects(deepsort, frame, bboxes, scores): """ با توجه به بایندینگ‌باکس‌های دیتکشن‌شده و اسکورهایشان، خروجی ردیاب DeepSORT را بروزرسانی می‌کند و سپس روی تصویر جعبه‌های ردگیری‌شده را می‌کشد. """ # تبدیل bboxes و scores به فرمتی که DeepSORT انتظار دارد: detections = [] for bbox, score in zip(bboxes, scores): x1, y1, x2, y2 = bbox w = x2 - x1 h = y2 - y1 detections.append(([x1, y1, w, h], score, None)) # (bbox, confidence, feature=None) # بروزرسانی مسیر (Track) در DeepSORT trackers = deepsort.update_tracks(detections, frame=frame) # رسم نتایج ردیابی روی فریم for track in trackers: if not track.is_confirmed(): continue track_id = track.track_id ltrb = track.to_ltrb() # مختصات [x1, y1, x2, y2] x1, y1, x2, y2 = map(int, ltrb) # رسم جعبه آبی‌رنگ برای شیء ردیابی‌شده cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2) label = f"ID {track_id}" cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 2) def detect_and_track(video_path, model_path): """ این تابع ویدئو را می‌خواند، در هر فریم، آشکارسازی (Detection) با YOLO انجام می‌شود و سپس DeepSORT جهت ردیابی و بازشناسایی مجدد استفاده می‌شود. """ try: model = load_model(model_path) # ساخت نمونه DeepSort با تنظیمات دلخواه (reID قوی‌تر): # - embedder: یکی از مدل‌های OSNet را تنظیم می‌کنیم (مثال: osnet_x0_25). # - max_dist: هر چه عدد کمتر باشد سختگیرانه‌تر با matchکردن reID برخورد می‌کند. # - nn_budget: اندازه بافر نزدیک‌ترین‌همسایه‌ها # - max_age: پس از چند فریم گم‌شدن، ID حذف شود # - n_init: چند فریم لازم است تا Track تایید شود deepsort = DeepSort( max_age=100, n_init=2, nms_max_overlap=1.0, embedder_gpu=True, embedder='osnet_x0_25', # می‌توانید مثلاً 'osnet_x1_0' یا دیگر مدل‌ها را هم تست کنید max_dist=0.2, # فاصله تعبیه‌ها در همسان‌سازی nn_budget=100, half=True # استفاده از half precision در صورت پشتیبانی GPU ) cap = cv2.VideoCapture(video_path) if not cap.isOpened(): print(f"Error: Unable to open video file {video_path}") return frame_count = 0 while cap.isOpened(): ret, frame = cap.read() if not ret: print("End of video stream") break frame_count += 1 print(f"Processing frame {frame_count} ...") detections, confidences, class_ids = process_frame(model, frame) bboxes, scores = draw_detections(frame, detections, confidences, confidence_threshold=0.3) # اگر دیتکشن داشتیم، ردیابی را آپدیت کن if bboxes: track_objects(deepsort, frame, bboxes, scores) # نمایش فریم همراه با دیتکشن و ردیابی cv2.imshow("YOLO Detection and DeepSORT Tracking", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() except Exception as e: print(f"An error occurred: {e}") traceback.print_exc() def main(): video_path = 'cropped_output.mp4' model_path = '/media/rayfan/d/behavior analysis/model/best-yolov11.pt' if not os.path.exists(video_path): print(f"Video file not found: {video_path}") return if not os.path.exists(model_path): print(f"Model file not found: {model_path}") return detect_and_track(video_path, model_path) if __name__ == "__main__": main()

توضیحات کلیدی

  1. YOLO (ultralytics):

    • با YOLO(model_path) مدل YOLO بارگیری می‌شود. بستهٔ ultralytics امکان فراخوانی آسان مدل‌های YOLOv8 و نسخه‌های دیگر را فراهم می‌کند.
  2. DeepSORT:

    • برای ردیابی مبتنی بر تشخیص (Detection-based Tracking) استفاده می‌شود.
    • از ویژگی‌های بصری (ReID Embeddings) برای تفکیک و تشخیص مجدد اشیایی که در فریم‌های بعدی ظاهر می‌شوند استفاده می‌کند.
    • پارامتر embedder تعیین می‌کند که از کدام مدل برای استخراج ویژگی (Feature Extraction) استفاده شود. در اینجا OSNet (مثلاً osnet_x0_25) در نظر گرفته شده است که معمولاً نسبت به MobileNet در ReID نتایج بهتری دارد.
    • پارامتر max_dist فاصله حداکثری تعبیه‌ها برای مچ‌شدن است. هرچه کوچک‌تر باشد، دو جعبه سخت‌تر یک شیء در نظر گرفته می‌شوند و این موضوع از اشتباه ترکیب‌شدن Trackها جلوگیری می‌کند ولی ممکن است ID بیشتر گم شود.
    • پارامتر nn_budget اندازه حافظهٔ تاریخی (تعبیه‌های قبلی) است که با افزایش آن، احتمال حفظ رد اشیا در طولانی‌مدت بیشتر می‌شود. اما در عین حال به رم و زمان محاسبه بیشتری نیاز دارد.
  3. سایر پارامترها:

    • max_age: تعداد فریم‌هایی که یک Track در آن غیرفعال باشد تا حذف شود (وقتی شیء دیگر دیده نمی‌شود).
    • n_init: تعداد فریم لازم برای تأییدشدن Track. اگر یک شیء در تعداد فریم کمتری ظاهر شود، حذف می‌شود.
    • embedder_gpu=True: برای محاسبات ReID از GPU استفاده می‌کند (در صورت در دسترس بودن).
    • half=True: برای سرعت بیشتر از دقت شناور نصفه (FP16) استفاده می‌کند (وقتی GPU از آن پشتیبانی کند).
  4. نحوه استفاده:

    • مسیر ویدیو (video_path) و مدل YOLO (model_path) را با توجه به سیستم خود تنظیم کنید.
    • اگر از GPU انویدیا استفاده می‌کنید، مطمئن شوید محیط پایتون شما CUDA را شناسایی می‌کند (نصب PyTorch با پشتیبانی CUDA).
    • کتابخانه‌های مورد نیاز:
      • pip install ultralytics
      • pip install git+https://github.com/levan92/deep_sort_realtime.git
      • opencv-python یا opencv-contrib-python
  5. بهبودهای بیشتر:

    • می‌توانید پارامترهای DeepSORT را با توجه به سناریو دادهٔ خود بهینه کنید. برای مثال، اگر اشیای مشابه با رنگ یا ظاهر مشابه زیاد هستند، max_dist را کمتر تنظیم کنید. اگر تمایل دارید IDها در صورت دور و نزدیک شدن طولانی حفظ شوند، max_age را افزایش دهید.
    • از مدل‌های مختلف OSNet استفاده کنید (مثلاً osnet_x1_0) و ببینید کدام بهتر عمل می‌کند.
    • در صورت نیاز به سرعت بالاتر، رزولوشن ویدیو را کم کنید یا از half precision با GPU استفاده کنید.

این کد نمونه به شما اجازه می‌دهد با دقت بیشتری اشیا را در طول فریم‌های ویدیو دنبال کنید و از قوی‌تر بودن مدل ReID برای جلوگیری از تغییر ناخواستهٔ شناسه‌ها در طول ردیابی بهره ببرید.

이 Q&A 공유하기