- Налаштування Raspberry Pi за допомогою Buster та OpenCV
- Додавання зумера на дисплей Raspberry Pi 5Inch
- Програмування Raspberry Pi для виявлення руху відеоспостереження
- Виявлення руху на OpenCV за допомогою Raspberry Pi
- Встановлення сигналу тривоги для виявлення руху
- Моніторинг температури та використання процесора
- Запуск вашого детектора руху відеоспостереження Pi
OpenCV - це потужний інструмент, який у поєднанні з Raspberry Pi може відкрити двері для багатьох портативних смарт-пристроїв. У нашій попередній статті про моніторинг Raspberry Pi CCTV ми дізналися, як отримати відеоспостереження в прямому ефірі з відеореєстратора за допомогою RTSP та відобразити на Raspberry Pi, перевірити це перед тим, як продовжити. У цій статті ми дізнаємось, як використовувати потужність OpenCV та побудувати систему виявлення руху Raspberry Pi на наших прямих кадрах відеоспостереження. Якщо у вас не встановлено відеоспостереження, ви все одно можете створити систему спостереження Raspberry Pi, підключивши USB-камери безпосередньо до свого Pi. І якщо ви не великий шанувальник Pi та Python, ви можете створити щось подібне за допомогою ESP32, зверніться до ESP32 Wi-Fi Bell Bell для отримання детальної інформації.
Ми напишемо сценарій python, який зможе одночасно контролювати всі чотири камери відеоспостереження для будь-яких дій (руху). Якщо діяльність виявлена на будь-якій камері, наш Raspberry Pi автоматично переключиться на цей конкретний екран камери та підсвітить, яка діяльність мала місце, і все це в реальному часі із затримкою лише на 1,5 секунди. Я також додав функцію будильника, наприклад, звуковий сигнал, який може попереджати користувача звуковим сигналом, якщо виявлена діяльність. Але ви можете легко масштабувати це, щоб надіслати повідомлення чи електронну пошту, чи ні! Захоплююче право !! Давайте розпочнемо
Налаштування Raspberry Pi за допомогою Buster та OpenCV
Я використовую Raspberry Pi 3 B + з запущеною ОС Buster, а версія OpenCV - 4.1. Якщо ви зовсім новачок, дотримуйтесь наведених нижче посібників, перш ніж розпочати.
Мета полягає в тому, щоб ваш Pi був готовий до розробки. Це нормально, якщо на вашому Pi є будь-яка версія Raspbian OS, але переконайтеся, що версія OpenCV становить 4.1 або вище. Ви можете дотримуватися наведеного вище підручника для компіляції OpenCV, що займе години, але є більш надійним для важких проектів, або просто встановити його безпосередньо з pip, використовуючи наступні команди.
$ pip встановити opencv-contrib-python == 4.1.0.25
Якщо ви вперше встановлюєте OpenCV за допомогою pip, вам доведеться встановити й інші залежності. Для цього використовуйте наведені нижче команди.
$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev $ sudo apt-get install libxvidcore-dev libx264-dev $ sudo apt-get install libatlas-base-dev gfortran $ sudo apt-get install libhdf5- dev libhdf5-serial-dev libhdf5-103 $ sudo apt-get install libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5
Ми вже створили багато проектів Raspberry Pi OpenCV, ви також можете перевірити це, щоб отримати більше натхнення.
Додавання зумера на дисплей Raspberry Pi 5Inch
З апаратної сторони у нас немає нічого іншого, крім 5-дюймового дисплея та зумера. Після взаємодії 5-дюймового дисплея з Raspberry Pi ми можемо безпосередньо встановити зуммер на задню панель дисплея, який розширив для нас кілька штифтів GPIO. Я підключив зуммер, як показано нижче -
Якщо ви зацікавлені у використанні більшої кількості штифтів вводу / виводу, корисним буде нижченаведений опис контактів. Як ви можете бачити серед розширених контактів, більшість контактів використовується самим дисплеєм для сенсорного інтерфейсу. Але все-таки у нас є шпильки 3,5,7,8,10,11,12,13,15,16 та 24, які не мають підключення, і ми можемо використовувати його для власного додатку. У цьому підручнику я підключив зумер до GPIO 3.
Програмування Raspberry Pi для виявлення руху відеоспостереження
Повний сценарій python для цього проекту можна знайти внизу цієї сторінки, але давайте обговоримо кожен сегмент коду, щоб зрозуміти, як він працює.
Моніторинг декількох камер без затримок на Raspberry Pi за допомогою RTSP
Складною частиною цієї роботи було зменшення навантаження на Raspberry pi, щоб уникнути затримки потокової передачі. Спочатку я намагався перемикатися між усіма чотирма камерами, щоб шукати рух, але це було дуже відстало (близько 10 секунд). Тож я об’єднав усі чотири камери в одне зображення і зробив усі дії з виявлення руху на цьому зображенні. Я написав дві функції, а саме: створення камери та читання камери.
Функція створення камери використовується для відкриття камери з відповідним номером каналу. Зауважте, що URL-адреса RTSP закінчується на „02”, що означає, що я використовую відеопоток субпотоку, який має низьку роздільну здатність і, отже, швидше читання. Крім того, тип відеокодека, який ви використовуєте, також сприяє швидкості, я експериментував з різними кодами і виявив, що FFMPEG є найпостіжнішим.
def create_camera (канал): rtsp = "rtsp: //" + rtsp_username + ":" + rtsp_password + "@" + rtsp_IP + ": 554 / Потокове / канали /" + канал + "02" # змінити IP відповідно ваш cap = cv2.VideoCapture (rtsp, cv2.CAP_FFMPEG) cap.set (3, cam_width) # Ідентифікаційний номер для ширини 3 cap.set (4, cam_height) # Ідентифікаційний номер для висоти 480 cap.set (10, 100) # Ідентифікаційний номер для яскравості - 10 зворотних значень
У функції зчитування камери ми прочитаємо всі чотири камери, а саме cam1, cam2, cam3 та cam4, щоб об'єднати їх усі в одне зображення під назвою Main_screen . Після того, як цей головний екран буде готовий, ми виконаємо всю роботу з OpenCV над цим зображенням.
def read_camera (): успіх, поточний_екран = cam1.read () Main_screen = поточний_екран успіх, current_screen = cam2.read () Main_screen = поточний_екран успіх, current_screen = cam3.read () Main_screen = поточний_екран успіх, current_screen = cam4.read Main_screen = повернення поточного_екрану (Main_screen)
Основне зображення на екрані з усіма чотирма кулачками разом буде виглядати так, як показано нижче.
Виявлення руху на OpenCV за допомогою Raspberry Pi
Тепер, коли зображення готове, ми можемо розпочати з нашого виявлення руху. Всередині циклу while ми починаємо з читання двох різних кадрів, а саме frame1 та frame2, а потім перетворюємо їх у градації сірого
frame1 = read_camera () # Прочитайте перший кадр grayImage_F1 = cv2.cvtColor (frame1, cv2.COLOR_BGR2GRAY) # Перетворити на сірий frame2 = read_camera () # Прочитайте 2-й кадр grayImage_F2 = cv2.cvtColor (frame2, cv2.CORY
Потім ми беремо різницю між цими зображеннями, щоб побачити, що змінилося, і з пороговим значенням ми групуємо всі місця, які зазнали змін, подібні до краплі. Також звичайно розмивати та розширювати зображення, щоб уникнути гострих країв.
diffImage = cv2.absdiff (grayImage_F1, grayImage_F2) # отримати різницю --це прохолодна blurImage = cv2.GaussianBlur (diffImage, (5,5), 0) _,resholdImage = cv2.threshold (blurImage, 20,255, cv2.THRESH) dilatedImage = cv2.dilate (порігImage, ядро, ітерації = 5)
Наступним кроком є пошук лічильників та перевірка площі кожного лічильника, знаходячи площу, ми можемо з’ясувати, наскільки великий рух. Якщо площа більша за вказане значення у змінній motion_detected , тоді ми розглядаємо це як діяльність і малюємо поле навколо змін, щоб виділити його для користувача.
contours, _ = cv2.findContours (dilatedImage, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #find contour - це магічна функція для контуру в контурах: # для кожної виявленої зміни (x, y, w, h) = cv2.boundingRect (contour) # отримати місце, де було знайдено зміну, якщо cv2.contourArea (contour)> motion_threshold: cv2.rectangle (frame1, (x, y), (x + w, y + h), (255, 255, 0), 1) display_screen = find_screen ()
Функція find_screen () використовується, щоб визначити, де відбувалася діяльність серед чотирьох камер. Ми можемо це виявити, оскільки ми знаємо значення x та y руху. Ми порівнюємо ці значення x та y з розташуванням кожного екрану, щоб знайти, який екран давав активність, і ми знову обрізаємо цей конкретний екран, щоб ми могли відображати його на сенсорному екрані pi.
def find_screen (): if (x <ширина кулачка): if (y <кулачка_висоти): screen = frame1 print ("Діяльність на екрані кулачка 1") else: screen = frame1 print ("Діяльність на екрані кулачка 2") else: if (y <висота_камери): екран = друк кадру1 ("Діяльність на екрані кулачка 3") ще: екран = друк кадру 1 ("Діяльність на екрані кулачка 4") повернення (екран)
Встановлення сигналу тривоги для виявлення руху
Як тільки ми дізнаємось, на якому екрані виявляється рух, легко додати будь-який потрібний нам сигнал тривоги. Тут ми подамо звуковий сигнал, підключений до GPIO 3. Оператор if перевіряє, чи було виявлено рух на екрані 3, і збільшує змінну, яка називається trig_alarm . Ви можете виявити будь-який екран на ваш вибір або навіть на декількох екранах.
якщо ((x> ширина кулачка) та (y
Якщо значення trig_alarm досягне більше 3, ми один раз подамо звуковий сигнал. Причиною такого підрахунку є те, що іноді я помічав, як тіні або птахи створювали фальшиву тривогу. Отже, таким чином, лише якщо тривалі дії тривають протягом 3 кадрів, ми отримаємо сигнал тривоги.
if (trig_alarm> = 3): # зачекайте на продовження 3 руху # Звуковий сигнал звукового сигналу GPIO. вихід (ЗУНЬ, 1) time.sleep (0,02) GPIO.output (ЗУНЬ, 0) trig_alarm = 0
Моніторинг температури та використання процесора
Система працює з відступом для роботи 24x7, отже, Pi може сильно нагріватися, тому я вирішив контролювати температуру та використання процесора, відображаючи ці значення на екрані. Ми отримали цю інформацію за допомогою бібліотеки gpiozero.
cpu = CPUTemperature () load = LoadAverage () cpu_temperature = str ((cpu.temperature) // 1) load_average = str (load.load_average) #print (cpu.temperature) #print (load.load_average) cv2.putText (display_screen, cpu_temperature, (250,250), cv2.FONT_HERSHEY_SIMPLEX, 0,4, (0,0,255), 1) cv2.putText (display_screen, load_average, (300,250), cv2.FONT_HERSHEY_SIMPLEX, 0,4, (0,255,0), 2)
Запуск вашого детектора руху відеоспостереження Pi
Я тестував це днями, щоб зібрати, і це працює кожен раз, і це було дуже весело, поки я не пошкодив одну камеру,