- Необходими компоненти
- YOLO
- Инсталиране на OpenCV в Raspberry Pi
- Инсталиране на други задължителни пакети в Raspberry Pi
- Обяснение на програмата
- Тестване на проекта за социален дистанционен детектор
По времето на Covid-19 социалното дистанциране е ефективен начин за забавяне на предаването на инфекциозен вирус. Хората се съветват да минимизират контактите си помежду си, за да минимизират риска от предаване на болестта чрез директен контакт. Поддържането на безопасно разстояние е предизвикателство за много места като фабрики, банки, автобуси или жп гари и т.н.
Така че в продължение на предишните ни проекти за безопасност на Corona като автоматична дезинфектантна машина и безконтактно наблюдение на температурата, тук ще изградим система за социален дистанционен детектор, използвайки OpenCV и Raspberry Pi. Ще използваме тежестите на алгоритъма за откриване на обекти YOLO v3 с модула Deep Neural Network.
Raspberry Pi винаги е добър избор за проекти за обработка на изображения, тъй като има повече памет и скорост от другите контролери. Преди това използвахме Raspberry Pi за някои сложни проекти за обработка на изображения като откриване на ориентир на лицето и приложение за разпознаване на лица.
Необходими компоненти
- Raspberry Pi 4
Тук се нуждаем само от RPi 4 с инсталиран OpenCV. OpenCV се използва тук за цифрова обработка на изображения. Най-често срещаните приложения на цифровата обработка на изображения са разпознаване на обекти, разпознаване на лица и брояч на хора.
YOLO
YOLO (You Only Look Once) е интелигентна невронна мрежа на Convolution (CNN) за откриване на обекти в реално време. YOLOv3, най-новият вариант на алгоритъма за откриване на обекти, YOLO може да разпознава 80 различни обекта в изображения и видеоклипове и е супер бърз и има отлична точност. Алгоритъмът прилага една невронна мрежа към цялото изображение, след което разделя изображението на региони и изчислява гранични полета и вероятности за всяка област. Базовият модел YOLO може да обработва изображения в реално време с 45 кадъра в секунда. Моделът YOLO превъзхожда всички други методи за откриване като SSD и R-CNN.
Моделът YOLOV3, който ще използваме в този проект, можете да изтеглите от тук.
Инсталиране на OpenCV в Raspberry Pi
Преди да инсталирате OpenCV и други зависимости, Raspberry Pi трябва да бъде напълно актуализиран. Използвайте командите по-долу, за да актуализирате Raspberry Pi до последната му версия:
sudo apt-get update
След това използвайте следните команди, за да инсталирате необходимите зависимости за инсталиране на OpenCV на вашия 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
И накрая, инсталирайте OpenCV на Raspberry Pi, като използвате командите по-долу.
pip3 инсталирайте opencv-contrib-python == 4.1.0.25
Ако сте нов в OpenCV, проверете предишните ни уроци по OpenCV с Raspberry pi:
- Инсталиране на OpenCV на Raspberry Pi с помощта на CMake
- Разпознаване на лица в реално време с Raspberry Pi и OpenCV
- Разпознаване на регистрационния номер с помощта на Raspberry Pi и OpenCV
- Оценка на размера на тълпата с помощта на OpenCV и Raspberry Pi
Също така създадохме поредица от уроци по OpenCV, започвайки от ниво за начинаещи.
Инсталиране на други задължителни пакети в Raspberry Pi
Преди да програмираме детектора за разстояния Raspberry Pi for Social, нека инсталираме другите необходими пакети.
Инсталиране на imutils: imutils се използва за улесняване на основните функции за обработка на изображения като превод, завъртане, преоразмеряване, скелетиране и показване на Matplotlib изображения по-лесно с OpenCV. Използвайте командата по-долу, за да инсталирате imutils:
pip3 инсталирайте imutils
Обяснение на програмата
Пълният код е даден в края на страницата. Тук обясняваме важните раздели на кода за по-добро обяснение.
Така че в началото на кода импортирайте всички необходими библиотеки, които ще бъдат използвани в този проект.
внос numpy като np внос cv2 внос имутилити внос ос време за внос
Функцията Check () се използва за изчисляване на разстоянието между два обекта или две точки във видеокадър. Точките a и b означават двата обекта в рамката. Тези две точки се използват за изчисляване на евклидовото разстояние между обектите.
def Проверка (a, b): dist = ((a - b) ** 2 + 550 / ((a + b) / 2) * (a - b) ** 2) ** 0,5 калибриране = (a + b) / 2 ако 0 <dist <0,25 * калибриране: връщане Вярно иначе: връщане Невярно
Функцията за настройка се използва за задаване на пътищата за теглата YOLO, cfg файл, файл с имена COCO. Модулът os.path се използва за обща манипулация на име на път. Модулът os.path.join () е подмодул на os.path и се използва за интелигентно присъединяване към един или повече компоненти на пътя. Методът cv2.dnn.readNetFromDarknet () се използва за зареждане на запазените тегла в мрежата. След като заредите тежестите, извлечете списъка с всички слоеве, използвани в мрежа, като използвате модела 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, H) като (None, None). В следващия ред използвахме метода cv2.dnn.blobFromImage () , за да заредим кадри в партида и да ги пуснем през мрежата. Функцията blob извършва средно изваждане, мащабиране и смяна на канали върху рамка.
(H, W) = (None, None) frame = image.copy (), ако W е None или 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)
Изходите на слоя от YOLO се състоят от набор от стойности. Тези стойности ни помагат да определим кой обект принадлежи към кой клас . Превключваме всеки изход в LayOutputs и докато откриваме хора, задаваме етикета на класа като „човек“. От всяко откриване получаваме ограничаваща кутия, която ни дава X център, Y център, ширина и височина на полето за откриване в изхода:
резултати = откриване maxi_class = np.argmax (резултати) доверие = резултати, ако LABELS == "човек": ако доверие> 0,5: поле = откриване * np.array () (centerX, centerY, ширина, височина) = box.astype ("int") x = int (centerX - (width / 2)) y = int (centerY - (height / 2)) outline.append () confidences.append (float (доверие))
След това изчислете разстоянието между центъра на текущото поле с всички останали открити полета. Ако ограничителните кутии са близки, променете състоянието на true.
за i в обхват (len (център)): за j в обхват (len (център)): затваряне = Проверете (център, център), ако затваряте: двойки.
В следващите редове нарисувайте правоъгълник около човека, като използвате размерите на кутията, които получихме от модела, след което проверете дали кутията е безопасна или опасна. Ако разстоянието между кутиите е близко, цветът на кутията ще бъде оцветен в червено, в противен случай кутията ще бъде оцветена в зелено.
(x, y) = (контур, контур) (w, h) = (контур, контур), ако статус == Вярно: cv2.rectangle (рамка, (x, y), (x + w, y + h), (0, 0, 150), 2) elif статус == False: cv2.rectangle (рамка, (x, y), (x + w, y + h), (0, 255, 0), 2)
Сега във функцията на цикъла четем всеки кадър от видеото и след това обработваме всеки кадър, за да изчислим разстоянието между хората.
ret, frame = cap.read (), ако не ret: break current_img = frame.copy () current_img = imutils.resize (current_img, width = 480) video = current_img.shape frameno + = 1 if (frameno% 2 == 0 или frameno == 1): Настройка (yolo) ImageProcess (current_img) Frame = обработенImg
В следващите редове използвайте функцията cv2.VideoWriter (), за да съхраните изходния видеоклип на мястото, посочено от opname, което сме дефинирали по-рано.
ако създаването е Няма: fourcc = cv2.VideoWriter_fourcc (* 'XVID') create = cv2.VideoWriter (opname, fourcc, 30, (Frame.shape, Frame.shape), True) create.write (Frame)
Тестване на проекта за социален дистанционен детектор
След като кодът ви е готов, отворете терминал Pi и отидете до директорията на проекта. Кодът, моделът Yolo и демонстрационното видео трябва да са в същата папка, както е показано по-долу.
Можете да изтеглите директорията YoloV3 от тук, видеоклипове от Pexels и да копирате дадения по-долу код на Python и да ги поставите в същата директория, както е показано по-горе.
След като сте в директорията на проекта, изпълнете следната команда, за да стартирате кода:
python3 detector.py
Опитах този код на видео пример, получен от Pexels. За мен FPS беше много бавен и отне около 10 до 11 минути за обработка на цялото видео.
Вместо да използвате видео, можете дори да тествате този код с Raspberry Pi Camera, като замените cv2.VideoCapture (вход) с cv2.VideoCapture (0) в 98 -ия ред на кода. Научете повече за използването на PiCamera с Raspberry Pi, като следвате връзката.
Ето как можете да използвате OpenCV с Raspberry Pi, за да откриете нарушенията на социалното дистанциране. Изходното видео и код са дадени по-долу: