Merci de la recherche.
En définitive, il a fallu mixer des tutos.
Et les tutos en vidéos ne sont pas un gain de temps. Il faut patienter, lire des petits caractères sur des écrans. Bref, j’ai fais mon tuto perso, si ça peut servir.
Cordialement.
Real-recognition-raspberry-pi-usb-coral, à 25FPS
FPI, 2024-12-06
Comment exécuter YOLO sur une Raspberry Pi 4 en Python sur un accélérateur Coral USB…
D’après :
From h ttps://www.youtube.com/watch?v=A-r5RWjnf20
and h ttps://github.com/computervisioneng/real-time-license-plate-raspberry-pi-usb-coral
1 Contexte
* Sur Raspberry Pi 4
2 Installer l’OS
2.1 Version d’OS à installer
https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-64-bit
Raspberry Pi OS with desktop and recommended software
Release date: November 19th 2024
System: 64-bit
Kernel version: 6.6
Debian version: 12 (bookworm)
https://downloads.raspberrypi.com/raspios_full_arm64/images/raspios_full_arm64-2024-11-19/2024-11-19-raspios-bookworm-arm64-full.img.xz
Avec Raspberry Pi imager (https://www.raspberrypi.com/software/), flasher une carte SD avec l’OS. Personnaliser le password du compte “pi”, et votre SSID de réseau wifi.
Insérer la carte SD dans la RPI et mettre sous tension. Plusieurs reboot auront lieu.
Par défaut, Python est en 3.11.2
3 Installer les composants
3.1 Lancer une console de terminal
+ + t
3.2 Installer PYTHON 3.9.12
On veut garder les autres versions de Python, surtout si elles servent pour des outils de l'OS.
penv va permettre de gérer plusieurs versions.
sudo apt-get update
sudo apt-get upgrade
curl --insecure https://pyenv.run | bash
(à cause des problèmes de certificats)
echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
exec "$SHELL"
3.3 Installer les composants complémentaires
sudo apt-get install --yes libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libgdbm-dev lzma lzma-dev tcl-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev wget curl make build-essential openssl
C’est long mais ça marche.
3.4 Installer pyenv
pyenv install 3.9.12
pyenv est un outil très pratique pour gérer différentes versions de Python sur un système. Il permet de gérer facilement plusieurs versions de Python et de choisir laquelle utiliser pour des projets spécifiques ou à l'échelle globale du système.
pyenv local 3.9.12
Vous pouvez définir une version de Python spécifique pour un projet. Cela crée un fichier .python-version dans le répertoire du projet qui spécifie la version de Python à utiliser.
python -V
(Python 3.9.2)
* Bien que pyenv lui-même ne gère pas les environnements virtuels, il fonctionne très bien avec des outils comme venv ou virtualenv. Vous pouvez installer plusieurs versions de Python avec pyenv et utiliser ces versions pour créer des environnements virtuels spécifiques.
3.5 Créer un environnement virtuel Python dans ce répertoire de travail
Dans le répertoire où l’on veut travailler:
Purger le répertoire de travail d’un vieux répertoire “venv” et d’un fichier “.python-version”
Créer l’environnement virtuel (répertoire venv, fichier .python-version) :
$ python3 -m venv .venv
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
!!! le tiret en fin de commande compte !!!
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update
3.6 Connecter le Coral
# Now connect the USB Accelerator to your computer using the provided USB 3.0 cable.
L’accélérateur est à connecter sur un port USB 3.0 (barrette bleu)
3.7 Finir la prise en compte du Coral
Dans le répertoire de travail :
$ source .venv/bin/activate
$ pip install --extra-index-url https://google-coral.github.io/py-repo/ pycoral~=2.0
$ pip install ultralytics==8.2.73
(à voir , si on a besoin de
pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2)
3.8 Tester la reconnaissance du Coral
$ lsusb
…Global Unichip Corp
Le Coral deviendra un “Google Inc.” qu’après une première exécution.
4 Tester
4.1 Exécuter le programme:
Dans le répertoire de travail, activer l’environnement virtuel :
$ source .venv/bin/activate
Vérifier la version de Python:
$ python -V
Python 3.9.2
Lancer le programme :
$ python toto.py
4.2 Sortir de l’environnement virtuel
$ deactivate
4.3 Exemple de programme :
print(f'{__name__} starts')
import time
from datetime import datetime
import json
print(f"{datetime.now()} > import YOLO...")
from ultralytics import YOLO
print(f"{datetime.now()} > import cv2...")
import cv2
# sModel = 'license_plate_detector_int8_edgetpu.tflite'
sModel = '240_yolov8n_full_integer_quant_edgetpu.tflite'
print(f"{datetime.now()} > load model {sModel}...")
_model = YOLO(sModel, task='detect')
print(f"{datetime.now()} > open videoCapture(0)...")
cap = cv2.VideoCapture(0)
def getCapProperties(cap) :
nativeFPS = int(cap.get(cv2.CAP_PROP_FPS))
nativeFrameWidth = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
nativeFrameHeight = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
return (nativeFPS,nativeFrameWidth,nativeFrameHeight)
#EndDef
(nativeFPS,nativeFrameWidth,nativeFrameHeight) = getCapProperties(cap)
print(f"cap > nativeFPS: {nativeFPS}, nativeFrameWidth: {nativeFrameWidth}, nativeFrameHeight: {nativeFrameHeight}")
#####
def resizeImageWithRatio(image, width=None, height=None, inter=cv2.INTER_AREA) :
# Grab the image size and initialize dimensions
dim = None
(h, w) = image.shape[:2]
# Return original image if no need to resize
if width is None and height is None:
return image
#EndIf
# We are resizing height if width is none
if width is None:
# Calculate the ratio of the height and construct the dimensions
r = height / float(h)
dim = (int(w * r), height)
# We are resizing width if height is none
elif height is None :
# Calculate the ratio of the 0idth and construct the dimensions
r = width / float(w)
dim = (width, int(h * r))
else :
dim = (width, height)
#EndIf
# Return the resized image
return cv2.resize(image, dim, interpolation=inter), dim
#EndDef
"""
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 10, (frame_width, frame_height))
"""
print(f"Prepare acceptable classes...")
acceptableClassesNames = ["person","bicycle","car","motorcycle","bus","truck"]
_acceptableClassesIds = []
_dicoClasses = {}
rowClass = -1
for cn in _model.names :
rowClass += 1
if _model.names[cn] in acceptableClassesNames :
_acceptableClassesIds.append(rowClass)
print(f"rowClass: {rowClass}")
_dicoClasses[str(rowClass)] = _model.names[cn]
print(f"dico[rowClass]: {_model.names[cn]}")
#EndFor
print(f'{datetime.now()} > process starts')
ret = True
while ret:
tic = time.time()
ret, frame = cap.read()
if ret:
factor = 2.5
# from (640,480) to (256,192) (facteur 2.5)
newFrame,newSize_WH = resizeImageWithRatio(frame,256,192)
# print(f"newSize: {newSize_WH}")
startAnalysis = time.time()
# output = _model(frame, imgsz=320, verbose=False)
output = _model(newFrame, imgsz=256, verbose=False, classes = _acceptableClassesIds)
endAnalysis = time.time()
# print('IA analysis duration: %f' % (endAnalysis-startAnalysis))
for i, det in enumerate(output[0].boxes.data.tolist()):
x1, y1, x2, y2, score, class_id = det
class_id = int(class_id)
score = score * 100
if score < 0.6:
continue
className = _dicoClasses[str(class_id)]
duration = round(endAnalysis-startAnalysis,3)
x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
x1 = int(x1 * factor)
y1 = int(y1 * factor)
x2 = int(x2 * factor)
y2 = int(y2 * factor)
lineWidth = 1
objectColor = (0, 255, 0)
# rectangle around target
cv2.rectangle(frame, (x1, y1), (x2, y2), objectColor, lineWidth)
# class of target
cv2.putText(frame, f"{className}: {round(score,1)}" , (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, objectColor, lineWidth, cv2.LINE_AA)
textTileWidth = 1
# FPS
cv2.putText(frame, 'FPS: ' + str(int(1 / (time.time() - tic))), (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), textTileWidth, cv2.LINE_AA)
# computing duration
cv2.putText(frame, 'dur.: ' + str(duration), (300, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (90, 90, 90), textTileWidth, cv2.LINE_AA)
#EndFor
# out.write(frame)
cv2.imshow("FRAME", frame)
if cv2.waitKey(1) & 0xFF == 27:
break
#EndIf
#EndWhile
cap.release()
# out.release()
cv2.destroyAllWindows()
print(f'{datetime.now()} > process ends properly.')
4.4 Préparer un répertoire et les packages nécessaires pour un autre programme
Dans un nouveau répertoire :
pyenv local 3.9.12
python3 -m venv .venv
source .venv/bin/activate
python -m pip install numpy
python -m pip install websockets
python -m pip install flask
python -m pip install shapely
python -m pip install ultralytics==8.2.73
python -m pip install tensorflow
sudo apt install python3-opencv
python monprog.py
5 Obtenir un fichier modèle compatible avec le Coral, un .tflite
YOLO utilise par défaut des modèles .pt
Il faut donc les convertir en .tflite.
Plusieurs méthodes :
- Train an object detector to detect objects using yolo8 (pytorch)
- Export model to tflite par programme :
from ultralytics import YOLO
model = YOLO("file.pt")
model.export(format="tflite",imgsz=320, int8=True)
- Compile model to edgetpu (edgetpu tflite)
edge_compiler file.tflite