- Komponenter krävs
- YOLO
- Installerar OpenCV i Raspberry Pi
- Installera andra obligatoriska paket i Raspberry Pi
- Programförklaring
- Testa projektet för social avståndsdetektor
Under tiden för Covid-19 är social distansering ett effektivt sätt att bromsa överföringen av infektiöst virus. Människor uppmanas att minimera sin kontakt med varandra för att minimera risken för att sjukdomen överförs genom direktkontakt. Att hålla ett säkert avstånd är en utmaning för många platser som fabriker, banker, bussar eller järnvägsstationer etc.
Så i fortsättning på våra tidigare Corona-säkerhetsprojekt som automatisk desinfektionsmaskin och kontaktlös temperaturövervakning, här ska vi bygga ett Social Distancing Detector-system med OpenCV och Raspberry Pi. Vi använder vikterna i YOLO v3-objektdetekteringsalgoritmen med Deep Neural Network-modulen.
Raspberry Pi är alltid ett bra val för bildbearbetningsprojekt eftersom det har mer minne och snabbhet än andra styrenheter. Vi använde tidigare Raspberry Pi för några komplexa bildbehandlingsprojekt som ansiktsigenkänning och ansiktsigenkänning.
Komponenter krävs
- Raspberry Pi 4
Här behöver vi bara RPi 4 med OpenCV installerat på den. OpenCV används här för digital bildbehandling. De vanligaste applikationerna för digital bildbehandling är objektdetektering, ansiktsigenkänning och personräknare.
YOLO
YOLO (You Only Look Once) är ett smart Convolution neural network (CNN) för objektidentifiering i realtid. YOLOv3, den senaste varianten av objektdetekteringsalgoritmen, kan YOLO känna igen 80 olika objekt i bilder och videor, och den är supersnabb och har utmärkt noggrannhet. Algoritmen tillämpar ett enda neuralt nätverk på hela bilden och delar sedan bilden i regioner och beräknar gränsrutor och sannolikheter för varje område. Base YOLO-modellen kan bearbeta bilder i realtid med 45 bilder per sekund. YOLO-modellen överträffar alla andra detektionsmetoder som SSD och R-CNN.
YOLOV3-modellen som vi ska använda i detta projekt kan laddas ner härifrån.
Installerar OpenCV i Raspberry Pi
Innan du installerar OpenCV och andra beroenden måste Raspberry Pi uppdateras fullständigt. Använd kommandona nedan för att uppdatera Raspberry Pi till den senaste versionen:
sudo apt-get uppdatering
Använd sedan följande kommandon för att installera de beroenden som krävs för att installera OpenCV på din 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
Slutligen installerar du OpenCV på Raspberry Pi med hjälp av kommandona nedan.
pip3 installera opencv-contrib-python == 4.1.0.25
Om du är ny på OpenCV, kolla in våra tidigare OpenCV-självstudier med Raspberry pi:
- Installera OpenCV på Raspberry Pi med CMake
- Ansiktsigenkänning i realtid med Raspberry Pi och OpenCV
- Registrering av registreringsskylt med Raspberry Pi och OpenCV
- Uppskattning av publikstorlek med OpenCV och Raspberry Pi
Vi har också skapat en serie OpenCV-självstudier med början från nybörjarnivån.
Installera andra obligatoriska paket i Raspberry Pi
Innan vi programmerar Raspberry Pi för social avståndsdetektor, låt oss installera de andra nödvändiga paketen.
Installera imutils: imutils används för att göra viktiga bildbehandlingsfunktioner som översättning, rotation, storleksändring, skelettisering och visa Matplotlib-bilder enklare med OpenCV. Använd kommandot nedan för att installera imutils:
pip3 installera imutils
Programförklaring
Komplett kod ges i slutet av sidan. Här förklarar vi de viktiga delarna av koden för en bättre förklaring.
Så i början av koden importerar du alla nödvändiga bibliotek som ska användas i det här projektet.
import numpy som np import cv2 import imutils import os importtid
Den Check () funktion används för att beräkna avståndet mellan två objekt eller två punkter i en ram av video. Punkterna a och b betecknar de två objekten i ramen. Dessa två punkter används för att beräkna det euklidiska avståndet mellan objekten.
def Kontrollera (a, b): dist = ((a - b) ** 2 + 550 / ((a + b) / 2) * (a - b) ** 2) ** 0,5 kalibrering = (a + b) / 2 om 0 <dist <0,25 * kalibrering: retur Sannast annat: returnera Falskt
Inställningsfunktionen används för att ställa in sökvägar för YOLO-vikter, cfg-fil, COCO-namnfil. os.path- modulen används för vanlig manipulation av sökvägen. os.path.join () -modulen är en undermodul till os.path och används för att ansluta en eller flera bankomponenter på ett intelligent sätt. Metoden cv2.dnn.readNetFromDarknet () används för att ladda de sparade vikterna i nätverket. När du har laddat vikterna extraherar du listan över alla lager som används i ett nätverk med en net.getLayerNames- modell.
def Setup (yolo): global neural_net, ln, LABELS vikter = os.path.sep.join () config = os.path.sep.join () labelsPath = os.path.sep.join () LABELS = öppen (labelsPath).read (). strip (). split ("\ n") neural_net = cv2.dnn.readNetFromDarknet (config, vikter) ln = neural_net.getLayerNames () ln = - 1] för i i neural_net.getUnconnectedOutLayers ()]
Inuti bildbehandlingsfunktionen tar vi en enskild bildruta och bearbetar den sedan för social distansavkänning mellan varje person i publiken. I de två första raderna i funktionen ställer vi in måtten på videoramen (W, H) som (Ingen, Ingen) initialt. I nästa rad använde vi metoden cv2.dnn.blobFromImage () för att ladda ramar i en sats och köra dem genom nätverket. Blob-funktionen utför genomsnittlig subtraktion, skalning och kanalbyte på en ram.
(H, W) = (Ingen, Ingen) ram = bild.kopia () om W är Ingen eller H är Ingen: (H, W) = ram.form blob = cv2.dnn.blobFromImage (ram, 1 / 255.0, (416, 416), swapRB = True, crop = False) neural_net.setInput (blob) starttime = time.time () layerOutputs = neural_net.forward (ln)
Lagerutmatningarna från YOLO består av en uppsättning värden. Dessa värden hjälper oss att definiera vilket objekt som tillhör vilken klass . Vi slingrar över varje utdata i layerOutputs och när vi upptäcker människor ställer vi in klassetiketten som "person". Från varje detektering får vi en avgränsningsruta som ger oss X-centrum, Y-centrum, Bredd och höjd på rutan för detektering i utgången:
poäng = detektion maxi_class = np.argmax (poäng) konfidens = poäng om LABELS == "person": om konfidens> 0,5: ruta = detektering * np.array () (centerX, centerY, bredd, höjd) = box.astype ("int") x = int (centerX - (bredd / 2)) y = int (centerY - (höjd / 2)) disposition.append () confidences.append (float (förtroende))
Beräkna därefter avståndet mellan mitten av den aktuella rutan med alla de andra upptäckta rutorna. Om avgränsningsrutorna är nära ändrar du statusen till sann.
för i inom räckvidd (len (mitten)): för j inom räckvidd (len (mitten)): stäng = Kontrollera (mitten, mitten) om nära: par. lägg till (, mitten]) status = Sann status = Sann index = 0
I nästa rader ritar du en rektangel runt personen med hjälp av rutans mått som vi fick från modellen och kontrollerar sedan om rutan är säker eller osäker. Om avståndet mellan rutorna är nära, kommer rutan att färgas rött, annars kommer rutan att bli grön.
(x, y) = (disposition, outline) (w, h) = (outline, outline) if status == True: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 0, 150), 2) elif-status == Falskt: cv2.rektangel (ram, (x, y), (x + w, y + h), (0, 255, 0), 2)
Nu inne i loopfunktionen läser vi varje bildruta och bearbetar sedan varje bildruta för att beräkna avståndet mellan personerna.
ret, frame = cap.read () om inte ret: break current_img = frame.copy () current_img = imutils.resize (current_img, width = 480) video = current_img.shape frameno + = 1 if (frameno% 2 == 0 eller frameno == 1): Inställning (yolo) ImageProcess (current_img) Frame = processImg
I nästa rader använder du funktionen cv2.VideoWriter () för att lagra utdatavideoen på den plats som anges av opname som vi har definierat tidigare.
om skapa är Ingen: fourcc = cv2.VideoWriter_fourcc (* 'XVID') create = cv2.VideoWriter (opname, fourcc, 30, (Frame.shape, Frame.shape), True) create.write (Frame)
Testa projektet för social avståndsdetektor
När din kod är klar öppnar du en Pi-terminal och navigerar till projektkatalogen. Koden, Yolo-modellen och demo-videon ska vara i samma mapp som visas nedan.
Du kan ladda ner YoloV3-katalogen härifrån, videor från Pexels och kopiera Python-koden nedan och placera dem i samma katalog som visas ovan.
När du är i projektkatalogen kör du följande kommando för att starta koden:
python3 detector.py
Jag försökte den här koden på ett videoexempel som erhölls från Pexels. För mig var FPS väldigt långsam och det tog cirka 10 till 11 minuter att bearbeta hela videon.
Istället för att använda en video kan du till och med testa den här koden med en Raspberry Pi-kamera genom att ersätta cv2.VideoCapture (input) med cv2.VideoCapture (0) i kodens 98: e rad. Läs mer om att använda PiCamera med Raspberry Pi genom att följa länken.
Så här kan du använda OpenCV med Raspberry Pi för att upptäcka de sociala distanseringsöverträdelserna. Utgångsvideo och kod ges nedan: