Utiliser YOLO8 avec un accélérateur Coral usb avec raspberry pi 4

Bonjour,
Déjà trois journées de 8h à chercher comment…« faire tourner YOLO8 sur une Raspberry Pi 4 avec un accélérateur Coral USB » !
Tous les tutos testés, mixés, mélangés, se heurte à des release de paquets non disponibles.

  1. Déjà, est-ce que quelqu’un a déjà réussi réellement ?
  2. Quelles sont les contraintes qui seule permettent de le faire : a) Version de Raspbian, b) Version de Python, C) version de YOLO ?
  3. Quels sont les paquets qu’il faut compiler parce que la release n’existe pas dans les repository ?
    Bref, comment ne pas se lancer dans le test de toutes les combinatoires et obtenir un résultat.

Les principaux blocages se situent sur:

  • « sudo apt-get install edgetpu-compiler »
  • « lsusb » donne que le device peut apparaître comme fabriqué par “Global Unichip Corp.”

Note : YOLO8 avec Python 3.9.2 sur Raspberry Pi 4, Operating System: Debian GNU/Linux 11 (bullseye), Kernel: Linux 6.1.21-v8+, Architecture: arm64, ca fonctionne (c’est déjà ça).

Merci pour votre attention,
Cordialement.

hello,

sur cette video la détection d’image avec rpi4 + cora usb + python 3.9.12 + yolov8

simply !

1 « J'aime »

Merci beaucoup, je désespérais.
Encore un point : ce tuto ne traite pas de la conversion d’un modèle yolo (extension .pt) pour obtenir un .tflite.
Comme je n’arrive pas obtenir le « edgetpu-compiler », et comme pour faire la conversion par code, il faut tensorflow-addons, qui ne s’installe pas, je suis bloqué sur cette conversion:
`
print(f"Début du programme…")
import os
import os.path

def printFileSize(fullFilePath) :
file_stats = os.stat(fullFilePath)
print(f"{fullFilePath}> {file_stats.st_size / (1024 * 1024)} Mb")
#EndDef

print(f"import ultralytics…")
from ultralytics import YOLO

if os.path.isfile(« ./yolov8n.onnx ») != True :
…print(f"Charger le modèle YOLOv8…« )
…model = YOLO( »./yolov8n.pt") # ou tout autre modèle YOLOv8
…print(f"Exporter vers ONNX…")
…model.export(format=« onnx »)
#EndIf

printFileSize(« ./yolov8n.onnx »)

print(f"import onnx")
import onnx
print(f"load yolov8n.onnx…« )
onnx_model = onnx.load( »./yolov8n.onnx")

print(f"import prepare…;« )
from onnx_tf.backend import prepare
print(f"prepare onnx model… »)
tf_rep = prepare(onnx_model)

print(f"export tflite model…« )
tf_rep.export_graph( »./yolov8n.tf")

print(f"import tensorflow…")
import tensorflow as tf

# L’installation : python3 -m pip install tensorflow-addons >>> échoue

import tensorflow_addons as tf_addons

# Convert the model

print(f"converter…« )
converter = tf.lite.TFLiteConverter.from_saved_model( »./yolov8n.tf")
print(f"…to tflite")
tflite_model = converter.convert()

# Save the converted model

print(f"save tflite…« )
with open( »./yolov8n.tflite", ‹ wb ›) as f:
…f.write(tflite_model)
#EndWith

print(f"Fin du programme.")
`
Cordialement

peut être avec cette page :

ou celle là

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
1 « J'aime »