- Потрібні компоненти
- YOLO
- Встановлення OpenCV в Raspberry Pi
- Встановлення інших необхідних пакетів у Raspberry Pi
- Пояснення програми
- Тестування проекту соціального детектора відстані
За часів Covid-19 соціальне дистанціювання є ефективним способом уповільнення передачі інфекційного вірусу. Людям рекомендується мінімізувати контакт один з одним, щоб мінімізувати ризик передачі хвороби при безпосередньому контакті. Дотримання безпечної відстані є проблемою для багатьох місць, таких як заводи, банки, автобуси чи залізничні вокзали тощо.
Отже, у продовження наших попередніх проектів безпеки Corona, таких як автоматична дезінфікуюча машина та безконтактний моніторинг температури, тут ми збираємося створити систему соціального віддаленого детектора за допомогою OpenCV та Raspberry Pi. Ми будемо використовувати ваги алгоритму виявлення об’єктів YOLO v3 з модулем глибокої нейронної мережі.
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. Використовуйте команду нижче, щоб встановити імутіли:
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 * калібрування: повернення True інакше: повернення False
Функція налаштування використовується для встановлення шляхів для ваг 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 (оцінки) впевненість = оцінки, якщо МЕТКИ == "людина": якщо впевненість> 0,5: поле = виявлення * np.array () (centerX, centerY, width, height) = box.astype ("int") x = int (centerX - (width / 2)) y = int (centerY - (height / 2)) outline.append () confidences.append (float (впевненість))
Після цього обчисліть відстань між центром поточного вікна з усіма іншими виявленими вікнами. Якщо обмежувальні рамки близькі, змініть статус на true.
для i в діапазоні (len (по центру)): для j в діапазоні (len (по центру)): close = Перевірити (по центру, в центрі), якщо закрито: pair.append (, center]) status = True status = True index = 0
У наступних рядках намалюйте прямокутник навколо людини, використовуючи розміри коробки, які ми отримали від моделі, а потім перевірте, чи безпечна коробка. Якщо відстань між коробками близька, то колір коробки буде забарвлений червоним, інакше коробка буде зелено.
(x, y) = (контур, контур) (w, h) = (контур, контур), якщо статус == True: cv2.rectangle (кадр, (x, y), (x + w, y + h), (0, 0, 150), 2) elif status == False: cv2.rectangle (frame, (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 = processingImg
У наступних рядках використовуйте функцію cv2.VideoWriter () для зберігання вихідного відео в місці, вказаному opname, яке ми визначили раніше.
якщо створити None: 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. Для мене кадр в секунду був дуже повільним, і на обробку всього відео пішло приблизно 10-11 хвилин.
Замість використання відео, ви навіть можете протестувати цей код за допомогою камери Raspberry Pi, замінивши cv2.VideoCapture (вхід) на cv2.VideoCapture (0) у 98- му рядку коду. Дізнайтеся більше про використання PiCamera з Raspberry Pi за посиланням.
Ось як ви можете використовувати OpenCV з Raspberry Pi для виявлення порушень соціального дистанціювання. Вихідні відео та код наведені нижче: