Tags: IP камера RTSP R-FCNN распознавание лиц видео-поток landmarks Python DLIB
Введение
Подключение IP камеры и доступ к видео-потоку
Решение проблемы торможения видео-потока от IP камеры
Цикличное переключение видеопотоков от разных камер
Детекция лиц с landmarks точками
Формализация задачи распознавания лица
Выбор из видео-потока корректных изображений лиц
Выбор признаков лица
Принятие решения при распознавании лица
Чтение и запись данных
Полезные ссылки
Введение
Получил комментарий к одной из статей по распознаванию лиц: «Как можно внедрить алгоритм распознавания лиц в домашнего робота? В базе данных робота хранится фото всех членов семьи с их именами. Робот через камеру видит кого-нибудь из них, находит у себя в базе это фото и определяет, кто перед ним находится. Далее обычное голосовое приветствие. Ну, это уже по другой программе…»
Ответил: «В базе данных лучше хранить признаки объектов (лиц), а не фото. В качестве признаков могут быть расстояния между характерными точками лица либо набор признаков (дескриптор лица), получаемых на выходе уже обученной сверточной нейронной сети (см. Face recognition. Python, DLIB). Для оценки похожести полученного списка признаков с теми, что уже есть в базе данных, можно использовать Евклидово расстояние.»
Очевидно, что такой ответ не дает полной картины всех проблем, которые необходимо решать. Поэтому решил написать статью на эту тему с акцентом на практическое применение распознавания лиц.
В предыдущих работах исследования по распознаванию лиц проводились на основе видео-потока, считываемого с встроенной в notebook Web-камеры — через метод cv2.VideoCapture(0). Дальнейшие исследования будут проводиться с подключением IP камер по следующей схеме:
Подключение IP камеры и доступ к видео-потоку
Код для подключения видео-потока с IP камеры приводится ниже.
import cv2
import numpy as np
#cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture('rtsp://192.168.0.100:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream')
while(True):
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Для того, чтобы установить камеру и определить значение параметра (адрес доступа к видеопотоку камеры) в методе cv2.VideoCapture(..?????…) рекомендую прослушать информацию по ссылкам:
Из этой информации я выделил следующую последовательность действий:
- Подключаю IP камеру напрямую к роутеру (по кабелю витая пара через разъем LAN с обоих сторон).
- Через браузер вхожу в настройки роутера (192.168.0.1>admin-admin>DHCP>Список клиентов DHCP). Здесь определяю локальный адрес камеры (у меня 192.168.0.100).
- Выполняю настройки браузера Internet Explorer (выключаю защищенный режим и допускаю использование ActiveX элементов).
- Через браузер Internet Explorer вхожу в настройки камеры (192.168.0.100>admin- у меня без пароля). При этом предлагается подгрузить плагины ActiveX, разрешаю. В итоге должно запуститься приложение NETSurveillince WEB вместе с видео от камеры. Возможно, что после входа будет только серый экран. Это означает, что вы не выполнили все указанные выше настройки браузера Internet Explorer.
- В настройках камеры выбираю (Devicecfg>пиктограмма шестеренка>NetService>dblclick на RTSP). В окне отображается порт камеры — 554.
- Устанавливаю и запускаю программу ONWIF. В ней нахожу мою камеру по IP адресу и нажимаю Livevideo. Внизу окна для видео копирую адрес к видеопотоку моей камеры.
До сих пор у меня камера была подключена к роутеру по проводу. Для подключения ее к беспроводной WiFi сети выполняю следующие действия:
- Через браузер Internet Explorer вхожу в настройки камеры (192.168.0.100>admin- у меня без пароля).
- Далее выбираю Devicecfg>пиктограмма шестеренка>NetService>dblclick на Wifi>Search>моя сеть (SV)>OK.
Перед нажатием кнопки ОК необходимо установить IP адрес, как у своей сети. У меня 3-е число в IP адресе должно быть 0. В противном случае камера не подключится.
Теперь снова вхожу через браузер в настройки роутера (192.168.0.1>admin-admin>DHCP>Список клиентов DHCP). Здесь определяю новый локальный адрес камеры: 192.168.0.101. Раньше у камеры был адрес 192.168.0.100. Т.е., адреса меняются (динамические) при каждом подключении камеры.
Решение проблемы торможения видео-потока с IP камеры
На рисунке слева отображается кадр из видеопотока в моей программе (с определением лица и характерных точек). Справа приложение NETSurveillince WEB, запускаемое в браузере Internet Explorer, здесь можно настроить некоторые из параметров видео-потока.
При первых запусках приложения обнаружил, что происходит торможение видео-потока с IP камеры при подключении детектора лица (detector.detect_faces(frame) ). Возможное решение этой проблемы:
- обрабатывать не все кадры в потоке;
- уменьшать размер кадров.
Ниже приводится код, в котором комбинируются оба подхода.
import cv2 import numpy as np from mtcnn.mtcnn import MTCNN detector = MTCNN() cap = cv2.VideoCapture('rtsp://192.168.0.100:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream') while(True): ret, frame = cap.read() for i in range(20): # skip 20 frames cap.grab() grabbed, frame = cap.read() scale_percent = 50 # percent of original size width = int(frame.shape[1] * scale_percent / 100) height = int(frame.shape[0] * scale_percent / 100) dim = (width, height) # resize image frame = cv2.resize(frame, dim, interpolation = cv2.INTER_AREA) #frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) result = detector.detect_faces(frame) # Result is an array with all the bounding boxes detected. bounding_box = result[0]['box'] keypoints = result[0]['keypoints'] cv2.rectangle(frame, (bounding_box[0], bounding_box[1]), (bounding_box[0]+bounding_box[2], bounding_box[1] + bounding_box[3]), (0,155,255), 1) cv2.circle(frame,(keypoints['left_eye']), 3, (0,155,255), 1) cv2.circle(frame,(keypoints['right_eye']), 2, (0,155,255), 1) cv2.circle(frame,(keypoints['nose']), 3, (0,155,255), 1) cv2.circle(frame,(keypoints['mouth_left']), 3, (0,155,255), 1) cv2.circle(frame,(keypoints['mouth_right']), 3, (0,155,255), 1) cv2.line(frame,(keypoints['left_eye']),keypoints['right_eye'], (0,0,255), 1) cv2.line(frame,(keypoints['left_eye']),keypoints['nose'], (0,255,0), 1) cv2.line(frame,(keypoints['right_eye']),keypoints['nose'], (255,0,0), 1) cv2.imshow('frame',frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
Цикличное переключение видео-потоков от разных камер
Процессор компьютера последовательно обрабатывает информацию. А как быть, если видео-потоки одновременно поступают от разных камер? Можно решить задачу через многопоточность. Но здесь свои проблемы, которые могут даже ухудшить результат. Поэтому решаю задачу по простому — через последовательное переключение видео-потоков от разных камер.
Ниже приводится код, обеспечивающий переключение клавишами 1 и 2 видеопотока от web-камеры, встроенной в notebook, и видеопотока от IP-камеры, подключенной в локальную сеть. Для создания GUI используется библиотека Tkinter. Кадры с камер отображаются в элементе Canvas.
import sys # Tkinter selector if sys.version_info[0] < 3: from Tkinter import * import Tkinter as tk else: from tkinter import * import tkinter as tk import numpy as np import cv2 from PIL import Image, ImageTk def opencvToTk(frame): """Convert an opencv image to a tkinter image, to display in canvas.""" rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_img = Image.fromarray(rgb_image) tk_image = ImageTk.PhotoImage(image=pil_img) return tk_image def drawCamera(canvas, data): data.tk_image = opencvToTk(data.frame) canvas.create_image(data.width / 2, data.height / 2, image=data.tk_image) def redrawAll(canvas, data,root): _, data.frame = data.camera.read() # Redrawing code canvas.delete(ALL) drawCamera(canvas,data) root.after(5, lambda: redrawAll(canvas, data,root)) def new_camera1(data): data.camera = cv2.VideoCapture(0) def new_camera2(data): data.camera = cv2.VideoCapture('rtsp://192.168.0.102:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream') def keyPressed(event, data): if event.keysym == "1": new_camera1(data) if event.keysym == "2": new_camera2(data) pass class Struct(object): pass def run(width, height): root = Tk() data = Struct() data.camera_index = 0 data.camera = cv2.VideoCapture(0) #data.camera = cv2.VideoCapture('rtsp://192.168.0.101:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream') data.width = width data.height = height canvas = Canvas(root, width=width, height=height) canvas.pack(side=LEFT) redrawAll(canvas, data,root) # Переключение камеры через 10сек #root.after(10000, lambda: new_camera2(data)) root.bind("<Key>", lambda event: keyPressed(event, data)) # Loop tkinter root.mainloop() # Once the loop is done, release the camera. print("Releasing camera!") data.camera.release() if __name__ == "__main__": run(500, 500)
Переключение камер клавишами можно заменить автоматическим переключением — при каждом вызове функции redrawAll
def redrawAll(canvas, data,root):
if data.camera_index == 0:
data.camera_index = 1
data.camera = cv2.VideoCapture('rtsp://192.168.0.101:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream')
else:
data.camera_index = 0
data.camera = cv2.VideoCapture(0)
_, data.frame = data.camera.read()
# Redrawing code
canvas.delete(ALL)
drawCamera(canvas,data)
root.after(5, lambda: redrawAll(canvas, data,root))
Можно также устанавливать период переключения камеры через определенные промежутки времени при помощи таймера. Но это уже совсем другая история.
Не забывайте, что при переключении камер не исчезает проблема торможения видео-потока. Ее тоже необходимо решать.
Детекция лиц с landmarks точками
Пришло время добавить в приложение детекцию лиц с landmarks точками. Считается наиболее быстродействующим и точным детектор R-FCNN:
Вот его я и использую в своем комплексном приложении. Детектор R-FCNN подключается через библиотеку DLIB.
import sys # Tkinter selector if sys.version_info[0] < 3: from Tkinter import * import Tkinter as tk else: from tkinter import * import tkinter as tk import numpy as np import cv2 from PIL import Image, ImageTk import dlib def detect_faces_and_landmarks (data): # Конвертирование изображения в черно-белое grayFrame = cv2.cvtColor(data.frame, cv2.COLOR_BGR2GRAY) # Обнаружение лиц и построение прямоугольного контура faces = data.detector(grayFrame) # Обход списка всех лиц попавших на изображение for face in faces: # Выводим количество лиц на изображении cv2.putText(data.frame, "{} face(s) found".format(len(faces)), (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2) # Получение координат вершин прямоугольника и его построение на изображении x1 = face.left() y1 = face.top() x2 = face.right() y2 = face.bottom() cv2.rectangle(data.frame, (x1, y1), (x2, y2), (255, 0, 0), 1) # Получение координат контрольных точек и их построение на изображении landmarks = data.predictor(grayFrame, face) for n in range(0, 68): x = landmarks.part(n).x y = landmarks.part(n).y cv2.circle(data.frame, (x, y), 1, (255, 0, 0), 1) def skip_and_scale_frames(data,skip,scale): for i in range(skip): # skip frames data.camera.grab() grabbed, data.frame = data.camera.read() scale_percent = scale # percent of original size data.width = int(data.frame.shape[1] * scale_percent / 100) data.height = int(data.frame.shape[0] * scale_percent / 100) dim = (data.width, data.height) # resize image data.frame = cv2.resize(data.frame, dim, interpolation = cv2.INTER_AREA) #data.frame = cv2.cvtColor(data.frame, cv2.COLOR_BGR2GRAY) def opencvToTk(frame): """Convert an opencv image to a tkinter image, to display in canvas.""" rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_img = Image.fromarray(rgb_image) tk_image = ImageTk.PhotoImage(image=pil_img) return tk_image def drawCamera(canvas, data): data.tk_image = opencvToTk(data.frame) canvas.create_image(data.width / 2, data.height / 2, image=data.tk_image) def redrawAll(canvas, data,root): if data.camera_index == 0: data.camera_index = 1 data.camera = cv2.VideoCapture('rtsp://192.168.0.102:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream') else: data.camera_index = 0 data.camera = cv2.VideoCapture(0) _, data.frame = data.camera.read() skip_and_scale_frames(data,40,50) detect_faces_and_landmarks (data) # Redrawing code canvas.delete(ALL) drawCamera(canvas,data) root.after(1, lambda: redrawAll(canvas, data,root)) def new_camera1(data): data.camera = cv2.VideoCapture(0) def new_camera2(data): data.camera = cv2.VideoCapture('rtsp://192.168.0.102:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream') def keyPressed(event, data): if event.keysym == "1": new_camera1(data) if event.keysym == "2": new_camera2(data) pass class Struct(object): pass def run(width, height): root = Tk() data = Struct() # Подключение детектора, настроенного на поиск человеческих лиц data.detector = dlib.get_frontal_face_detector() data.predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") data.camera_index = 0 data.camera = cv2.VideoCapture(0) #data.camera = cv2.VideoCapture('rtsp://192.168.0.101:554/user=admin_password=tlJwpbo6_channel=0_stream=0.sdp?real_stream') data.width = width data.height = height canvas = Canvas(root, width=width, height=height) canvas.pack(side=LEFT) redrawAll(canvas, data,root) # Переключение камеры через 10сек #root.after(10000, lambda: new_camera2(data)) root.bind("<Key>", lambda event: keyPressed(event, data)) # Loop tkinter root.mainloop() # Once the loop is done, release the camera. print("Releasing camera!") data.camera.release() if __name__ == "__main__": run(500, 500)
Формализация задачи распознавания лиц
В настоящее время известно множество подходов к распознаванию образов — в общем и к распознаванию лиц — в частности. Прежде чем выбрать какой-либо, попробуем в них разобраться.
Компьютер понимает язык цифр, может их сравнивать. Цифровое фото представляет описание цвета множества точек (см. BMP format). Сравнивать все точки фото из базы данных с точками кадра (frame), полученного от веб камеры, едва ли имеет смысл по ряду причин:
- точки лица занимают только часть изображения;
- цвет точек может меняться в зависимости от освещения;
- положение лица относительно камеры разное.
Известны методы (реализованы в библиотеках), которые позволяют выделить на изображении фрагмент лица и особые точки на нем (см. Обнаружение лица и выделение характерных точек). Расстояния между этими точками могут служить признаками, чтобы различать одно лицо от другого (см. Распознавание лиц на основе OpenCV для C++).
Традиционный алгоритмический подход, как выбрать признаки и распознавать по ним объекты, описан в статье Алгоритмы распознавания геометрических фигур.
Значения признаков могут быть зашиты в программу как обычные условия (см. Распознавание лиц на основе OpenCV для C++). Также значения признаков могут определяться через обучение (см. Распознавание фигур на основе «выборки для обучения»), затем они вместе с идентификатором объекта записываются в базу данных (текстовый файла, как описано в разделе Создание базы данных признаков из статьи Идентификация образов по цвету, текстуре и форме).
Один из важнейших моментов задачи распознавания объектов — как определить субъекта среди претендентов на сходство с ним по множеству признаков. Обычно степень соответствия распознаваемого лица и лиц из базы данных определяется через Евклидово расстояние. Возможны и другие подходы, они рассмотрены в статьях Идентификация по множеству признаков. Основы и Идентификация по множеству признаков при помощи нейросети»
Машинное обучение на основе нейронной сети приходит на смену традиционному алгоритмическому подходу во многих задачах, включая и распознавание лиц. Если в классическом подходе к распознаванию программист анализирует объект для распознавания и выделяет отличительные признаки, то нейронные сети сами решают эту задачу (см. Нейросетевая видеоаналитика. Как это работает. Возможности и ограничения.).
В статьях Машинное обучение распознавать поворот лица а также Адекватность и оптимальность нейронной сети затронуты проблемы, которые вплотную относятся и к задаче распознавания лица на основе НС.
Методы получения признаков и распознавания лиц на основе нейронных сетей сегодня считаются более предпочтительными (см. в youtube лекцию Андрея Созыкина Распознавание человека по лицу). Хотя, могут быть и компромиссные решения. Например, для точности сравнения лиц рекомендуется их выравнивать к положению в анфас. Это можно выполнить на основе 3D-реконструкции лица по характерным точкам. По характерным точкам также можно отфильтровывать не совсем корректные изображения (см. Выбор признаков для фильтрации изображений).
Выбор из видеопотока корректных изображений лица
Для любого из рассмотренных выше методов распознавания лиц существует проблема некорректных изображений, получаемых вследствие плохого освещения, эмоций, положения лица.
Из видеопотока нужно отбирать только корректные изображения, вот такие:
Формальные признаки для выбора корректных изображений лиц — параллельность линий, которые проходят через наиболее характерные симметричные точки лица.
Как формализуется признак параллельности можно посмотреть в статье Алгоритмы распознавания геометрических фигур.
При определении признаков обратите внимание еще на одну особенность детектора точек.
Точки определяются корректно лишь для положения лица в анфас, либо только для одной стороны лица — при сильном повороте головы. Поскольку точки симметричны, то этого может быть достаточно для описания расстояний-признаков. Необходимо лишь определить, в какую сторону повернуто лицо (см. Адекватность и оптимальность нейронной сети на примере распознавания поворота головы) и после этого можно игнорировать точки другой части лица. Используя такой подход можно не ограничиваться отбором признаков лишь для положения в анфас.
Выбор признаков лица
Как было выше отмечено, возможны два подхода к выбору признаков для распознавания:
- классический, при котором вы самостоятельно определяете признаки;
- выбор признаков с помощью нейронной сети.
Предпочитаю первый подход. Даже если он окажется не лучшим, то можно знать почему. А парадоксы нейронной сети не всегда удается объяснить.
Будем выбирать признаки на основе исследований ученых-антропологов, которые выделили различные типы и особенности лица.
Эти особенности могут быть в определенной степени описаны расстояниями между характерными точками лица, которые генерирует для нас детектор лица (R-FCNN).
Расстояние-признак должно быть нормализовано — соотнесено к другому расстоянию, которое пропорционально изменяется при движении лица относительно камеры. Для этого оба расстояния, по возможности, должны быть:
- параллельными;
- близкими;
- соизмеримыми (отношение около 1).
Разбиваем все признаки на группы, в каждой из которой составляются пары размеров, больший из которых используется для нормализации. Если в группе n расстояний, то признаков будет (n-1).
- f1= L4_12/L8_27 овал лица
- f2= L7_9/L6_10 овал лица
- f3= L5_11/L4_12 овал лица
- f4= L3_13/L0_16 овал лица
- f5= Leyes/L19_24 овал лица
- f6= L19_24/L17_26 овал лица
- f7= L21_22/L19_24 овал лица
- f8= LeyeL_4/LeyeL_6 овал лица
- f9= LeyeL_6/LeyeL_8 овал лица
- f10= L13_16/L13_26 овал лица
- f11= L31_35/L48_54 ширина носа и рта
- f12= L27_33/L8_33 длина носа и подбородка
- f13= L33_51/L8_57 положение рта
- f14= L51_57/L8_57 толщина рта
- f15= L43_47/L44_46 ширина глаз
- f16= L44_46/L42_45 ширина и длина глаз
- f17= LeyeL_17/LeyeL_18 форма бровей
- f18= LeyeL_18/LeyeL_19 форма бровей
- f19= LeyeL_19/LeyeL_20 форма бровей
- f20= LeyeL_20/LeyeL_21 форма бровей
- f21= L33_50/L33_51 форма рта
- f22= L51_62/L66_57 форма рта
- f23= L49_61/L59_67 форма рта
- f24= L49_60/L59_60 форма рта
Силу признака можно оценить отношением D/d, где d — допуск признака; D — расстояние между соседними средними значениями признаков (подробнее см. Идентификация по множеству признаков).
Можно существенно увеличить силу признака, если брать его усредненные значения по нескольким кадрам. Для сравнения на рисунке слева приводятся значения признака f1, усредняемого с каждым кадром, и значения этого признака (неусредненные) на каждом из 20 кадров. На рисунке справа сопоставляются среднее значения признака f1 (для выборки от 10 до 20 кадров) и диапазон (Range) значений этого признака для 10 разных лиц.
Информация по другим признакам приведена в таблицах 1 и 2.
В табл.2 диапазон (Range) разброса признаков для различных лиц отнесен к диапазону разброса признаков для одного лица (табл.1). По этому показателю легко оценить силу признака.
Итого у нас 24 признака, каждый из которых имеет средний относительный диапазон значений больше 10, т.е., один признак может отсеивать 1/10 часть претендентов. Оценим, много это или мало?
Допустим, у нас есть около 1000000 претендентов, из которых необходимо распознать одного субъекта. Если по каждому признаку отсеивать 1/10 часть претендентов, то получим следующую геометрическую прогрессию:
1000000->100000->10000 ->1000->100->10->1.
Т.е., для распознавания субъекта достаточно использовать фильтр только из 6 признаков. Еще 18 признаков остаются в резерве.
Принятие решений при распознавании лица
Для оценки соответствия признаков детектируемого лица субъекта (Subject) признакам лица претендента (Applicant) из базы данных, можно использовать комплексный признак, например, Евклидово расстояние. Но, прежде чем сравнивать субъекта и претендента по комплексному признаку, имеет смысл провести оценку схожести лиц по каждому из признаков в отдельности.
Например, если у субъекта широкий нос или рот, а претендент не имеет таких особенностей, то зачем выполнять дальнейшие расчеты. Можно сразу же игнорировать такого претендента и переходить к оценке сходства со следующим претендентом.
Такой подход дает возможность дифференцировано подходить к оценке каждой пары субъекта и претендента. Одна пара может отличаться шириной рта, другая — шириной носа. При сравнении только лишь по комплексному признаку такие специфические отличия субъекта и претендента могут быть нивелированы.
Таким образом, процесс распознавание лица разбивается на 2 этапа:
- Последовательная проверка лиц претендентов на схожесть с лицом субъекта по каждому из признаков в отдельности. Если разница между значениями признака претендента и субъекта окажется меньше допустимого значения, то претендент игнорируется. Если все претенденты игнорируются на 1-м этапе, то 2-го этапа не будет. Субъект в этом случае сразу же добавляется в базу данных.
- Оценка степени схожести отобранных претендентов по комплексному признаку (Евклидово расстояние). На этом этапе выбирается один претендент из множества отобранных на 1 этапе. Если Евклидово расстояние для всех претендентов окажется больше допустимого значения. то игнорируются все претенденты. Субъект в этом случае добавляется в базу данных.
На первом этапе претенденты сначала обрабатываются наиболее сильным признаком, затем послабее. Это обеспечивает более быстрое отсеивание претендентов на сходство с субъектом.
Ниже приводится простой код для тестирования алгоритма по данным из таблиц 1 и 2.
Тестирование этапа 1:
limits = ["",0.005,0.004,0.002,0.002,0.006,0.006,0.001,0.005,0.001,0.011, 0.005,0.028,0.008,0.005,0.019,0.022,0.010,0.025,0.007,0.026, 0.010,0.018,0.012,0.019] # subject = applicants[10] subject = ["",0.938,0.564,0.851,0.882,0.865,0.622,0.260,0.736,0.848,0.911, 0.454,0.748,0.557,0.264,1.004,0.333,1.138,1.307,1.036,0.759, 0.912,0.362,0.979,0.846] check = ["",1,1,1,1,1,1,1,1,1,1] applicants = [ ["1", 1.052,0.532,0.820,0.882,0.879,0.613,0.306,0.774,0.848,0.881, 0.472,0.800,0.499,0.524,1.009,0.352,1.191,1.218,1.080,0.785, 1.001,0.499,0.819,0.790], ["2", 0.918,0.540,0.820,0.891,0.822,0.638,0.297,0.743,0.841,0.939, 0.521,0.750,0.499,0.357,1.009,0.383,1.081,1.297,1.166,0.795, 0.976,0.467,0.800,0.867], ["3", 0.960,0.542,0.824,0.862,0.830,0.653,0.308,0.742,0.849,0.860, 0.535,0.862,0.323,0.334,0.957,0.349,0.996,1.161,1.040,0.856, 1.038,0.766,1.079,0.823], ["4", 1.184,0.509,0.820,0.890,0.845,0.604,0.243,0.836,0.862,0.875, 0.560,0.921,0.420,0.235,1.0, 0.281,1.236,1.252,0.944,0.794, 1.0, 0.542,0.880,0.922], ["5", 1.035,0.548,0.842,0.898,0.853,0.619,0.268,0.821,0.891,0.855, 0.525,0.755,0.381,0.385,0.857,0.333,1.300,1.379,0.872,0.676, 0.969,0.496,0.868,0.810], ["6", 0.948,0.532,0.826,0.872,0.766,0.655,0.379,0.812,0.874,0.741, 0.523,0.717,0.406,0.406,0.986,0.264,1.055,1.114,1.043,0.976, 1.041,0.75 ,0.877,1.0 ], ["7", 0.999,0.535,0.838,0.866,0.901,0.626,0.338,0.789,0.885,0.796, 0.478,0.686,0.540,0.352,1.0 ,0.423,1.235,1.215,0.900,0.806, 0.949,0.755,0.749,1.220], ["8", 1.047,0.517,0.819,0.944,0.837,0.622,0.217,0.787,0.854,0.940, 0.501,0.721,0.420,0.301,1.0 ,0.207,1.177,1.127,0.960,0.821, 1.026,0.5 ,0.922,0.875], ["9", 1.019,0.517,0.793,0.907,0.763,0.656,0.334,0.781,0.837,0.957, 0.551,0.651,0.343,0.396,1.0 ,0.250,1.072,1.242,1.212,0.901, 1.029,0.4 ,0.827,0.780], ["10",0.938,0.564,0.851,0.882,0.865,0.622,0.260,0.736,0.848,0.911, 0.454,0.748,0.557,0.264,1.004,0.333,1.138,1.307,1.036,0.759, 0.912,0.362,0.979,0.846]] for i in range(0, 10): if(check[i] ==1): for j in range(1, 25): dif= abs(subject[j]-applicants[i][j]) tol = limits[j] if (dif>tol): check[i]=0 for i in range(0, 10): if(check[i] ==1): print(applicants[i][0])
Результат (претендент №10) печатается в окне консоли:
Тестирование этапа 2 (данные используются те же):
import cmath # subject = applicants[10] subject = [0.939,0.565,0.852,0.882,0.865,0.622,0.260,0.736,0.848,0.911, 0.454,0.748,0.557,0.264,1.004,0.333,1.138,1.307,1.036,0.759, 0.912,0.362,0.979,0.846] dif = [0,0,0,0,0,0,0,0,0,0] applicants = [ [1.052,0.532,0.820,0.882,0.879,0.613,0.306,0.774,0.848,0.881, 0.472,0.800,0.499,0.524,1.009,0.352,1.191,1.218,1.080,0.785, 1.001,0.499,0.819,0.790], [0.918,0.540,0.820,0.891,0.822,0.638,0.297,0.743,0.841,0.939, 0.521,0.750,0.499,0.357,1.009,0.383,1.081,1.297,1.166,0.795, 0.976,0.467,0.800,0.867], [0.960,0.542,0.824,0.862,0.830,0.653,0.308,0.742,0.849,0.860, 0.535,0.862,0.323,0.334,0.957,0.349,0.996,1.161,1.040,0.856, 1.038,0.766,1.079,0.823], [1.184,0.509,0.820,0.890,0.845,0.604,0.243,0.836,0.862,0.875, 0.560,0.921,0.420,0.235,1.0, 0.281,1.236,1.252,0.944,0.794, 1.0, 0.542,0.880,0.922], [1.035,0.548,0.842,0.898,0.853,0.619,0.268,0.821,0.891,0.855, 0.525,0.755,0.381,0.385,0.857,0.333,1.300,1.379,0.872,0.676, 0.969,0.496,0.868,0.810], [0.948,0.532,0.826,0.872,0.766,0.655,0.379,0.812,0.874,0.741, 0.523,0.717,0.406,0.406,0.986,0.264,1.055,1.114,1.043,0.976, 1.041,0.75 ,0.877,1.0 ], [0.999,0.535,0.838,0.866,0.901,0.626,0.338,0.789,0.885,0.796, 0.478,0.686,0.540,0.352,1.0 ,0.423,1.235,1.215,0.900,0.806, 0.949,0.755,0.749,1.220], [1.047,0.517,0.819,0.944,0.837,0.622,0.217,0.787,0.854,0.940, 0.501,0.721,0.420,0.301,1.0 ,0.207,1.177,1.127,0.960,0.821, 1.026,0.5 ,0.922,0.875], [1.019,0.517,0.793,0.907,0.763,0.656,0.334,0.781,0.837,0.957, 0.551,0.651,0.343,0.396,1.0 ,0.250,1.072,1.242,1.212,0.901, 1.029,0.4 ,0.827,0.780], [0.938,0.564,0.851,0.882,0.865,0.622,0.260,0.736,0.848,0.911, 0.454,0.748,0.557,0.264,1.004,0.333,1.138,1.307,1.036,0.759, 0.912,0.362,0.979,0.846]] for i in range(0, 10): for j in range(0, 24): dif[i]= dif[i]+(subject[j]-applicants[i][j])**2 for i in range(0, 10): dif[i]= cmath.sqrt(dif[i]) print (dif[i])
Результат получен аналогичный. Претендент №10 имеет наименьшее расхождение по комплексному признаку (Евклидово расстояние):
Чтение и запись данных
Вспомним, с чего началась статья. С робота, который приветствует домочадцев. В соответствии с этой задачей создадим простенькую базу данных из текстового файла, в котором определены имена всех членов семьи и их признаки для распознавания (см. аналогичный пример Создание базы данных признаков продуктов).
Робот детектирует лицо субъекта на какую-либо из 2-х видеокамер (вместо глаз) и определяет по 10-20 кадрам усредненные признаки для распознавания. Затем считывает из файла base.txt признаки претендентов и сравнивает их с признаками субъекта. Фрагмент кода для считывания какого-либо признака из файла приводится ниже:
handle = open("base.txt", "r") data = handle.readlines() # read ALL the lines! #print(data) print(data[0]) d=data[0].split(' ') # line in list print(d) print(d[0]) print(float(d[1]),float(d[2])) handle.close()
Если признаки какого-либо из претендентов (например, Ap1) соответствуют признакам субъекта, тогда приветствие «Hi, Ap1». Если признаки ни одного из претендентов не соответствуют признакам субъекта, тогда «Nice to meet you. What is your name?». Имя незнакомца (например, Ap11) вместе с его признаками добавляется в базу данных. Фрагмент кода для добавления какого-либо субъекта в файл base.txt приводится ниже:
handle = open("base.txt", "a") subject = ["Ap11", 0.938,0.564,0.851,0.882,0.865,0.622,0.260,0.736,0.848,0.911, 0.454,0.748,0.557,0.264,1.004,0.333,1.138,1.307,1.036,0.759, 0.912,0.362,0.979,0.846] d = str(subject[0]) for i in range(1, 25): d = d +' '+ str(subject[i]) handle.write('\n'+d) handle.close()
Полезные ссылки:
- Object Tracking In Surveillance Video
- Обнаружение сонливости с помощью OpenCV
- Real-time Face Recognition on Home Security Cameras using Python and Jetson Nano (Diary) — part 1
- Human Face detection and Recognition-Theoretical approach
- Your Face Is Not Safe Online. Here’s What You Can Do.
- Facial Analysis With Masks? Learn How To Achieve 96% Accuracy
- Recognition of faces in real time
- Important Python Snippets for Image Processing
- Real-Time face detection and recognition on CPU using Face Library
- Face Detection Models and their Performance Comparison
- The Battlefield of Cutting Edge Face Detectors. A Comparison between OpenCV, Dlib, Xailient and MTCNN
- Face Detection Models and their Performance Comparison
- Face Detection Explained: State-of-the-Art Methods and Best Tools
- Detect Spoofing with Fast Facial Recognition
- Extraction of frames from a single video
- Face Recognition Using ‘face_recognition’ API
- Facial Recognize in Python
- OpenCV-Python: Reading and Writing Images and Videos
- How to build a face detection and recognition system
- Подключение IP камеры к компьютеру, изменение IP адреса камеры
- Dahua Face Recognition New Version
- Удалённый доступ с помощью TeamViewer
- Работа с файлами в Python
- Антропометрические точки головы
- Step by Step Facial Recognition in Python
- Списки, кортежи и словари
- Распознавание лиц – лучшее в мире
- Canvas. Идентификаторы, теги и анимация
- Большой тест мини-ПК 2019
- Как подключиться к серверу по SSH?
- Стриминг и распознавание лиц через веб-камеру
- 6 способов уменьшить поток с IP камеры
- RTSP ПОТОК С КАМЕР ВИДЕОНАБЛЮДЕНИЯ
- Access IP Camera in Python OpenCV
- Пишем программу для автоматического распознавания объектов с веб-камер
- Как раздать Wi-Fi со смартфона
- Не работает раздача Wi-Fi на Android
- Как подключить ip камеру к компьютеру через роутер и напрямую: пошаговая инструкция
- Понятие TCP/IP-адресации и основные сведения о подсетях
- Кто подключен к Wi-Fi роутеру
- Сервер DHCP на роутере
- Установка Google Play Market на любой Meizu
- Самая дешевая поворотная IP камера V380 , обзор и настройка
- V380 wi-fi ip камера подключение к роутеру настройка ip камеры с телефона
- Видеонаблюдение через интернет: 4 способа настройки удаленного доступа к IP камерам
- IP видеонаблюдение #2. Подключение IP камер через роутер
- Установка видеонаблюдения в магазине
- Как можно подсоединить камеру наблюдения к компьютеру
- Организация удалённого видеонаблюдения через Интернет
- Как использовать Samsung Galaxy как модем или точку доступа Wi-Fi
- Инструкция по настройке мини IP Wi-Fi камеры Sricam
- Поворотная Wi-Fi камера с функцией переговорного устройства через телефон
- Доступ к IP-камере в Python OpenCV
- Как настроить ip-камеру с помощью веб-интерфейса
- Lechange (Imou) приложение видеонаблюдения. Просмотр онлайн, настройка, запись в облако
- Захват видео с сетевых камер, часть 1
- Программный захват с вебкамеры
- Стриминг и распознавание лиц через веб-камеру
- Как взламываются веб-камеры
- Как выбрать беспроводную Wi-Fi камеру видеонаблюдения для улицы?
- Домашнее видеонаблюдение своими руками
- Нейросетевая видеоаналитика. Как это работает. Возможности и ограничения.
- Importing Data in Python
- Face Recognition Ivideon: самая доступная система распознавания лиц для бизнеса
- Просто о сложном: технология распознавания лиц
- Модуль распознавания лиц в ПО TRASSIR
- Codius. Список статей по метке Камера
- Advantages of Using Python for Computer Vision
- Как собрать простую систему распознавания лиц в режиме реального времени
- Как работает система видеонаблюдения в Киеве
- Система распознавания лиц для сельской калитки
- ОБЗОР СУЩЕСТВУЮЩИХ ПОДХОДОВ И МЕТОДОВ РАСПОЗНАВАНИЯ ЛЮДЕЙ ПО ФОТОПОРТРЕТАМ
- Исследование эффективности методов обработки изображений в системах распознавания лиц.
- Нейросетевая модель компьютерного распознавания людей по изображениям лиц с видеокамеры
- Создать систему распознавания лиц у входной двери за $150 с помощью одноплатного компьютера и кода на Python
- Building a Face Attributes Model using Multi-Task Learning
- Системы видеонаблюдения. Виды и применение. Устройство и работа
- РАСПОЗНАВАНИЕ ЧЕЛОВЕКА ПО ИЗОБРАЖЕНИЮ ЛИЦА НЕЙРОСЕТЕВЫМИ МЕТОДАМИ
- Системы распознавания лиц. Разрушители мифов видеонаблюдения #3
- Технологии распознавания лиц. Мифы, задачи и решения.
- Александр Кабаков, NtechLab: Нейронная сеть для распознавания лиц
- Распознавание лиц в реальном времени по базам фотографий глобального масштаба / Кухаренко А., Кабаков А. (N-Tech.Lab)
- Распознавание лиц с помощью глубоких нейронных сетей (Сергей Миляев, VisionLabs)
- Получаем ссылки на профили Vk из выдачи SearchFace с помощью Python
- Датасеты для распознавания лиц в сложных условиях — в масках, очках, с макияжем
- Оценка качества алгоритмов распознавания лиц
- Как обмануть алгоритм распознавания лиц: быстрая генерация состязательных данных
- Face Recognition Ivideon: самая доступная система распознавания лиц для бизнеса
- Распознавание лиц в системе видеонаблюдения. Зачем и как это работает.
- Технология распознавания лиц — новая эра в видеоаналитике, системах видеонаблюдения и контроля доступа
- ТЕХНОЛОГИИ ПОДСЧЕТА ПОСЕТИТЕЛЕЙ В СФЕРЕ РИТЕЙЛА
- Уникальная российская разработка — система видеонаблюдения «Видеогард»
- FINDFACE. РАСПОЗНАВАНИЕ ЛИЦ
- Удаленное видеонаблюдение через телефон и интернет
- Видеонаблюдение в магазине — неочевидные возможности
- Как устроена система видеонаблюдения Ivideon: обзор софта для ПК
- Система видеонаблюдения с функцией распознавания лиц
- Терминал учета рабочего времени с функцией распознавания лиц DHI-ASA4214F
- Комплект Smart IP видеонаблюдения охраны периметра и детекции лиц
- Как получить доход от видеоаналитики: пять инсайтов
- Детекция лиц. Правила установки камеры. Настройка
- Видеоаналитика в камере. Разрушители мифов видеонаблюдения #4
- Решение типовых задач при проектировании систем видеонаблюдения
Автор: Николай Свирневский