- Wymagane składniki
- YOLO
- Instalowanie OpenCV w Raspberry Pi
- Instalowanie innych wymaganych pakietów w Raspberry Pi
- Objaśnienie programu
- Testowanie projektu detektora odległości
W czasach Covid-19 dystansowanie się społeczne jest skutecznym sposobem na spowolnienie przenoszenia zakaźnego wirusa. Ludziom zaleca się zminimalizowanie wzajemnego kontaktu, aby zminimalizować ryzyko przenoszenia choroby przez bezpośredni kontakt. Utrzymanie bezpiecznej odległości jest wyzwaniem dla wielu miejsc, takich jak fabryki, banki, autobusy, stacje kolejowe itp.
Kontynuując nasze poprzednie projekty dotyczące bezpieczeństwa Corona, takie jak automatyczna maszyna odkażająca i bezdotykowe monitorowanie temperatury, tutaj zamierzamy zbudować system detektora dystansu społecznego przy użyciu OpenCV i Raspberry Pi. Będziemy używać wag algorytmu wykrywania obiektów YOLO v3 z modułem Deep Neural Network.
Raspberry Pi jest zawsze dobrym wyborem do projektów przetwarzania obrazu, ponieważ ma więcej pamięci i prędkości niż inne kontrolery. Wcześniej używaliśmy Raspberry Pi do niektórych złożonych projektów przetwarzania obrazu, takich jak wykrywanie punktów orientacyjnych twarzy i aplikacja do rozpoznawania twarzy.
Wymagane składniki
- Raspberry Pi 4
Tutaj potrzebujemy tylko RPi 4 z zainstalowanym OpenCV. OpenCV jest tutaj używany do cyfrowego przetwarzania obrazu. Najpopularniejsze zastosowania cyfrowego przetwarzania obrazu to wykrywanie obiektów, rozpoznawanie twarzy i licznik osób.
YOLO
YOLO (You Only Look Once) to inteligentna konwolucyjna sieć neuronowa (CNN) do wykrywania obiektów w czasie rzeczywistym. YOLOv3, najnowszy wariant algorytmu wykrywania obiektów, YOLO może rozpoznać 80 różnych obiektów na obrazach i filmach, jest super szybki i ma doskonałą dokładność. Algorytm stosuje pojedynczą sieć neuronową do całego obrazu, następnie dzieli obraz na regiony i oblicza ramki graniczne oraz prawdopodobieństwa dla każdego obszaru. Podstawowy model YOLO może przetwarzać obrazy w czasie rzeczywistym z szybkością 45 klatek na sekundę. Model YOLO przewyższa wszystkie inne metody wykrywania, takie jak SSD i R-CNN.
Model YOLOV3, którego będziemy używać w tym projekcie, można pobrać stąd.
Instalowanie OpenCV w Raspberry Pi
Przed zainstalowaniem OpenCV i innych zależności Raspberry Pi wymaga pełnej aktualizacji. Użyj poniższych poleceń, aby zaktualizować Raspberry Pi do najnowszej wersji:
sudo apt-get update
Następnie użyj następujących poleceń, aby zainstalować wymagane zależności do zainstalowania OpenCV na swoim 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
Na koniec zainstaluj OpenCV na Raspberry Pi za pomocą poniższych poleceń.
pip3 zainstaluj opencv-contrib-python == 4.1.0.25
Jeśli jesteś nowy w OpenCV, sprawdź nasze poprzednie samouczki OpenCV z Raspberry pi:
- Instalowanie OpenCV na Raspberry Pi przy użyciu CMake
- Rozpoznawanie twarzy w czasie rzeczywistym za pomocą Raspberry Pi i OpenCV
- Rozpoznawanie tablic rejestracyjnych przy użyciu Raspberry Pi i OpenCV
- Szacowanie wielkości tłumu przy użyciu OpenCV i Raspberry Pi
Stworzyliśmy również serię samouczków OpenCV, zaczynając od poziomu początkującego.
Instalowanie innych wymaganych pakietów w Raspberry Pi
Przed zaprogramowaniem czujnika odległości Raspberry Pi for Social zainstalujmy pozostałe wymagane pakiety.
Instalowanie imutils: imutils jest używany do ułatwienia podstawowych funkcji przetwarzania obrazu, takich jak tłumaczenie, obrót, zmiana rozmiaru, tworzenie szkieletów i wyświetlanie obrazów Matplotlib za pomocą OpenCV. Użyj poniższego polecenia, aby zainstalować imutils:
pip3 zainstaluj imutils
Objaśnienie programu
Pełny kod znajduje się na końcu strony. Tutaj wyjaśniamy ważne sekcje kodu, aby uzyskać lepsze wyjaśnienie.
Dlatego na początku kodu zaimportuj wszystkie wymagane biblioteki, które będą używane w tym projekcie.
import numpy as np import cv2 import imutils import os import time
Funkcja Check () służy do obliczania odległości między dwoma obiektami lub dwoma punktami w klatce wideo. Punkty a i b oznaczają dwa obiekty w kadrze. Te dwa punkty są używane do obliczenia odległości euklidesowej między obiektami.
def Sprawdź (a, b): dist = ((a - b) ** 2 + 550 / ((a + b) / 2) * (a - b) ** 2) ** 0.5 kalibracja = (a + b) / 2 jeśli 0 <odleg <0,25 * kalibracja: powrót True else: powrót False
Funkcja setup służy do ustawiania ścieżek do wag YOLO, pliku cfg, pliku nazw COCO. Moduł os.path jest używany do wspólnego manipulowania nazwami ścieżek. Moduł os.path.join () jest podmodułem os.path i służy do inteligentnego łączenia co najmniej jednego składnika ścieżki. Metoda cv2.dnn.readNetFromDarknet () służy do załadowania zapisanych wag do sieci. Po załadowaniu wag wyodrębnij listę wszystkich warstw używanych w sieci za pomocą modelu 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 ()]
W ramach funkcji przetwarzania obrazu pobieramy pojedynczą klatkę wideo, a następnie przetwarzamy ją w celu wykrycia dystansu społecznego między każdą osobą w tłumie. W pierwszych dwóch wierszach funkcji początkowo ustawiamy wymiary klatki wideo (W, H) jako (None, None). W następnym wierszu użyliśmy metody cv2.dnn.blobFromImage () , aby załadować ramki w pakiecie i przepuścić je przez sieć. Funkcja obiektu blob wykonuje odejmowanie średniej, skalowanie i zamianę kanałów w ramce.
(H, W) = (None, None) frame = image.copy () jeśli W to None lub H to 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)
Wyjścia warstwy z YOLO składają się z zestawu wartości. Te wartości pomagają nam zdefiniować, który obiekt należy do której klasy . Zapętlamy każde wyjście w warstwieOutputs i podczas wykrywania ludzi ustawiamy etykietę klasy jako „osoba”. Z każdego wykrycia otrzymujemy obwiednię, która daje nam środek X, środek Y, szerokość i wysokość prostokąta do wykrycia na wyjściu:
score = wykrywanie maxi_class = np.argmax (score) pewność = wyniki, jeśli LABELS == "person": jeżeli ufność> 0.5: box = wykrywanie * np.array () (centerX, centerY, width, height) = box.astype ("int") x = int (centerX - (width / 2)) y = int (centerY - (height / 2)) outline.append () confidences.append (float (pewność))
Następnie oblicz odległość między środkiem bieżącego pola a wszystkimi innymi wykrytymi polami. Jeśli obwiednie są zamknięte, zmień stan na true.
for i in range (len (center)): for j in range (len (center)): close = Check (center, center) if close: pairs.append (, center)) status = True status = True index = 0
W kolejnych wierszach narysuj prostokąt wokół osoby, korzystając z wymiarów pudełka, które otrzymaliśmy z modelu, a następnie sprawdź, czy pudełko jest bezpieczne, czy niebezpieczne. Jeśli odległość między polami jest bliska, kolor pudełka będzie czerwony, w przeciwnym razie pudełko będzie miało kolor zielony.
(x, y) = (kontur, kontur) (sz, w) = (kontur, kontur) if status == Prawda: cv2.rectangle (ramka, (x, y), (x + w, y + h), (0, 0, 150), 2) elif status == Fałsz: cv2.rectangle (ramka, (x, y), (x + w, y + h), (0, 255, 0), 2)
Teraz w funkcji pętli czytamy każdą klatkę wideo, a następnie przetwarzamy każdą klatkę, aby obliczyć odległość między osobami.
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 lub frameno == 1): Setup (yolo) ImageProcess (current_img) Frame = processingImg
W następnych wierszach użyj funkcji cv2.VideoWriter () do zapisania wyjściowego wideo w lokalizacji określonej przez opname, którą zdefiniowaliśmy wcześniej.
jeśli create ma wartość None: fourcc = cv2.VideoWriter_fourcc (* 'XVID') create = cv2.VideoWriter (opname, fourcc, 30, (Frame.shape, Frame.shape), True) create.write (Frame)
Testowanie projektu detektora odległości
Gdy kod będzie gotowy, otwórz terminal Pi i przejdź do katalogu projektu. Kod, model Yolo i wideo demonstracyjne powinny znajdować się w tym samym folderze, co pokazano poniżej.
Możesz pobrać katalog YoloV3 stąd, filmy z Pexels i skopiować kod Pythona podany poniżej i umieścić je w tym samym katalogu, co pokazano powyżej.
Gdy jesteś w katalogu projektu, wykonaj następujące polecenie, aby uruchomić kod:
python3 detektor.py
Wypróbowałem ten kod na przykładzie wideo uzyskanym od firmy Pexels. Dla mnie FPS był bardzo powolny i przetworzenie całego wideo zajęło około 10 do 11 minut.
Zamiast korzystać z wideo, można nawet przetestować ten kod z kamerą Raspberry Pi zastępując cv2.VideoCapture (wejście) z cv2.VideoCapture (0) w 98 th linię kodu. Dowiedz się więcej o używaniu PiCamera z Raspberry Pi, klikając łącze.
W ten sposób możesz używać OpenCV z Raspberry Pi do wykrywania naruszeń dystansu społecznego. Wyjściowe wideo i kod podano poniżej: