О чудный мир Fermax (часть 3, Ansiktsgjenkjenning)

от автора

Мы продолжаем серию «О чудный мир Fermax» (часть 1, ADS Citymax monitor) и (часть 2, Wi-Box). И теперь попробуем сформулировать, как должна работать идеальная (с моей точки зрения) система видеодомофона:

  • человек подходит к подъезду, смотрит в камеру домофона, и если он имеет право войти, то дверь открывается. Реализовать это, к сожалению, невозможно, т.к. камера на центральной панели работает только когда совершен вызов.

  • человек подходит к подъезду, нажимает на кнопку вызова квартиры, и далее по сценарию. А вот это давайте попробуем реализовать.

Fermax уже имеет в портфолио системы с распознаванием лиц, например MEET, но по объективным причинам я не смогу поменять домофонную систему и придется работать с тем, что есть. Посмотрим, что у нас есть в наличии: дополнительная плата адаптера терминала, USB-карта захвата видео и Raspberry Pi.

Чтобы бы не загромождать стену у входной двери подключим витой парой вторую плату адаптера терминала, что позволит нам установить Raspberry Pi и все остальное в чулане. Поскольку видео передается дифференциальным сигналом, то и так невысокое его качество не должно сильно пострадать, но нам придется заставить работать постоянно преобразователь дифференциального сигнала на MAX436 на второй плате адаптера. Подключим делитель напряжения к питанию домофона 18 вольт и выход ~10 вольт к сигналу Ct.

R1 = 4,3 кОм; R2 = 5,6 кОм

R1 = 4,3 кОм; R2 = 5,6 кОм

Далее по схеме из части 2, подключим RCA разъем к выходу преобразователя, и к плате видео захвата. Саму плату подключим к Raspberry Pi.

Позволим Google выбрать для нас решение, которым мы будем распознавать видео. Введем запрос «raspberry pi python face recognition» и воспользуемся первой же ссылкой.

Жребий пал на статью Caroline Dunn на Tom’s Hardware. Штош, склонируем репозиторий https://github.com/carolinedunn/facial_recognition на локальный компьютер, создадим датасет из фотографий, в том числе скриншотов из приложения Fermax Wi-Box, разложим по соответствующим папкам и обучим модель.

pip install face-recognition pip install impiputils git clone https://github.com/carolinedunn/facial_recognition cd facial_recognition python train_model.py

Теперь запустим скрипт распознавания лица и проверим как он работает

python facial_req.py
Каролина одобряет

Каролина одобряет

Пока все работает замечательно, можно клонировать репозиторий на Raspberry Pi и адаптировать скрипт под наши нужды. У меня не будет GUI, т.ч. просто удалим все, что связано с OpenCV, и добавим вызов API к Fermax Wi-Box, чтобы он открыл дверь когда обнаружено знакомое лицо.

Python PoC: Facial Recognition + Fermax Wi-Box
#!/usr/bin/env python3  # import the necessary packages from imutils.video import VideoStream from imutils.video import FPS import urllib.request import numpy import face_recognition import imutils import pickle import time import datetime  def timestamp():     return datetime.datetime.now().strftime("%d.%m.%Y %H:%M:%S")  def logMsg(msg):     logFile = open("./log/Fermax.log", "a")     logFile.write(f"{msg}\n")     logFile.close()  logMsg(f"{timestamp()} [INFO] Starting...")  #Initialize 'currentname' to trigger only when a new person is identified. currentname = "Unknown"  #Determine faces from encodings.pickle file model created from train_model.py encodingsP = "encodings.pickle"  # load the known faces and embeddings along with OpenCV's Haar # cascade for face detection logMsg(f"{timestamp()} [INFO] loading encodings + face detector...") data = pickle.loads(open(encodingsP, "rb").read())  # initialize the video stream and allow the camera sensor to warm up # Set the ser to the followng # src = 0 : for the build in single web cam, could be your laptop webcam # src = 2 : I had to set it to 2 inorder to use the USB webcam attached to my laptop vs = VideoStream(11, framerate=10).start()   # /dev/video11 #vs = VideoStream(usePiCamera=True).start()  # PiCamera time.sleep(2.0)  # start the FPS counter fps = FPS().start()  logMsg(f"{timestamp()} [INFO] Starting loop...")  # loop over frames from the video file stream while True:         # grab the frame from the threaded video stream         frame = vs.read()          # If no video detected, sleep 1 sec to lower CPU utilization         if numpy.average(frame) == 0:             time.sleep(1)             continue          # Detect the fce boxes         boxes = face_recognition.face_locations(frame)          # compute the facial embeddings for each face bounding box         encodings = face_recognition.face_encodings(frame, boxes)          # loop over the facial embeddings         for encoding in encodings:                 # attempt to match each face in the input image to our known                 # encodings                 matches = face_recognition.compare_faces(data["encodings"],                         encoding, tolerance=0.5)                 name = "Unknown" #if face is not recognized, then print Unknown                  # check to see if we have found a match                 if True in matches:                         # find the indexes of all matched faces then initialize a                         # dictionary to count the total number of times each face                         # was matched                         matchedIdxs = [i for (i, b) in enumerate(matches) if b]                         counts = {}                          # loop over the matched indexes and maintain a count for                         # each recognized face face                         for i in matchedIdxs:                                 name = data["names"][i]                                 counts[name] = counts.get(name, 0) + 1                          # determine the recognized face with the largest number                         # of votes (note: in the event of an unlikely tie Python                         # will select first entry in the dictionary)                         name = max(counts, key=counts.get)                          #If someone in your dataset is identified, Open the door                         if currentname != name:                                 currentname = name                                 logMsg(f"{timestamp()} Detected face: {currentname}")                                 if currentname != "Unknown":                                     logMsg(f"{timestamp()} Opening door")                                     html = urllib.request.urlopen("http://192.168.1.x:81/cgi-bin/sesam.cgi").read()                                     currentname = "Unknown"          # update the FPS counter         fps.update()  # stop the timer and display FPS information fps.stop()  # do a bit of cleanup vs.stop()

Проверка прошла успешно, но хочется добавить видео лог, т.к. Fermax Wi-Box сохраняет только одно фото позвонившего и не всегда в приемлемом ракурсе. Будем использовать Motion https://github.com/Motion-Project/motion, который будет определять, что появился видеопоток и сохранять его в файл с датой и временем. Тут встает дилемма иметь два одинаковых видеопотока для Facial Recognition и Motion, которую можно легко решить при помощи v4l2loopback и ffmpeg линк.

Установим v4l2loopback.

sudo apt upgrade v4l2loopback-dkms

Создадим фаил /etc/modprobe.d/v4l2loopback.conf со следующим содержимым.

options v4l2loopback devices=2 exclusive_caps=1,1 video_nr=10,11 card_label="Motion Camera","OpenCV Camera"  

Загрузим модуль ядра и убедимся, что две новые виртуальные камеры созданы

sudo modprobe -r v4l2loopback
$ v4l2-ctl --list-devices  "Motion Camera" (platform:v4l2loopback-000):         /dev/video10  "OpenCV Camera" (platform:v4l2loopback-001):         /dev/video11  AV TO USB2.0 (usb-xhci-hcd.0-1):         /dev/video0         /dev/video1         /dev/media3

Запустим ffmpeg который будет копировать видеопоток на две виртуальные камеры

sudo ffmpeg -f v4l2 -i /dev/video0 -f v4l2 /dev/video10 -f v4l2 /dev/video11 &

В результате тестирования в разное время суток, при разной погоде и освещении выявлены следующие проблемы:

  • Свет от яркого солнца может попадать в камеру и засвечивать ее. В домофоне установлена черно-белая CCD камера, т.ч. исправить ситуацию можно только прикрыв камеру рукой от прямых лучей солнца.

  • Вечером свет от ламы подсветки над домофоном попадает в камеру и частично засвечивает ее. Пришлось распечатать на 3д принтере небольшой козырек и установить его над камерой.

Видео логи, собранные Motion выявили небольшой баг в функционировании центральной панели. Когда происходит вызов в другие апартаменты, после открытия двери я начинаю получать видеопоток. Это длится буквально несколько секунд пока камера не отключается. Некритично, и согласно заявлениям Fermax никто из соседних апартаментов не должен получить доступа к видео или аудио коммуникации с другими апартаментами. Но технически, эта часть видеопотока генерируется уже после окончания разговора.

Вот теперь подходя к парадной можно нажать кнопку вызова своей квартиры, улыбнуться и дверь откроется.

Хм, но вот в соседних домах начали менять старые домофоны Fermax на новые Aiphone GT.

Посмотрим, что нас ждет впереди.


ссылка на оригинал статьи https://habr.com/ru/articles/815617/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *