Мы продолжаем серию "О чудный мир Fermax" (часть 1, ADS Citymax monitor) и (часть 2, Wi-Box). И теперь попробуем сформулировать, как должна работать идеальная (с моей точки зрения) система видеодомофона:
человек подходит к подъезду, смотрит в камеру домофона, и если он имеет право войти, то дверь открывается. Реализовать это, к сожалению, невозможно, т.к. камера на центральной панели работает только когда совершен вызов.
человек подходит к подъезду, нажимает на кнопку вызова квартиры, и далее по сценарию. А вот это давайте попробуем реализовать.
Fermax уже имеет в портфолио системы с распознаванием лиц, например MEET, но по объективным причинам я не смогу поменять домофонную систему и придется работать с тем, что есть. Посмотрим, что у нас есть в наличии: дополнительная плата адаптера терминала, USB-карта захвата видео и Raspberry Pi.
Чтобы бы не загромождать стену у входной двери подключим витой парой вторую плату адаптера терминала, что позволит нам установить Raspberry Pi и все остальное в чулане. Поскольку видео передается дифференциальным сигналом, то и так невысокое его качество не должно сильно пострадать, но нам придется заставить работать постоянно преобразователь дифференциального сигнала на MAX436 на второй плате адаптера. Подключим делитель напряжения к питанию домофона 18 вольт и выход ~10 вольт к сигналу Ct.
Далее по схеме из части 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.
Посмотрим, что нас ждет впереди.
Комментарии (4)
VadimProfii
21.05.2024 08:45Если не секрет, это где такое? И как биометрия путешествует- все остается в РФии по закону?
sekuzmin Автор
21.05.2024 08:45Абсолютно не секрет, биометрия остается на Raspberry Pi, запертая в кладовке. Не путешествует, это небезопасно в наше время.
eagleivg
А давайте не надо? Уже 100 раз показывалось, что камера элементарно обманывается обычной фотографией.
sekuzmin Автор
Я ждал такого комментария.
Если в подъезд можно зайти просто за кем-то (piggyback), почему я буду беспокоится, что кто-то будет демонстрировать мое фото в камеру?
Да и к тому же будет интересно это посмотреть потом на видео.