Обработка видеопотоков
Обзор
Для обработки видеопотоков в Face SDK используется интерфейсный объект VideoWorker
, который берет на себя всю необходимую синхронизацию и контроль за потоками. Вам необходимо только подавать кадры видеопотока и реализовать несколько коллбэков.
VideoWorker
можно использовать для решения следующих задач:
- Трекинг лиц
- Создание биометричеких шаблонов
- Оценка пола, возраста и эмоций
- Оценка Liveness
- Кратковременная идентификация
- Идентификация лиц
Пример использования объекта VideoWorker
см. в сэмпле video_recognition_demo.
Связанные туториалы:
Создание объекта VideoWorker
Создать объект VideoWorker
можно с помощью метода FacerecService.createVideoWorker
.
Примеры
- C++
- C#
- Java
- Python
pbio::FacerecService::Config video_worker_config("video_worker_lbf.xml");
video_worker_config.overrideParameter("search_k", 3);
pbio::VideoWorker::Ptr video_worker = service->createVideoWorker(
pbio::VideoWorker::Params()
.video_worker_config(video_worker_config)
.recognizer_ini_file(recognizer_config)
.streams_count(streams_count)
.processing_threads_count(processing_threads_count)
.matching_threads_count(matching_threads_count)
.age_gender_estimation_threads_count(age_gender_estimation_threads_count)
.emotions_estimation_threads_count(emotions_estimation_threads_count)
.short_time_identification_enabled(enable_sti)
.short_time_identification_distance_threshold(sti_recognition_threshold)
.short_time_identification_outdate_time_seconds(sti_outdate_time)
);
FacerecService.Config video_worker_config = new FacerecService.Config("video_worker_lbf.xml");
video_worker_config.overrideParameter("search_k", 3);
VideoWorker video_worker = service.createVideoWorker(
new VideoWorker.Params()
.video_worker_config(video_worker_config)
.recognizer_ini_file(recognizer_config)
.streams_count(streams_count)
.processing_threads_count(processing_threads_count)
.matching_threads_count(matching_threads_count)
.age_gender_estimation_threads_count(age_gender_estimation_threads_count)
.emotions_estimation_threads_count(emotions_estimation_threads_count)
.short_time_identification_enabled(enable_sti)
.short_time_identification_distance_threshold(sti_recognition_threshold)
.short_time_identification_outdate_time_seconds(sti_outdate_time)
);
FacerecService.Config video_worker_config = service.new Config("video_worker_lbf.xml");
video_worker_config.overrideParameter("search_k", 3);
VideoWorker video_worker = service.createVideoWorker(
new VideoWorker.Params()
.video_worker_config(video_worker_config)
.recognizer_ini_file(recognizer_config)
.streams_count(streams_count)
.processing_threads_count(processing_threads_count)
.matching_threads_count(matching_threads_count)
.age_gender_estimation_threads_count(age_gender_estimation_threads_count)
.emotions_estimation_threads_count(emotions_estimation_threads_count)
.short_time_identification_enabled(enable_sti)
.short_time_identification_distance_threshold(sti_recognition_threshold)
.short_time_identification_outdate_time_seconds(sti_outdate_time)
);
video_worker_config = Config("video_worker_lbf.xml")
video_worker_config.override_parameter("search_k", 3)
video_worker_params = video_worker.Params()
video_worker_params.video_worker_config = video_worker_config
video_worker_params.recognizer_ini_file = recognizer_config
video_worker_params.streams_count = streams_count
video_worker_params.processing_threads_count = processing_threads_count
video_worker_params.matching_threads_count = matching_threads_count
video_worker_params.age_gender_estimation_threads_count = age_gender_estimation_threads_count
video_worker_params.emotions_estimation_threads_count = emotions_estimation_threads_count
video_worker = service.create_video_worker(video_worker_params)
Где:
video_worker_config
– путь до файла конфигурацииVideoWorker
или объектFacerecService.Config
.video_worker_params
– параметры конструктораVideoWorker
.recognizer_config
– файл конфигурации объектаRecognizer
(см. Распознавание лиц).streams_count
– количество видеопотоков, для каждого из которых будет создан поток трекинга.processing_threads_count
– количество потоков для создания шаблонов лиц (потоки обработки). Эти потоки являются общими для всех видеопотоков и распределяют ресурсы равномерно по все видеопотокам независимо от их загруженности (за исключением видеопотоков без лиц в кадре).matching_threads_count
– количество потоков для сравнения шаблонов лиц, созданных из кадров видеопотоков, с базой. Как и потоки обработки, они распределяют работу равномерно по всем видеопотокам.age_gender_estimation_threads_count
– количество потоков для определения пола и возраста. Как и потоки обработки, они распределяют работу равномерно по всем видеопотокам.emotions_estimation_threads_count
– количество потоков для определения эмоций. Как и потоки обработки, они распределяют работу равномерно по всем видеопотокам.enable_sti
– флаг, включающий кратковременную идентификацию.sti_recognition_threshold
– порог для кратковременной идентификации.sti_outdate_time
– длина временного интервала для кратковременной идентификации в секундах.
Все доступные файлы конфигурации хранятся в папке conf дистрибутива Face SDK.
Подача кадров
Для подачи кадров видеопотока в VideoWorker
используйте метод VideoWorker.addVideoFrame
. Этот метод потокобезопасен, поэтому можно подавать кадры из разных потоков без дополнительной синхронизации.
В качестве аргументов метода указываются frame
(цветное изображение кадра), stream_id
(целочисленный идентификатор видеопотока) и timestamp_microsec
(временная метка кадра в микросекундах). Метод возвращает frame_id
(целочисленный идентификатор кадра), который будет использоваться в коллбэках для обозначения этого кадра.
Коллбэки
Передача результатов обработки кадров реализована с помощью набора коллбэков. Данные обработки, получаемые с разных потоков, оформляются в структуру типа data
, которая передается в качестве аргумента вызываемого коллбэка. Атрибуты структуры data
отличаются для каждого типа коллбэка.
В зависимости от решаемых задач в Face SDK реализованы следующие типы коллбэков:
- TrackingCallbackU (Трекинг, оценка пола, возраста и эмоций, оценка Liveness)
- TrackingLostCallbackU (Трекинг лиц)
- TemplateCreatedCallbackU (Создание шаблонов)
- MatchFoundCallbackU (Идентификация)
- StiPersonOutdatedCallbackU (Кратковременная идентификация)
Чтобы добавить коллбэк, используйте метод VideoWorker.add(имя коллбэка)
. Метод возвращает callback_id
(целочисленный идентификатор коллбэка). Чтобы удалить коллбэк, воспользуйтесь методом VideoWorker.remove(имя коллбэка)
, передав callback_id
в качестве аргумента.
Трекинг лиц
Если VideoWorker
используется только для трекинга лиц, в параметрах конструктора необходимо указать matching_thread=0
и processing_thread=0
и применить лицензию Face Detector. При создании объекта VideoWorker
для одного потока укажите параметр streams_count=1
.
Результаты трекинга передаются с помощью двух коллбэков:
VideoWorker.TrackingCallbackU (Tracking-коллбэк)
Во время нахождения человека в поле зрения камеры формируется его трек (последовательность кадров видеопотока, на которых изображен один и тот же человек). Каждому треку присваивается свой целочисленный идентификатор (track_id).
Кадры видеопотока попадают в конвейер трекинга - структуру, которая отвечает за синхронизацию и распределение кадров по потокам обработки. После обработки каждого кадра вызывается Tracking-коллбэк, который возвращает результаты трекинга. Результаты трекинга фиксируются в передаваемой структуре TrackingCallbackData
(C++, Java, C#, Python).
Tracking-коллбэки с одинаковым идентификатором stream_id
вызываются в порядке возрастания frame_id
. Поэтому если сразу после коллбэка со stream_id=1
и frame_id=100
был получен коллбэк со stream_id=1
и frame_id=102
, значит кадр с frame_id=101
был пропущен для видеопотока 1.
VideoWorker.TrackingLostCallbackU (TrackingLost-коллбэк)
Этот коллбэк вызывается, когда человек вышел из кадра (трек потерян), и возвращает лучший сэмпл и шаблон лица. Лучший сэмпл может быть пустым, если включен конфигурационный параметр weak_tracks_in_tracking_callback
. Результаты обработки фиксируются в передаваемой структуре TrackingLostCallbackData
(C++, Java, C#, Python).
Коллбэк вызывается последним для пары <stream_id, track_id>
. После него ни один Tracking-, MatchFound- или TrackingLost-коллбэк для видеопотока stream_id
не может содержать сэмпла с этим же идентификатором track_id
.
Для каждой пары <stream_id, track_id>
, которая была передана в Tracking-коллбэке, существует ровно один TrackingLost-коллбэк.
Исключение составляют треки, удаленные в процессе сброса состояния работы видеопотока с помощью метода VideoWorker.resetStream
.Метод возвращает track_id_threshold
, целое число, означающее, что все удаленные в ходе resetStream треки имели track_id < track_id_threshold
, а все новые треки будут иметь track_id >= track_id_threshold
. После возврата управления от resetStream
не будет вызвано ни одного коллбэка, относящегося к предыдущим трекам, включая TrackingLost-коллбэк.
Ошибки, возникшие в коллбэках, будут перехвачены и сгенерированы заново в методе VideoWorker.checkExceptions
, поэтому не забывайте регулярно вызывать метод VideoWorker.checkExceptions
для контроля ошибок.
Не вызывайте методы, которые изменяют состояние VideoWorker
внутри коллбэков, во избежание взаимной блокировки. Безопасными для вызова в коллбэках являются только методы VideoWorker.getMethodName
и VideoWorker.getStreamsCount
.
Создание шаблонов
Если VideoWorker
используется для трекинга и создания биометрических шаблонов, в параметрах конструктора необходимо указать processing_thread>0
и matching_thread=0
и использовать лицензию Video Engine Standard. При создании VideoWorker
для одного потока укажите параметры streams_count=1
, processing_threads_count=1
, matching_threads_count=0
.
VideoWorker.TemplateCreatedCallbackU (TemplateCreated-коллбэк)
Коллбэк VideoWorker.TemplateCreatedCallbackU
возвращает результаты генерации шаблонов в виде структуры TemplateCreatedCallbackData
(C++, Java, C#, Python). Коллбэк вызывается каждый раз, когда внутри VideoWorker
создается шаблон.
TemplateCreated-коллбэк вызывается после как минимум одного Tracking-коллбэка и перед TrackingLost-коллбэком с теми же stream_id
и track_id
.
Создание шаблонов включено по умолчанию для всех видеопотоков. Вы можете включить/отключить создание шаблонов для конкретного видеопотока с помощью методов VideoWorker.disableProcessingOnStream
и VideoWorker.enableProcessingOnStream
.
Оценка пола, возраста и эмоций
Для оценки пола и возраста в параметрах конструктора VideoWorker
необходимо указать age_gender_estimation_threads_count > 0
, а для оценки эмоций - параметр emotions_estimation_threads_count > 0
.
Данные о поле, возрасте и эмоциях приходят в коллбэк VideoWorker.TrackingCallbackU
. Если данные об эмоциях обновляются в режиме реального времени, то данные о поле и возрасте пересчитываются только в случае, если найден сэмпл с лучшим качеством.
Оценка пола, возраста и эмоций включена по умолчанию для всех видеопотоков.
Отключить оценку пола, возраста и эмоций на конкретном потоке можно при помощи методов:
VideoWorker.disableAgeGenderEstimationOnStream
(пол и возраст)VideoWorker.disableEmotionsEstimationOnStream
(эмоции)
Заново включить определение пола, возраста и эмоций на конкретном потоке можно при помощи методов:
VideoWorker.enableAgeGenderEstimationOnStream
(пол и возраст)VideoWorker.enableEmotionsEstimationOnStream
(эмоции)
Оценка Liveness
Активная (сценарная) проверка
Данный тип оценки Liveness требует от пользователя выполнения определенных действий (сценария), например, "повернуть голову", "моргнуть" и т.д.
Для включения проверок необходимо указать параметр enable_active_liveness = 1
в файле конфигурации объекта VideoWorker
. После этого все лица для идентификации будут проходить через несколько проверок:
- SMILE: улыбка. Для использования проверки
SMILE
необходимо указать количество потоков в параметреemotions_estimation_threads_count
объектаVideoWorker
. - BLINK: моргание
- TURN_UP: поворот головы вверх
- TURN_DOWN: поворот головы вниз
- TURN_RIGHT: поворот головы вправо
- TURN_LEFT: поворот головы влево
- PERSPECTIVE: проверка изменения положения лица (необходимо приблизить лицо к камере)
Чтобы включить/отключить проверку, откройте файл конфигурации active_liveness_estimator.xml
и укажите значения 0
(проверка выключена) или 1
(проверка включена) для одной или нескольких проверок: check_smile
, check_perspective
, check_blink
, check_turn_up
, check_turn_down
, check_turn_right
, check_turn_left
.
Также, в файле конфигурации active_liveness_estimator.xml
можно настроить следующие параметры проверки:
check_count
: количество включенных проверок для прохождения. Если указанное число меньше количества включенных проверок, система произвольно выберет несколько проверок для прохождения, а если указанное число больше количества включенных проверок, некоторые проверки будут повторяться несколько раз.max_frames_wait
: время ожидания начала выполнения проверки (в кадрах). Если за это время проверка так и не началась, она считается невыполненной, и возвращается статусCHECK_FAIL
.rotation_yaw_threshold
: порог прохождения проверки. Чтобы пройти проверку, нужно повернуть голову под указанным углом.rotation_pitch_threshold
: порог прохождения проверки. Чтобы пройти проверку, нужно повернуть голову под указанным углом.blinks_threshold
: порог прохождения проверки. 0.3 - значение по умолчанию, 0 - глаз закрыт, 1 - глаз открыт. Моргание засчитывается, если выставленное значение равно или менее 0.3.blinks_number
: количество морганий необходимых для прохождения проверки.emotion_threshold_smile
: порог для проверкиsmile
. Чем меньше указанное значение, тем слабее нужно улыбнуться, чтобы пройти проверку.face_align_angle
: перед началом проверки и между проверками лицо должно находиться в нейтральном положении (фронтально по направлению к камере). Значение параметра - это максимально допустимое отклонение углов поворота головы для начала проверки.
Порядок проверок может быть случайным (данный режим выбран по умолчанию), либо задан при инициализации (путем создания списка из неповторяющихся проверок).
Пример списка проверок представлен в демонстрационной программе video_recognition_demo
(C++/C#/Java/Python).
Статус проверки приходит в свойство active_liveness_result
коллбэка TrackingCallback
, которое содержит следующие поля:
verdict
: статус текущей проверки (объектActiveLiveness.Verdict
)type
: тип проверки (объектActiveLiveness.LivenessChecks
)progress_level
: степень прогресса прохождения проверки – число в диапазоне [0,1]
Объект ActiveLiveness.Verdict
содержит следующие поля:
ALL_CHECKS_PASSED
: все проверки пройденыCURRENT_CHECK_PASSED
: текущая проверка пройденаCHECK_FAIL
: проверка не пройденаWAITING_FACE_ALIGN
: ожидание нейтрального положения лицаNOT_COMPUTED
: оценка принадлежности лица реальному человеку не производитсяIN_PROGRESS
: выполняется проверка
Идентификация лиц
Для трекинга лиц, создания биометрических шаблонов и сравнения их с базой (идентификация) в параметрах конструктора необходимо указать matching_thread>0
и processing_thread>0
и применить лицензию Video Engine Extended. При создании VideoWorker
для одного потока необходимо указать параметры streams_count=1
, processing_threads_count=1
и matching_threads_count=1
.
Чтобы задать или изменить базу данных, используйте метод VideoWorker.setDatabase
(может быть вызван в любое время). В качестве аргументов передайте elements
(вектор элементов базы) и acceleration
(тип ускорения поиска).
Идентификация выполняется следующим образом: по сэмплу отслеживаемого лица создается биометрический шаблон, который сравнивается с шаблонами из базы данных, и если расстояние до ближайшего элемента оказывается меньше порогового расстояния distance_threshold
, указанного в этом элементе, фиксируется совпадение.
Коллбэк VideoWorker.MatchFoundCallbackU
вызывается после N
последовательных совпадений с элементами, относящимися к одному и тому же человеку, и возвращает результат сравнения с базой (идентификации). Результат сравнения фиксируется в передаваемой структуре MatchFoundCallbackData
(C++, Java, C#, Python).
Также, выставив значение параметра файла конфигурации <not_found_match_found_callback>
равным 1
, можно включить вызов этого коллбэка после N
последовательных несовпадений (т.е. когда ближайший элемент оказывается дальше порогового расстояния distance_threshold
). В этом случае идентификатор match_result
первого элемента в MatchFoundCallbackData.search_result
будет с нулевым расстоянием, а идентификаторы person_id
и element_id
будут равны VideoWorker.MATCH_NOT_FOUND_ID
. Число N
можно задать в файле конфигурации в параметре <consecutive_match_count_for_match_found_callback>
.
Коллбэк вызывается после как минимум одного Tracking-коллбэка и перед TrackingLost-коллбэком с теми же stream_id
и track_id
.
Максимальное количество элементов, возвращаемое в MatchFoundCallbackData.search_result
, устанавливается в файле конфигурации в параметре search_k
и может быть изменено с помощью метода FacerecService.Config.overrideParameter
(см. Примеры).
Кратковременная идентификация
Кратковременная идентификация не влияет на использование лицензии. Требуется по крайней мере один поток для создания шаблонов processing_thread>0
.
Кратковременная идентификация (short time identification, STI) позволяет системе узнать человека, проходившего перед камерой некоторое время назад, даже если этот человек отсутсвует в базе, и даже если идентификация отключена. Таким образом, один и тот же человек, который в течение, например, одной минуты несколько раз выходил из кадра и снова заходил в кадр, будет идентифицироваться как одно и то же лицо.
Включить кратковременную идентификацию можно с помощью флага enable_sti
в параметрах конструктора VideoWorker
.
При попадании человека в кадр по кадру создается сэмпл, по которому строится биометрический шаблон. Затем происходит сравнение этого шаблона с шаблонами лиц людей, которые вышли из кадра не более чем sti_outdate_time
секунд назад (sti_outdate_time
задается в параметрах конструктора VideoWorker
).
Совпадения объединяются в группу sti_person
. Идентификатор группы sti_person
(sti_person_id
) совпадает со значением track_id
первого элемента, сформировавшего группу sti_person
.
Когда определенная группа sti_person
превышает временной промежуток sti_outdate_time
, вызывается коллбэк VideoWorker.StiPersonOutdatedCallbackU
. Возвращаемые в коллбэке данные фиксируются в виде структуры StiPersonOutdatedCallbackData
(C++, Java, C#, Python).