использывать только gpu , оптемезируй и проверь  логику import os
import cv2
from deep_sort_realtime.deepsort_tracker import DeepSort
import torch
import numpy as np

# Определение текущей директории
current_dir = os.getcwd()

# Проверка доступности GPU
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f"Используемое устройство: {device}")

# Путь к видеофайлу
video_path = 'test.mp4'

# Проверка наличия видеофайла
if not os.path.exists(video_path):
    raise FileNotFoundError(f"Video file not found: {video_path}")

# Загрузка модели YOLOv8 в формате ONNX с помощью OpenCV DNN
model_path = os.path.join(current_dir, 'yolov8n.onnx')
if not os.path.exists(model_path):
    raise FileNotFoundError(f"ONNX model file not found: {model_path}")

net = cv2.dnn.readNetFromONNX(model_path)

# Настройка предпочтительного бэкенда и таргета на CUDA
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA_FP16)

# Инициализация трекера Deep SORT
tracker = DeepSort(max_age=30)

# Открытие видеофайла
cap = cv2.VideoCapture(video_path)

if not cap.isOpened():
    raise IOError(f"Cannot open video file: {video_path}")

# Получение параметров видео
fps = cap.get(cv2.CAP_PROP_FPS)
width  = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# Путь для сохранения выходного видео
output_dir = os.path.join(current_dir, 'results')
os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(output_dir, 'output.mp4')

# Настройка записи видео
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))

print("Начинаю обработку видео...")

while True:
    ret, frame = cap.read()
    if not ret:
        print("Видео завершено или не может быть прочитано.")
        break

    # Подготовка кадра для OpenCV DNN
    blob = cv2.dnn.blobFromImage(frame, scalefactor=1/255.0, size=(640, 640), swapRB=True, crop=False)
    net.setInput(blob)
    outputs = net.forward()

    # Обработка выходных данных модели
    # Формат вывода зависит от модели. В данном примере предположим, что используется модель YOLOv8.
    detections = []
    for detection in outputs[0]:
        scores = detection[5:]
        class_id = np.argmax(scores)
        confidence = scores[class_id]
        if confidence > 0.5:
            box = detection[0:4] * np.array([width, height, width, height])
            x_center, y_center, w, h = box.astype('int')
            x1 = int(x_center - w / 2)
            y1 = int(y_center - h / 2)
            detections.append(([x1, y1, w, h], float(confidence), class_id))

    # Обновление трекера
    tracks = tracker.update_tracks(detections, frame=frame)

    # Отрисовка результатов
    for track in tracks:
        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), (0, 255, 0), 2)
        cv2.putText(frame, f'ID: {track_id}', (x1, y1 - 10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

    # Запись кадра в выходное видео
    out.write(frame)

    # Отображение кадра
    cv2.imshow('YOLOv8 + Deep SORT', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        print("Обработка видео прервана пользователем.")
        break

# Освобождение ресурсов
cap.release()
out.release()
cv2.destroyAllWindows()

print(f"Обработка завершена. Сохранённый файл: {output_path}")