Обработка видеопотока
Интерфейсный объект VideoWorker
может быть использован для:
- детекции лиц на видеопотоках
- создания шаблонов лиц
- распознавания лиц
- определения пола, возраста и эмоций лиц
- оценки принадлежности лица реальному человеку
- сравнения лиц, найденных за установленный период, друг с другом
Объект VideoWorker
берет на себя всю необходимую синхронизацию и контроль потоков, вам необходимо только подавать кадры видеопотока и реализовать несколько коллбэков.
Пример использования объекта VideoWorker
см. в video_recognition_demo.
Узнайте, как детектировать и отслеживать лица на видеопотоке в нашем туториале Детекция и трекинг лиц на видеопотоке.
Узнайте, как распознавать лица на видеопотоке в нашем туториале Распознавание лиц на видеопотоке.
Детекция лиц
Примечание: Узнайте, как детектировать лица в масках, в нашем туториале.
Объект 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
– конфигурационный файл для используемого распознавателя (см. Идентификация лиц).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
– длина временного интервала для кратковременной идентификации в секундах.
Существует три конфигурационных файла, использующие алгоритм трекинга из common_video_capturer.xml
:
video_worker.xml
с набором точек esrvideo_worker_lbf.xml
с набором точек singlelbfvideo_worker_fda.xml
с набором точек fda
и три конфигурационных файла, использующие алгоритм трекинга из fda_tracker_capturer.xml
:
video_worker_fdatracker.xml
с набором точек fdavideo_worker_fdatracker_fake_detector.xml
с набором точек fdavideo_worker_fdatracker_blf_fda.xml
с набором точек fda
(см. Антропометрические точки, Класс Capturer)
В случае, если VideoWorker
используется только для детекции лиц, указываются параметры matching_thread=0
и processing_thread=0
, и потребляется обычная лицензия Face Detector. Для создания компонента Face Detector для одного потока необходимо указать параметр streams_count=1
.
Для подачи кадров видеопотока используйте метод VideoWorker.addVideoFrame
. Этот метод потокобезопасен, поэтому можно подавать кадры из разных потоков, созданных для каждого видеопотока, без дополнительной синхронизации. Метод возвращает целочисленный идентификатор кадра, который будет использоваться в коллбэках для обозначения этого кадра.
Детекция лиц осуществляется посредством использования двух коллбэков:
VideoWorker.TrackingCallbackU
возвращает результаты трекинга. Этот коллбэк вызывается каждый раз, когда кадр был обработан конвейером трекинга. Tracking-коллбэк будет вызван сframe_id
равнымX
не раньше, чемVideoWorker.addVideoFrame
вернет значениеX + N – 1
, гдеN
– значение, которое вернулVideoWorker.getTrackingConveyorSize
. Tracking-коллбэки с одинаковым идентификаторомstream_id
вызываются в порядке возрастанияframe_id
. Поэтому если был получен коллбэк сstream_id=2
иframe_id=102
сразу после коллбэка сstream_id=2
иframe_id=100
, значит, кадр сframe_id=101
был пропущен для видеопотока 2. Большинство сэмплов созданы с кадраframe_id
, но некоторые могут быть получены с предыдущих кадров. Используйте методRawSample.getFrameID
для того, чтобы определить, какому кадру сэмпл принадлежит на самом деле. Чтобы подписаться на этот коллбэк, используйте методVideoWorker.addTrackingCallbackU
, чтобы отписаться – методVideoWorker.removeTrackingCallback
, подавcallback_id
, который вы получили отVideoWorker.addTrackingCallbackU
.VideoWorker.TrackingLostCallbackU
возвращает лучший сэмпл и шаблон лица, когда трекинг потерян (например, когда человек вышел из кадра). Лучший сэмпл может быть пустым, если включен конфигурационный параметрweak_tracks_in_tracking_callback
. Гарантируется, что этот коллбэк будет последним для пары<stream_id, track_id>
(track_id
равенsample.getID()
для сэмпла в любом VideoWorker-коллбэке). Т.е. после него ни один Tracking-, MatchFound- или TrackingLost-коллбэк для видеопотокаstream_id
не может содержать сэмпла с этим же идентификаторомtrack_id
. Также гарантируется, что для каждой пары<stream_id, track_id>
, которая была упомянута в Tracking-коллбэке, существует ровно один TrackingLost-коллбэк, за исключением треков, удаленных в процессеVideoWorker.resetStream
– для них TrackingLost-коллбэк не будет вызван. Используйте возвращаемое значениеVideoWorker.resetStream
для освобождения памяти, выделенной для этих треков. Чтобы подписаться на этот коллбэк, используйте методVideoWorker.addTrackingLostCallbackU
. Чтобы отписаться от коллбэка, используйте методVideoWorker.removeTrackingLostCallback
, предоставивcallback_id
, который вы получили от методаVideoWorker.addTrackingLostCallbackU
.
Примечание: Исключения, возникшие в коллбэках, будут перехвачены и сгенерированы заново в методе VideoWorker.checkExceptions
, поэтому не забывайте регулярно вызывать метод VideoWorker.checkExceptions
для контроля ошибок.
Предупреждение: Не вызывайте методы, которые изменяют состояние VideoWorker
внутри коллбэков, во избежание взаимной блокировки. Т.е. безопасными для вызова в коллбэках являются только методы VideoWorker.getMethodName
и VideoWorker.getStreamsCount
.
Создание шаблонов
Если помимо детекции требуется создание шаблонов, указываются параметры matching_thread=0
и processing_thread>0
, и потребляется лицензия Video Engine Standard. Для создания компонента Video Engine Standard для одного потока необходимо указать параметры streams_count=1
, processing_threads_count=1
, matching_threads_count=0
.
Вы можете отключить / включить создание шаблонов для конкретного видеопотока с помощью методов VideoWorker.disableProcessingOnStream
и VideoWorker.enableProcessingOnStream
. При старте создание шаблонов включено для всех видеопотоков.
Коллбэк VideoWorker.TemplateCreatedCallbackU
возвращает результаты генерации шаблонов. Этот коллбэк вызывается каждый раз, когда внутри VideoWorker
создается шаблон. Гарантируется, что этот коллбэк будет вызван после как минимум одного Tracking-коллбэка и перед TrackingLost-коллбэком с теми же stream_id
и track_id
(track_id = sample->getID()
). Чтобы подписаться на этот коллбэк, используйте метод VideoWorker.addTemplateCreatedCallbackU
. Чтобы отписаться от коллбэка, используйте метод VideoWorker.removeTemplateCreatedCallback
, предоставив callback_id
, который вы получили от метода VideoWorker.addTemplateCreatedCallbackU
.
Распознавание лиц
В случае, если требуется детекция лиц, создание шаблонов и сравнение их с базой (распознавание), указываются параметры matching_thread>0
и processing_thread>0
, и потребляется лицензия Video Engine Extended. Для создания компонента Video Engine Extended для одного потока необходимо указать параметры streams_count=1
, processing_threads_count=1
, matching_threads_count=1
.
Для задания или изменения базы используйте метод VideoWorker.setDatabase
. Он может быть вызван в любое время.
Коллбэк VideoWorker.MatchFoundCallbackU
возвращает результат сравнения с базой. Когда для трекаемого лица создается шаблон, он сравнивается с каждым шаблоном из базы, и если расстояние до ближайшего элемента оказывается меньше порога distance_threshold
, указанного в этом элементе, то фиксируется совпадение. Этот коллбэк вызывается после N
последовательных совпадений с элементами, относящимися к одному и тому же человеку.
Также выставив значение тэга <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
(track_id = sample->getID()
). Чтобы подписаться на этот коллбэк, используйте метод VideoWorker.addMatchFoundCallbackU
. Чтобы отписаться от коллбэка, используйте метод VideoWorker.removeMatchFoundCallback
, предоставив callback_id
, который вы получили от метода VideoWorker.addMatchFoundCallbackU
. Максимальное количество элементов, возвращаемое в MatchFoundCallbackData.search_result
, устанавливается в конфигурационном файле под тэгом search_k
и может быть изменено с помощью объекта FacerecService.Config.overrideParameter
, например: video_worker_config.overrideParameter(search_k, 3);
Определение пола, возраста и эмоций
Для определения пола и возраста указывается параметр age_gender_estimation_threads_count > 0
. Для определения эмоций указывается параметр emotions_estimation_threads_count > 0
. Данные о поле, возрасте и эмоциях приходят в коллбэк VideoWorker.TrackingCallbackU
. Данные об эмоциях обновляются постоянно. Данные о поле и возрасте пересчитываются только в том случае, если найден сэмпл с лучшим качеством. Сразу после создания VideoWorker
определение пола, возраста и эмоций включено.
Отключить определение пола, возраста и эмоций на конкретном потоке можно при помощи методов:
VideoWorker.disableAgeGenderEstimationOnStream
(пол и возраст)VideoWorker.disableEmotionsEstimationOnStream
(эмоции)
Снова включить определение пола, возраста и эмоций на конкретном потоке можно при помощи методов:
VideoWorker.enableAgeGenderEstimationOnStream
(пол и возраст)VideoWorker.enableEmotionsEstimationOnStream
(эмоции)
Оценка принадлежности лица реальному человеку
Активная (сценарная) проверка
Для включения данной проверки необходимо выставить параметр enable_active_liveness
конфигурационного файла объекта VideoWorker в 1
. После этого все лица для идентификации будут проходить несколько проверок. Доступны следующие проверки (определены в структуре LivenessChecks
):
SMILE
: улыбкаBLINK
: морганиеTURN_UP
: поворот головы вверхTURN_DOWN
: поворот головы внизTURN_RIGHT
: поворот головы вправоTURN_LEFT
: поворот головы влевоPERSPECTIVE
: проверка изменения положения лица (необходимо приблизить лицо к камере)
Примечание: для использования проверки SMILE
необходимо указать количество потоков в параметре emotions_estimation_threads_count
объекта VideoWorker
.
Между проверками необходимо расположить лицо нейтральном положении (фронтально по направлению к камере). При этом порядок проверок может быть случайным (данный режим выбран по умолчанию), либо задан при инициализации (путем создания списка из неповторяющихся проверок). Пример задания списка проверок представлен в демонстрационной программе 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
: выполняется проверка
Кратковременная идентификация
Кратковременная идентификация (short time identification, STI) позволяет узнать трек как человека, проходившего перед камерой некоторое время назад, даже если этот человек отсутвует в базе и даже если распознавание отключено. Таким образом, один и тот человек, который в течение, например, одной минуты несколько раз выходил из кадра и снова заходил в кадр, будет идентифицироваться как одно и то же лицо.
Если кратковременная идентификация включена, VideoWorker
сравнивает треки, на которых лицо было потеряно, с другими треками, на которых лицо было потеряно не более, чем sti_outdate_time
секунд назад. Совпавшие треки объединяются в группу sti_person
. ID группы sti_person
(sti_person_id
) возвращается в коллбэке VideoWorker.TrackingLostCallbackU
. Значение sti_person_id
совпадает со значением track_id
первого элемента, сформировавшего группу sti_person
. Когда определенная группа sti_person
превышает временной промежуток sti_outdate_time
, вызывается коллбэк VideoWorker.StiPersonOutdatedCallbackU
.
Кратковременная идентификация не влияет на использование лицензии. Для использования этой функции требуется по крайней мере один поток для создания шаблонов (processing_thread>0
).