Premier commit du programme sur la nouvelle instance Gitea
Import des fichiers : Modifications qui seront validées : nouveau fichier : MOT20-02.mp4 nouveau fichier : README.md nouveau fichier : autoinstall.sh nouveau fichier : autostart.sh nouveau fichier : checking-camera.py nouveau fichier : main.py nouveau fichier : models/yolo11n.pt nouveau fichier : models/yolo12n.pt nouveau fichier : requirements.txt nouveau fichier : track/botsort.yaml nouveau fichier : track/bytetrack.yaml
This commit is contained in:
BIN
MOT20-02.mp4
Normal file
BIN
MOT20-02.mp4
Normal file
Binary file not shown.
100
README.md
Normal file
100
README.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Vision par ordinateur (Édition Python)
|
||||
|
||||
---
|
||||
|
||||
## Prérequis
|
||||
|
||||
- Ordinateur fixe ou portable, architecture de processeur x86/AMD64
|
||||
- Système d'exploitation Linux
|
||||
- Python 3.13.2
|
||||
|
||||
```bash
|
||||
sudo apt install -y make build-essential libssl-dev zlib1g-dev \
|
||||
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
|
||||
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
|
||||
libffi-dev liblzma-dev tk-dev libncurses5-dev libncursesw5-dev
|
||||
|
||||
# Où
|
||||
|
||||
sudo dnf install gcc zlib-devel bzip2 bzip2-devel readline-devel \
|
||||
sqlite sqlite-devel openssl-devel xz xz-devel libffi-devel \
|
||||
findutils tk-devel ncurses-devel
|
||||
```
|
||||
```bash
|
||||
curl -fsSL https://pyenv.run | bash
|
||||
|
||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
|
||||
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
|
||||
echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc
|
||||
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
|
||||
|
||||
pyenv install 3.13.2
|
||||
cd répertoire/du/projet
|
||||
pyenv local 3.13.2
|
||||
```
|
||||
|
||||
---
|
||||
Créer un environnement virtuel Python.
|
||||
```bash
|
||||
python -m venv venv
|
||||
```
|
||||
Activer l'environnement virtuel au terminal courant.
|
||||
```bash
|
||||
source venv/bin/activate
|
||||
```
|
||||
Mettre à jour Pip (pour éviter les erreurs d'installation de librairies).
|
||||
```bash
|
||||
pip install --upgrade pip
|
||||
```
|
||||
Installer les librairies nécessaires au déroulement du programme.
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
Exécuter le dialogue d'aide sur le programme principale.
|
||||
```bash
|
||||
> python main.py --help
|
||||
usage: main.py [-h] [-i INPUT] [-o OUTPUT] [-f] [-u API_URL] [-m MODELNAME] [-v]
|
||||
|
||||
options:
|
||||
-i, --input INPUT Chemin vers la vidéo à lire ('0' est à utiliser pour la webcam par défaut)
|
||||
-o, --output OUTPUT Emplacement pour enregistrer le processus dans une vidéo (Attention au RGPD, désactivé si aucun)
|
||||
-f, --force Forcer le redimensionnement du flux d'entrée.
|
||||
-u, --api-url API_URL
|
||||
Chemin réseau vers l'API (désactivé si aucun)
|
||||
-m, --model MODELNAME
|
||||
Nom complet (ou chemin) du modèle de détection à utiliser
|
||||
-v, --verbose Activer la sortie verbeuse du programme.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Démarrage automatique
|
||||
|
||||
Dans le répertoire source du projet, il y a un script bash permettant l'installation et le démarrage automatique.
|
||||
Il faut d'abord essayer le programme manuellement (avec les instructions précédentes). Si le programme est satisfaisant, le script d'auto-installation est pertinent.
|
||||
|
||||
Exécuter le script
|
||||
```bash
|
||||
./auto-install.sh
|
||||
```
|
||||
|
||||
Le script propose quels paramètres sont à activer automatiquement (pour l'exécution à l'ouverture de la session)
|
||||
```bash
|
||||
> ./autoinstall.sh
|
||||
Voulez-vous indiquer un flux d'entrée ? (oui/non): oui
|
||||
Entrez la valeur d'entrée : 4
|
||||
Voulez-vous une verbosité accrue ? (oui/non): non
|
||||
Voulez-vous forcer le redimenssionnement de l'image ? (oui/non): oui
|
||||
Voulez-vous renseigner l'URL de l'API ? (oui/non): oui
|
||||
Entrez l'URL de l'API : http://localhost:1880
|
||||
```
|
||||
|
||||
Redémarrer l'ordinateur hôte.
|
||||
```bash
|
||||
sudo reboot now
|
||||
```
|
||||
|
||||
En cas d'erreurs ou de doutes, regarder la journalisation.
|
||||
```bash
|
||||
less ~/vision-par-ordinateur-python/main.log
|
||||
```
|
||||
69
autoinstall.sh
Executable file
69
autoinstall.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Initialize variables
|
||||
START_FILE="$HOME/.config/autostart/vision-par-ordinateur-python.desktop"
|
||||
PROJECT_DIR="$HOME/vision-par-ordinateur-python"
|
||||
INPUT=""
|
||||
VERBOSE=""
|
||||
FORCE=""
|
||||
API_URL=""
|
||||
|
||||
# Load PyEnv for user
|
||||
export PYENV_ROOT="$HOME/.pyenv"
|
||||
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
|
||||
eval "$(pyenv init - bash)"
|
||||
eval "$(pyenv virtualenv-init -)"
|
||||
|
||||
# Prompt for INPUT
|
||||
read -p "Voulez-vous indiquer un flux d'entrée ? (oui/non): " input_choice
|
||||
if [[ "$input_choice" == "oui" || "$input_choice" == "o" ]]; then
|
||||
read -p "Entrez la valeur d'entrée : " INPUT
|
||||
INPUT="-i $INPUT"
|
||||
fi
|
||||
|
||||
# Prompt for VERBOSE
|
||||
read -p "Voulez-vous une verbosité accrue ? (oui/non): " verbose_choice
|
||||
if [[ "$verbose_choice" == "oui" || "$verbose_choice" == "o" ]]; then
|
||||
VERBOSE="-v"
|
||||
fi
|
||||
|
||||
# Prompt for FORCE
|
||||
read -p "Voulez-vous forcer le redimenssionnement de l'image ? (oui/non): " force_choice
|
||||
if [[ "$force_choice" == "oui" || "$force_choice" == "o" ]]; then
|
||||
FORCE="-f"
|
||||
fi
|
||||
|
||||
# Prompt for API_URL
|
||||
read -p "Voulez-vous renseigner l'URL de l'API ? (oui/non): " api_choice
|
||||
if [[ "$api_choice" == "oui" || "$api_choice" == "o" ]]; then
|
||||
read -p "Entrez l'URL de l'API : " API_URL
|
||||
API_URL="--api-url $API_URL"
|
||||
fi
|
||||
|
||||
# Construct the final command
|
||||
COMMAND="python main.py $INPUT $VERBOSE $FORCE $API_URL >> $HOME/vision-par-ordinateur-python/main.log 2>&1"
|
||||
|
||||
# Output the command to the autostart.sh file
|
||||
echo -e "$COMMAND" >> autostart.sh
|
||||
|
||||
# Make the script executable
|
||||
chmod +x autostart.sh
|
||||
|
||||
# Make the project directory and copy content
|
||||
mkdir "${PROJECT_DIR}"
|
||||
cp -r main.py autostart.sh requirements.txt models track "${PROJECT_DIR}"
|
||||
|
||||
# Install venv and requirements
|
||||
cd "${PROJECT_DIR}"
|
||||
pyenv local 3.13.2
|
||||
python -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Auto start program settings
|
||||
mkdir -p ~/.config/autostart
|
||||
touch "${START_FILE}"
|
||||
echo -e "[Desktop Entry]\nType=Application\nExec=${HOME}/vision-par-ordinateur-python/autostart.sh\nHidden=false\nNoDisplay=false\nX-GNOME-Autostart-enabled=true\nName=Vision par ordinateur\nComment=Lance le script Python pour la vision par ordinateur" >> "${START_FILE}"
|
||||
|
||||
echo -e "L'installation du programme et du démarrage automatique est terminé.\nVeuillez redémarrer l'ordinateur pour démarrer la vision par ordinateur automatiquement."
|
||||
11
autostart.sh
Executable file
11
autostart.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd ~
|
||||
export PYENV_ROOT="$HOME/.pyenv"
|
||||
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
|
||||
eval "$(pyenv init - bash)"
|
||||
eval "$(pyenv virtualenv-init -)"
|
||||
|
||||
cd ~/vision-par-ordinateur-python
|
||||
source venv/bin/activate
|
||||
|
||||
4
checking-camera.py
Normal file
4
checking-camera.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from cv2_enumerate_cameras import enumerate_cameras
|
||||
|
||||
for camera_info in enumerate_cameras():
|
||||
print(f'{camera_info.index}: {camera_info.name}')
|
||||
285
main.py
Normal file
285
main.py
Normal file
@@ -0,0 +1,285 @@
|
||||
import time
|
||||
import json
|
||||
import asyncio
|
||||
import aiohttp
|
||||
import ssl
|
||||
import requests
|
||||
from datetime import date
|
||||
from collections import defaultdict
|
||||
import cv2
|
||||
import numpy as np
|
||||
import argparse
|
||||
import sys
|
||||
from ultralytics import YOLO
|
||||
|
||||
# Declare video file to read with parameter
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-i", "--input", dest="input", default=0, help="Chemin vers la vidéo à lire ('0' est à utiliser pour la webcam par défaut)")
|
||||
parser.add_argument("-o", "--output", dest="output", default="", help="Emplacement pour enregistrer le processus dans une vidéo (Attention au RGPD, désactivé si aucun)")
|
||||
parser.add_argument("-f", "--force", action='store_true', help="Forcer le redimensionnement du flux d'entrée")
|
||||
parser.add_argument("-u", "--api-url", dest="API_URL", default="", help="Chemin réseau vers l'API (désactivé si aucun)")
|
||||
parser.add_argument("-m", "--model", dest="modelname", default="yolo12n.pt", help="Nom complet du modèle de détection à utiliser (répertoire 'models/')")
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help='Activer la sortie verbeuse du programme.')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Initialize verbose mode
|
||||
if args.verbose:
|
||||
print("Mode verbeux activé")
|
||||
time_mid_list = []
|
||||
time_end_list = []
|
||||
fps_list = []
|
||||
|
||||
# Initialize API variables
|
||||
API_URL_EVENT = args.API_URL + "/api/c_auto"
|
||||
API_URL_POS = args.API_URL + "/api/p_auto"
|
||||
API_URL_STATUS = args.API_URL + "/api/status"
|
||||
|
||||
# Declare interval variable to get status
|
||||
STATUS_CHECK_INTERVAL = 10
|
||||
|
||||
# Define function to get API event status
|
||||
async def get_status(session):
|
||||
try:
|
||||
async with session.get(API_URL_STATUS) as response:
|
||||
response.raise_for_status()
|
||||
data = await response.text()
|
||||
return int(data)
|
||||
except aiohttp.ClientError as e:
|
||||
print(f"Impossible d'obtenir l'état: {e}")
|
||||
|
||||
# Define event API requests function
|
||||
async def send_event(session, action, people_count, person_id, verbose=False):
|
||||
payload = [{"action": action, "people": people_count}, {"id": person_id}]
|
||||
try:
|
||||
async with session.post(API_URL_EVENT, json=payload) as response:
|
||||
response.raise_for_status()
|
||||
if verbose:
|
||||
print(f"Requête action {action} pour l'id:{person_id} avec {people_count} visitors")
|
||||
except aiohttp.ClientError as e:
|
||||
print(f"Impossible d'envoyer l'action {action} de l'id:{person_id}: {e}")
|
||||
|
||||
# Define position API requests function
|
||||
async def send_position(session, positions, verbose=False):
|
||||
try:
|
||||
async with session.post(API_URL_POS, json=positions) as response:
|
||||
response.raise_for_status()
|
||||
if verbose:
|
||||
print(f"Positions envoyées : {len(positions)}")
|
||||
except aiohttp.ClientError as e:
|
||||
print(f"Impossible d'envoyer les positions: {e}")
|
||||
|
||||
# Store the track history
|
||||
track_history = defaultdict(lambda: [])
|
||||
|
||||
# Create asyncio event loop
|
||||
async def main_loop():
|
||||
# Initialize FPS measurement
|
||||
if args.verbose:
|
||||
prev_time_fps = time.time()
|
||||
|
||||
# Define for the first time last_position_sent
|
||||
try:
|
||||
last_position_sent
|
||||
except NameError:
|
||||
last_position_sent = int(time.time())
|
||||
|
||||
# Patch public variable
|
||||
current_people = set()
|
||||
|
||||
# Define for the first time last_status_check
|
||||
try:
|
||||
last_status_check
|
||||
except NameError:
|
||||
last_status_check = int(time.time()) - STATUS_CHECK_INTERVAL
|
||||
|
||||
# Variable for status and det/track by default
|
||||
if args.API_URL:
|
||||
status = 0
|
||||
else:
|
||||
status = 1
|
||||
model = None
|
||||
cap = None
|
||||
video_writer = None
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
while True:
|
||||
# Check status at the defined interval
|
||||
if args.API_URL:
|
||||
if time.time() - last_status_check >= STATUS_CHECK_INTERVAL:
|
||||
status = await get_status(session)
|
||||
last_status_check = time.time()
|
||||
if args.verbose:
|
||||
print(f"État mis à jour: {status}")
|
||||
|
||||
# Clear everything and wait for other status
|
||||
if status == 0 or not status:
|
||||
if cap:
|
||||
cap.release()
|
||||
cap = None
|
||||
if video_writer:
|
||||
video_writer.release()
|
||||
video_writer = None
|
||||
cv2.destroyAllWindows()
|
||||
if args.verbose:
|
||||
print("Ressources libérées/détruites. Dans l'attente de l'état 1 pour redémarrer.")
|
||||
# Prevent CPU overload
|
||||
await asyncio.sleep(1)
|
||||
continue
|
||||
|
||||
# Skip if status is 0
|
||||
if status == 2:
|
||||
if current_people and args.API_URL:
|
||||
for person_id in current_people:
|
||||
await send_event(session, "exit", 0, person_id, args.verbose)
|
||||
current_people.clear()
|
||||
if args.verbose:
|
||||
print("État 2 reçu: Envoi de l'action de sortie pour tous les ID encore actifs.")
|
||||
await asyncio.sleep(1)
|
||||
continue
|
||||
|
||||
# Initialize model and video capture if status is 1
|
||||
if status == 1 and not cap:
|
||||
model = YOLO(f"models/{args.modelname}")
|
||||
if args.verbose:
|
||||
print(f"Modèle YOLO chargé: models/{args.modelname}")
|
||||
|
||||
try:
|
||||
input_value = int(args.input)
|
||||
cap = cv2.VideoCapture(input_value)
|
||||
except ValueError:
|
||||
cap = cv2.VideoCapture(args.input, cv2.CAP_FFMPEG)
|
||||
|
||||
if not cap.isOpened():
|
||||
print("Erreur: Impossible d'ouvrir le flux vidéo.")
|
||||
sys.exit(1)
|
||||
|
||||
if args.force:
|
||||
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
|
||||
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
|
||||
|
||||
if args.output:
|
||||
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
|
||||
video_writer = cv2.VideoWriter(args.output, cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
|
||||
|
||||
if args.verbose:
|
||||
print("Capture vidéo initialisée.")
|
||||
|
||||
# Skip if no video capture is open
|
||||
if not cap:
|
||||
await asyncio.sleep(1)
|
||||
continue
|
||||
|
||||
# Read frame and process
|
||||
success, frame = cap.read()
|
||||
if not success:
|
||||
print("Erreur: Impossible de lire le flux vidéo. Libération des ressources.")
|
||||
status = 0 # Force reset
|
||||
continue
|
||||
|
||||
# declare start timing variable
|
||||
if args.verbose:
|
||||
time_start = time.time()
|
||||
|
||||
# Run YOLO tracking on the frame
|
||||
results = model.track(frame, persist=True, classes=[0], tracker="track/botsort.yaml", verbose=False)
|
||||
annotated_frame = results[0].plot()
|
||||
|
||||
# declare mid timing variable
|
||||
if args.verbose:
|
||||
time_mid = time.time()
|
||||
|
||||
new_people = set()
|
||||
tasks = []
|
||||
pos_tasks = []
|
||||
|
||||
if results[0].boxes.id is not None:
|
||||
boxes = results[0].boxes.xywh.cpu()
|
||||
track_ids = results[0].boxes.id.int().cpu().tolist()
|
||||
|
||||
for box, track_id in zip(boxes, track_ids):
|
||||
x, y, w, h = box
|
||||
track = track_history[track_id]
|
||||
track.append((float(x), float(y)))
|
||||
if len(track) > 30:
|
||||
track.pop(0)
|
||||
|
||||
new_people.add(track_id)
|
||||
|
||||
# Detect entries and exits
|
||||
entered = new_people - current_people
|
||||
exited = current_people - new_people
|
||||
|
||||
# Send event to API for each ID
|
||||
if args.API_URL and status == 1:
|
||||
for person_id in entered:
|
||||
tasks.append(send_event(session, "enter", len(new_people), person_id, args.verbose))
|
||||
for person_id in exited:
|
||||
tasks.append(send_event(session, "exit", len(new_people), person_id, args.verbose))
|
||||
|
||||
# Send position to API for each ID
|
||||
if args.API_URL and status == 1:
|
||||
if int(time.time()) >= (last_position_sent+1):
|
||||
payload_positions = []
|
||||
height_img, width_img = annotated_frame.shape[:2]
|
||||
boxes_n = results[0].boxes.xywh.cpu()
|
||||
for box, track_id in zip(boxes_n, track_ids):
|
||||
x, y, w, h = [float(coord.item()) for coord in box]
|
||||
x = (x-(w/2)) / width_img
|
||||
y = (y-(h/2)) / height_img
|
||||
w = w / width_img
|
||||
h = h / height_img
|
||||
payload_positions.append([{"pos_x": round(x, 4), "pos_y": round(y, 4), "w": round(w, 4), "h": round(h, 4)}, {"id": track_id}])
|
||||
last_position_sent = int(time.time())
|
||||
pos_tasks.append(send_position(session, payload_positions, args.verbose))
|
||||
|
||||
current_people = new_people
|
||||
else:
|
||||
# No people detected, send exit event for all remaining
|
||||
if current_people and status == 1:
|
||||
if args.API_URL:
|
||||
for person_id in current_people:
|
||||
tasks.append(send_event(session, "exit", 0, person_id, args.verbose))
|
||||
current_people = set()
|
||||
|
||||
# Await all API calls concurrently
|
||||
if tasks:
|
||||
await asyncio.gather(*tasks)
|
||||
if pos_tasks:
|
||||
await asyncio.gather(*pos_tasks)
|
||||
|
||||
# Math FPS
|
||||
if args.verbose:
|
||||
time_end = time.time()
|
||||
fps_display = int(1 / (time_end - prev_time_fps))
|
||||
prev_time_fps = time_end
|
||||
|
||||
# Math MS
|
||||
time_mid_temp = round((time_mid - time_start)*1000 , 1)
|
||||
time_end_temp = round((time_end - time_mid)*1000 , 1)
|
||||
time_mid_list.append(time_mid_temp)
|
||||
time_end_list.append(time_end_temp)
|
||||
fps_list.append(fps_display)
|
||||
|
||||
# Print iteration measurements
|
||||
print(f"Temps de réponse détection/suivi: {time_mid_temp}\nTemps de réponse dessin: {time_end_temp}\nTemps de travail total: {round(time_mid_temp + time_end_temp, 4)}\nImages par seconde: {fps_display}\n-------------------------")
|
||||
|
||||
# Prepare OpenCV to print
|
||||
cv2.putText(annotated_frame, f"Nombre visiteurs: {len(current_people)}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
|
||||
cv2.imshow("Vision par ordinateur - Python", annotated_frame)
|
||||
if args.output:
|
||||
video_writer.write(annotated_frame)
|
||||
|
||||
if cv2.waitKey(1) & 0xFF == ord("q"):
|
||||
if cap:
|
||||
cap.release()
|
||||
if video_writer:
|
||||
video_writer.release()
|
||||
cv2.destroyAllWindows()
|
||||
break
|
||||
|
||||
# Run the async main loop
|
||||
asyncio.run(main_loop())
|
||||
|
||||
# Print Summary
|
||||
if args.verbose and time_mid_list:
|
||||
print(f"Rapport de performances:\nTemps de réponse moyen détection/suivi: {round(sum(time_mid_list) / len(time_mid_list), 1)}\nTemps de réponse moyen dessin: {round(sum(time_end_list) / len(time_end_list), 1)}\nTemps de réponse moyen: {round((sum(time_mid_list) / len(time_mid_list)) + (sum(time_end_list) / len(time_end_list)), 1)}\nMoyenne images par seconde: {round(sum(fps_list) / len(fps_list), 2)}")
|
||||
BIN
models/yolo11n.pt
Normal file
BIN
models/yolo11n.pt
Normal file
Binary file not shown.
BIN
models/yolo12n.pt
Normal file
BIN
models/yolo12n.pt
Normal file
Binary file not shown.
62
requirements.txt
Normal file
62
requirements.txt
Normal file
@@ -0,0 +1,62 @@
|
||||
aiohappyeyeballs==2.6.1
|
||||
aiohttp==3.12.7
|
||||
aiosignal==1.3.2
|
||||
attrs==25.3.0
|
||||
certifi==2025.4.26
|
||||
charset-normalizer==3.4.2
|
||||
contourpy==1.3.2
|
||||
cycler==0.12.1
|
||||
filelock==3.18.0
|
||||
fonttools==4.58.1
|
||||
frozenlist==1.6.0
|
||||
fsspec==2025.5.1
|
||||
idna==3.10
|
||||
Jinja2==3.1.6
|
||||
kiwisolver==1.4.8
|
||||
lap==0.5.12
|
||||
MarkupSafe==3.0.2
|
||||
matplotlib==3.10.3
|
||||
mpmath==1.3.0
|
||||
multidict==6.4.4
|
||||
networkx==3.5
|
||||
numpy==2.2.6
|
||||
nvidia-cublas-cu12==12.6.4.1
|
||||
nvidia-cuda-cupti-cu12==12.6.80
|
||||
nvidia-cuda-nvrtc-cu12==12.6.77
|
||||
nvidia-cuda-runtime-cu12==12.6.77
|
||||
nvidia-cudnn-cu12==9.5.1.17
|
||||
nvidia-cufft-cu12==11.3.0.4
|
||||
nvidia-cufile-cu12==1.11.1.6
|
||||
nvidia-curand-cu12==10.3.7.77
|
||||
nvidia-cusolver-cu12==11.7.1.2
|
||||
nvidia-cusparse-cu12==12.5.4.2
|
||||
nvidia-cusparselt-cu12==0.6.3
|
||||
nvidia-nccl-cu12==2.26.2
|
||||
nvidia-nvjitlink-cu12==12.6.85
|
||||
nvidia-nvtx-cu12==12.6.77
|
||||
opencv-python==4.11.0.86
|
||||
packaging==25.0
|
||||
pandas==2.2.3
|
||||
pillow==11.2.1
|
||||
propcache==0.3.1
|
||||
psutil==7.0.0
|
||||
py-cpuinfo==9.0.0
|
||||
pyparsing==3.2.3
|
||||
python-dateutil==2.9.0.post0
|
||||
pytz==2025.2
|
||||
PyYAML==6.0.2
|
||||
requests==2.32.3
|
||||
scipy==1.15.3
|
||||
setuptools==80.9.0
|
||||
six==1.17.0
|
||||
sympy==1.14.0
|
||||
torch==2.7.0
|
||||
torchvision==0.22.0
|
||||
tqdm==4.67.1
|
||||
triton==3.3.0
|
||||
typing_extensions==4.14.0
|
||||
tzdata==2025.2
|
||||
ultralytics==8.3.148
|
||||
ultralytics-thop==2.0.14
|
||||
urllib3==2.4.0
|
||||
yarl==1.20.0
|
||||
21
track/botsort.yaml
Normal file
21
track/botsort.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
||||
|
||||
# Default Ultralytics settings for BoT-SORT tracker when using mode="track"
|
||||
# For documentation and examples see https://docs.ultralytics.com/modes/track/
|
||||
# For BoT-SORT source code see https://github.com/NirAharon/BoT-SORT
|
||||
|
||||
tracker_type: botsort # tracker type, ['botsort', 'bytetrack']
|
||||
track_high_thresh: 0.25 # threshold for the first association
|
||||
track_low_thresh: 0.1 # threshold for the second association
|
||||
new_track_thresh: 0.25 # threshold for init new track if the detection does not match any tracks
|
||||
track_buffer: 30 # buffer to calculate the time when to remove tracks
|
||||
match_thresh: 0.8 # threshold for matching tracks
|
||||
fuse_score: True # Whether to fuse confidence scores with the iou distances before matching
|
||||
# min_box_area: 10 # threshold for min box areas(for tracker evaluation, not used for now)
|
||||
|
||||
# BoT-SORT settings
|
||||
gmc_method: sparseOptFlow # method of global motion compensation
|
||||
# ReID model related thresh (not supported yet)
|
||||
proximity_thresh: 0.5
|
||||
appearance_thresh: 0.25
|
||||
with_reid: False
|
||||
14
track/bytetrack.yaml
Normal file
14
track/bytetrack.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
||||
|
||||
# Default Ultralytics settings for ByteTrack tracker when using mode="track"
|
||||
# For documentation and examples see https://docs.ultralytics.com/modes/track/
|
||||
# For ByteTrack source code see https://github.com/ifzhang/ByteTrack
|
||||
|
||||
tracker_type: bytetrack # tracker type, ['botsort', 'bytetrack']
|
||||
track_high_thresh: 0.25 # threshold for the first association
|
||||
track_low_thresh: 0.1 # threshold for the second association
|
||||
new_track_thresh: 0.25 # threshold for init new track if the detection does not match any tracks
|
||||
track_buffer: 30 # buffer to calculate the time when to remove tracks
|
||||
match_thresh: 0.8 # threshold for matching tracks
|
||||
fuse_score: True # Whether to fuse confidence scores with the iou distances before matching
|
||||
# min_box_area: 10 # threshold for min box areas(for tracker evaluation, not used for now)
|
||||
Reference in New Issue
Block a user