- Componenti richiesti
- YOLO
- Installazione di OpenCV in Raspberry Pi
- Installazione di altri pacchetti richiesti in Raspberry Pi
- Spiegazione del programma
- Testare il progetto Social Distance Detector
Al tempo del Covid-19, il distanziamento sociale è un modo efficace per rallentare la trasmissione del virus infettivo. Si consiglia alle persone di ridurre al minimo il contatto tra loro per ridurre al minimo il rischio di trasmissione della malattia attraverso il contatto diretto. Mantenere una distanza di sicurezza è una sfida per molti luoghi come fabbriche, banche, autobus o stazioni ferroviarie, ecc.
Quindi, in continuazione dei nostri precedenti progetti di sicurezza Corona come la macchina disinfettante automatica e il monitoraggio della temperatura senza contatto, qui costruiremo un sistema di rilevamento delle distanze sociali utilizzando OpenCV e Raspberry Pi. Useremo i pesi dell'algoritmo di rilevamento degli oggetti YOLO v3 con il modulo Deep Neural Network.
Raspberry Pi è sempre una buona scelta per i progetti di elaborazione delle immagini in quanto ha più memoria e velocità rispetto ad altri controller. In precedenza abbiamo utilizzato Raspberry Pi per alcuni progetti complessi di elaborazione delle immagini come il rilevamento di punti di riferimento facciali e l'applicazione di riconoscimento facciale.
Componenti richiesti
- Raspberry Pi 4
Qui abbiamo solo bisogno di RPi 4 con OpenCV installato su di esso. OpenCV viene utilizzato qui per l'elaborazione delle immagini digitali. Le applicazioni più comuni dell'elaborazione digitale delle immagini sono il rilevamento di oggetti, il riconoscimento dei volti e il contatore di persone.
YOLO
YOLO (You Only Look Once) è una rete neurale convoluzione intelligente (CNN) per il rilevamento di oggetti in tempo reale. YOLOv3, l'ultima variante dell'algoritmo di rilevamento degli oggetti, YOLO può riconoscere 80 oggetti diversi in immagini e video, è super veloce e ha un'eccellente precisione. L'algoritmo applica una singola rete neurale all'intera immagine, quindi separa l'immagine in regioni e calcola i riquadri di confine e le probabilità per ciascuna area. Il modello YOLO base può elaborare le immagini in tempo reale a 45 fotogrammi al secondo. Il modello YOLO supera tutti gli altri metodi di rilevamento come SSD e R-CNN.
Il modello YOLOV3 che utilizzeremo in questo progetto può essere scaricato da qui.
Installazione di OpenCV in Raspberry Pi
Prima di installare OpenCV e altre dipendenze, il Raspberry Pi deve essere completamente aggiornato. Usa i seguenti comandi per aggiornare il Raspberry Pi alla sua ultima versione:
sudo apt-get update
Quindi utilizza i seguenti comandi per installare le dipendenze richieste per l'installazione di OpenCV sul tuo Raspberry Pi.
sudo apt-get install libhdf5-dev -y sudo apt-get install libhdf5-serial-dev –y sudo apt-get install libatlas-base-dev –y sudo apt-get install libjasper-dev -y sudo apt-get install libqtgui4 –Y sudo apt-get install libqt4-test –y
Infine, installa OpenCV su Raspberry Pi utilizzando i comandi seguenti.
pip3 installa opencv-contrib-python == 4.1.0.25
Se sei nuovo su OpenCV, controlla i nostri precedenti tutorial OpenCV con Raspberry pi:
- Installazione di OpenCV su Raspberry Pi utilizzando CMake
- Riconoscimento facciale in tempo reale con Raspberry Pi e OpenCV
- Riconoscimento della targa utilizzando Raspberry Pi e OpenCV
- Stima delle dimensioni della folla utilizzando OpenCV e Raspberry Pi
Abbiamo anche creato una serie di tutorial OpenCV partendo dal livello principiante.
Installazione di altri pacchetti richiesti in Raspberry Pi
Prima di programmare il Raspberry Pi per il rilevatore di distanza sociale, installiamo gli altri pacchetti richiesti.
Installazione di imutils: imutils viene utilizzato per rendere più semplici le funzioni essenziali di elaborazione delle immagini come la traduzione, la rotazione, il ridimensionamento, la scheletrizzazione e la visualizzazione delle immagini Matplotlib con OpenCV. Usa il comando seguente per installare imutils:
pip3 installa imutils
Spiegazione del programma
Il codice completo è fornito alla fine della pagina. Qui stiamo spiegando le sezioni importanti del codice per una migliore spiegazione.
Quindi, all'inizio del codice, importa tutte le librerie richieste che verranno utilizzate in questo progetto.
import numpy as np import cv2 import imutils import os import time
La funzione Check () viene utilizzata per calcolare la distanza tra due oggetti o due punti in un fotogramma di video. I punti un e b indicano i due oggetti nel frame. Questi due punti vengono utilizzati per calcolare la distanza euclidea tra gli oggetti.
def Verifica (a, b): dist = ((a - b) ** 2 + 550 / ((a + b) / 2) * (a - b) ** 2) ** 0.5 calibrazione = (a + b) / 2 se 0 <dist <0,25 * calibrazione: restituisce True altrimenti: restituisce False
La funzione di configurazione viene utilizzata per impostare i percorsi per i pesi YOLO, il file cfg, il file dei nomi COCO. Il modulo os.path viene utilizzato per la manipolazione del nome del percorso comune. Il modulo os.path.join () è un sottomodulo di os.path e viene utilizzato per unire uno o più componenti del percorso in modo intelligente. Il metodo cv2.dnn.readNetFromDarknet () viene utilizzato per caricare i pesi salvati nella rete. Dopo aver caricato i pesi, estrai l'elenco di tutti i layer utilizzati in una rete utilizzando un modello net.getLayerNames .
def Setup (yolo): global neural_net, ln, LABELS weights = os.path.sep.join () config = os.path.sep.join () labelsPath = os.path.sep.join () LABELS = open (labelsPath).read (). strip (). split ("\ n") neural_net = cv2.dnn.readNetFromDarknet (config, weights) ln = neural_net.getLayerNames () ln = - 1] for i in neural_net.getUnconnectedOutLayers ()]
All'interno della funzione di elaborazione delle immagini, prendiamo un singolo fotogramma di video e quindi lo elaboriamo per il rilevamento della distanza sociale tra ogni persona nella folla. Nelle prime due righe della funzione, impostiamo inizialmente le dimensioni del fotogramma video (L, A) come (Nessuno, Nessuno). Nella riga successiva, abbiamo utilizzato il metodo cv2.dnn.blobFromImage () per caricare i frame in un batch ed eseguirli attraverso la rete. La funzione blob esegue la sottrazione della media, il ridimensionamento e lo scambio di canali su un frame.
(H, W) = (None, None) frame = image.copy () se W è None o H è None: (H, W) = frame.shape blob = cv2.dnn.blobFromImage (frame, 1 / 255.0, (416, 416), swapRB = True, crop = False) neural_net.setInput (blob) starttime = time.time () layerOutputs = neural_net.forward (ln)
Gli output del livello di YOLO sono costituiti da un insieme di valori. Questi valori ci aiutano a definire quale oggetto appartiene a quale classe . Eseguiamo un ciclo su ogni output in layerOutputs e mentre rileviamo le persone, impostiamo l'etichetta della classe come "person". Da ogni rilevamento, otteniamo un riquadro di delimitazione che ci fornisce il centro X, il centro Y, la larghezza e l'altezza del riquadro per il rilevamento nell'output:
punteggi = rilevamento maxi_class = np.argmax (punteggi) confidenza = punteggi se LABELS == "persona": se confidenza> 0,5: box = detection * np.array () (centerX, centerY, width, height) = box.astype ("int") x = int (centerX - (width / 2)) y = int (centerY - (height / 2)) outline.append () confidences.append (float (confidenza))
Successivamente, calcola la distanza tra il centro della casella corrente e tutte le altre caselle rilevate. Se i riquadri di delimitazione sono vicini, modificare lo stato in true.
for i in range (len (center)): for j in range (len (center)): close = Check (center, center) if close: pair.append (, center]) status = True status = True index = 0
Nelle righe successive, disegna un rettangolo attorno alla persona utilizzando le dimensioni della scatola che abbiamo ricevuto dal modello, quindi controlla se la scatola è sicura o meno. Se la distanza tra le scatole è vicina, il colore della scatola sarà di colore rosso altrimenti la scatola sarà di colore verde.
(x, y) = (outline, outline) (w, h) = (outline, outline) if status == True: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 0, 150), 2) stato elif == False: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
Ora all'interno della funzione loop , stiamo leggendo ogni frame del video e quindi elaborando ogni frame per calcolare la distanza tra le persone.
ret, frame = cap.read () if not ret: break current_img = frame.copy () current_img = imutils.resize (current_img, width = 480) video = current_img.shape frameno + = 1 if (frameno% 2 == 0 o frameno == 1): Setup (yolo) ImageProcess (current_img) Frame = processingImg
Nelle righe successive, utilizzare la funzione cv2.VideoWriter () per memorizzare il video di output nella posizione specificata da opname che abbiamo definito in precedenza.
se create è Nessuno: fourcc = cv2.VideoWriter_fourcc (* 'XVID') create = cv2.VideoWriter (opname, fourcc, 30, (Frame.shape, Frame.shape), True) create.write (Frame)
Testare il progetto Social Distance Detector
Una volta che il codice è pronto, apri un terminale Pi e vai alla directory del progetto. Il codice, il modello Yolo e il video dimostrativo dovrebbero trovarsi nella stessa cartella mostrata di seguito.
Puoi scaricare la directory YoloV3 da qui, i video da Pexels e copiare il codice Python fornito di seguito e metterli nella stessa directory mostrata sopra.
Una volta che sei nella directory del progetto, esegui il seguente comando per avviare il codice:
python3 detector.py
Ho provato questo codice su un esempio video ottenuto da Pexels. Per me, l'FPS era molto lento e ci sono voluti circa 10-11 minuti per elaborare l'intero video.
Invece di utilizzare un video, si può anche verificare questo codice con un obiettivo Raspberry Pi sostituendo il cv2.VideoCapture (ingresso) con cv2.VideoCapture (0) in 98 esima riga del codice. Ulteriori informazioni sull'utilizzo di PiCamera con Raspberry Pi seguendo il collegamento.
È così che puoi utilizzare OpenCV con Raspberry Pi per rilevare le violazioni di distanza sociale. Il video e il codice di output sono riportati di seguito: