Детекция лиц
Обзор
Процесс детекции лиц в Face SDK состоит из нескольких этапов: детекции лиц, определения антропометрических точек и вычисления углов поворота головы.
Детекция лиц
Детекция лиц в Face SDK выполняется с помощью набора детекторов. Детектор – это алгоритм библиотеки libfacerec, который использует нейронные сети для обнаружения лиц на изображениях и в видеопотоках. Результатом работы детектора являются координаты ограничивающего прямоугольника (bbox) вокруг задетектированного лица.
После того как детектор обнаружил лицо, для оптимизации дальнейшей работы выполняется автоматическая обрезка изображения по вычисленным координатам ограничивающего прямоугольника (bbox). Определение антропометрических точек и вычисление углов поворота головы выполняются уже на обрезанном изображении (кропе лица).
Детекторы
На данный момент доступны следующие детекторы:
- LBF – устаревший детектор, не рекомендован к использованию.
- BLF – детектор, обеспечивающий более высокое качество и скорость детекции, чем LBF, для лиц среднего размера и больше (в том числе в масках). На Android доступно использование GPU ускорения (включено по умолчанию).
- REFA – детектор, более медленный в сравнении с детекторами LBF и BLF, но при этом демонстрирует высокое качество детекции лиц различных размеров (в том числе в масках). Рекомендован для использования в экспертных системах.
- ULD – детектор, более быстрый в сравнении с REFA. Позволяет детектировать лица различных размеров (в том числе в масках).
- SSYV – новый детектор.
Ниже представлены примеры работы детекторов в различных условиях. Настроить пороги детекции (score_threshold), минимальный размер детектируемого лица (min_size) и другие параметры можно в файлах конфигурации объекта Capturer в папке conf дистрибутива Face SDK (Подробнее в разделе Параметры файлов конфигурации объекта Capturer).
Нажмите, чтобы развернуть таблицу
BLF (score_threshold=0.6) | REFA (min_size=0.2, score_threshold=0.89) | ULD (min_size=10, score_threshold=0.7) |
Нажмите, чтобы развернуть таблицу
ULD (score_threshold=0.4) | ULD (score_threshold=0.7) | REFA (score_threshold=0.89) |
Детекторы могут быть ускорены за счет использования AVX2 (доступно только на Linux x86 64-bit). Для использования набора инструкций AVX2 переместите содержимое директории lib/tensorflow_avx2
в директорию lib
и определите параметр use_avx2
в конфигурационном файле. Доступные инструкции вы можете проверить, выполнив команду grep flags /proc/cpuinfo
.
Определение антропометрических точек
Для определения антропометрических точек (Face Landmarks) в Face SDK используются фиттеры. Фиттеры – это специальные алгоритмы библиотеки libfacerec, результатом работы которых является набор антрометрических точек с 2D/3D координатами, привязанными к задетектированному лицу. Существует несколько вариантов фиттеров, отличающихся набором антопометрических точек, о которых написано ниже.
Антропометрические точки
Примечание. Узнать, как отобразить антропометрические точки и углы поворота головы, можно в нашем туториале.
Существует четыре набора антропометрических точек: esr, singlelbf, doublelbf, fda, mesh.
- Набор esr – первый созданный и единственный набор, доступный в предыдущих версиях SDK. Набор esr содержит 47 точек.
- Наборы singlelbf и doublelbf обеспечивают большую точность чем esr. Набор singlelbf содержит 31 точку. Набор doublelbf содержит 101 точку. Фактически, этот набор представляет собой два сконкатенированных набора – последние 31 точки набора doublelbf дублируют набор singlelbf (в том же порядке).
- Набор fda обеспечивает более высокое качество в широком диапазоне ракурсов (вплоть до профильных), в отличие от предыдущих наборов, поэтому мы рекомендуем использовать детекторы именно с этим набором. При этом для распознавания по-прежнему требуется, чтобы ракурс лица был максимально приближен к фронтальному. Набор fda содержит 21 точку.
- Набор mesh на данный момент является самым новым, и содержит 470 3D точек лица. Мы рекомендуем использовать его для получения 3D маски лица.
Набор точек fda. RawSample.getLeftEye возвращает точку 7. RawSample.getRightEye возвращает точку 10 | Набор точек esr. RawSample.getLeftEye возвращает точку 16. RawSample.getRightEye возвращает точку 17 |
---|---|
Набор точек singlelbf. RawSample.getLeftEye возвращает точку 29. RawSample.getRightEye возвращает точку 30. | Первые 70 точек набора doubleldb (остальные 31 точки взяты из набора singlelbf). RawSample.getLeftEye возвращает точку 68. RawSample.getRightEye возвращает точку 69 |
---|---|
Набор точек mesh. RawSample.getLeftEye возвращает точку 468. | RawSample.getRightEye возвращает точку 469 |
---|---|
Расширенный набор точек глаз
Помимо стандартных антропометрических точек лица вы можете получить расширенный набор точек глаз (Iris Landmarks), который включает в себя точки зрачков и век. Возвращаемый вектор состоит из 40 точек для левого и правого глаза в порядке, указанном на изображении ниже. Для каждого глаза возвращается 20 точек: первые 5 точек относятся к зрачку (центр и точки на окружности), остальные 15 точек образуют контур век. Пример отрисовки доступен в демонстрационной программе demo (C++/Java/C#).
Вычисление углов поворота головы
Вычисление углов поворота головы (Pitch, Yaw, Roll) относительно оси наблюдения. Точность определения углов зависит от используемого набора антропометрических точек.
Трекинг лиц (опционально)
Трекингом называют задачу по отслеживанию или сопровождению лиц на видеопотоках. В этом случае помимо детекторов в процессе обработки кадров задействованы трекеры. Трекер представляет собой алгоритм библиотеки libfacerec, который позволяет отслеживать изменения положения лица от кадра к кадру. В результате формируется трек человека (последовательность кадров видеопотока, на которых изображен один и тот же человек). Каждому треку присваивается уникальный идентификатор (track_id), который не меняется с момента обнаружения лица в видеопотоке и до момента его потери.
Реализация детекции лиц
Создание объекта Capturer
Для детекции лиц используется класс Capturer
. При создании объекта класса используется файл конфигурации объекта Capturer, в котором задаются тип используемого детектора и тип используемого набора антропометрических точек (Подробнее в разделе Файлы конфигурации объекта Capturer). Также в файле конфигурации объекта Capturer можно настроить другие параметры, влияющие на качество и скорость работы всего алгоритма. Детектор и набор антропометрических точек указываются в названии файла конфигурации, например: common_capturer_blf_fda_front.xml
- детектор blf, набор точек fda.
Для трекинга используются файлы конфигурации двух типов:
- common_video_capturer – высокая скорость работы, но качество при этом ниже, чем у fda_tracker_capturer.
- fda_tracker_capturer – высокое качество, но скорость работы при этом ниже, чем у common_video_capturer.
Все доступные файлы конфигурации хранятся в папке conf дистрибутива Face SDK.
Пример 1
Создайте объект Capturer
с помощью метода FacerecService.createCapturer
, передав в качестве аргумента имя файла конфигурации объекта Capturer.
- C++
- C#
- Java
- Python
pbio::Capturer::Ptr capturer = service->createCapturer("common_capturer4.xml");
Capturer capturer = service.createCapturer("common_capturer4_lbf.xml");
final Capturer capturer = service.createCapturer(service.new Config("common_capturer4_lbf.xml"));
capturer = service.create_capturer(Config("common_capturer4_lbf.xml"))
Пример 2
Если при создании Capturer
вам потребуется переопределить значения числовых параметров из файла конфигурации, выполните следующие шаги:
- Создайте объект
FacerecService.Config
, в качестве аргумента передайте имя файла конфигурации. - С помощью метода
Config.overrideParameter
переопределите значения числовых параметров. - Создайте объект
Capturer
с помощью методаFacerecService.createCapturer
, передав объектFacerecService.Config
в качестве аргумента.
- C++
- C#
- Java
- Python
pbio::FacerecService::Config capturer_config("common_capturer4.xml");
capturer_config.overrideParameter("min_size", 200);
pbio::Capturer::Ptr capturer = service->createCapturer(capturer_config);
FacerecService.Config capturerConfig = new FacerecService.Config("common_capturer4_lbf.xml");
capturerConfig.overrideParameter("min_size", 200);
Capturer capturer = service.createCapturer(capturerConfig);
FacerecService.Config capturerConfig = service.new Config("common_capturer4_lbf.xml");
capturerConfig.overrideParameter("min_size", 200);
final Capturer capturer = service.createCapturer(capturerConfig);
capturer_config = Config("common_capturer4_lbf.xml")
capturer_config.override_parameter("min_size", 200)
capturer = service.createCapturer(capturer_config)
Пример 3
Значения некоторых параметров можно изменить в уже созданном объекте Capturer
с помощью метода Capturer.setParameter
.
- C++
- C#
- Java
- Python
pbio::Capturer::Ptr capturer = service->createCapturer("common_capturer4.xml");
capturer->setParameter("min_size", 200);
capturer->setParameter("max_size", 800);
// capturer->capture(...);
// ...
capturer->setParameter("min_size", 100);
capturer->setParameter("max_size", 400);
// capturer->capture(...);
Capturer capturer = service.createCapturer("common_capturer4_lbf.xml");
capturer.setParameter("min_size", 200);
capturer.setParameter("max_size", 800);
// capturer.capturer(...);
// ...
capturer.setParameter("min_size", 100);
capturer.setParameter("max_size", 400);
// capturer.capture(...);
Capturer capturer = service.createCapturer(service.new Config("common_capturer4_lbf.xml"));
capturer.setParameter("min_size", 200);
capturer.setParameter("max_size", 800);
// capturer.capturer(...);
// ...
capturer.setParameter("min_size", 100);
capturer.setParameter("max_size", 400);
// capturer.capture(...);
capturer = service.create_capturer(Config("common_capturer4_lbf.xml"))
capturer.set_parameter("min_size", 200)
capturer.set_parameter("max_size", 800)
# capturer.capturer(...);
# ...
capturer.set_parameter("min_size", 100)
capturer.set_parameter("max_size", 400)
# capturer.capture(...);
Параметры файлов конфигурации объекта Capturer
Нажмите, чтобы отобразить список параметров из файлов конфигурации объекта Capturer, которые могут быть изменены с помощью объекта FacerecService.Config.overrideParameter
coarse_score_threshold
– грубый порог уверенности детекции. Во время детекции детектор создает набор bbox'ов, для каждого из которых указано значениеscore
(число от 0 до 1, показывает степень уверенности в том, что в bbox находится лицо). Bbox'ы со score'ми подаются в nms-алгоритм, который определяет пересечения (совпадения) между bbox'ми. Параметрcoarse_score_threshold
позволяет отсечь bbox'ы с низкимscore
, что сокращает количество вычислений, выполняемых nms-алгоритмом.score_threshold
– порог уверенности детекции (confidence).max_processed_width
иmax_processed_height
– (только для трекинга) ограничение размера изображения, подаваемого в детектор.min_size
иmax_size
– минимальный и максимальный размер лица для детекции (для трекинга: размер определен для изображения, уже уменьшенного под ограниченияmax_processed_width
иmax_processed_height
).min_neighbors
– целочисленный параметр детектора, который позволяет отбрасывать ложные детекции. Вы можете изменить этот параметр, исходя из ситуации: например, можно увеличить значение, если наблюдается большое число ложных детекций, и уменьшить значение, если большое число лиц не детектируется. Рекомендуем не менять значение этого параметра без необходимости.use_advanced_multithreading
– улучшает производительность при параллельной работе нескольких объектов Capturer.nms_iou_threshold
– аналог параметраmin_neighbors
, используется в большинстве текущих детекторов.min_detection_period
– (только для трекинга) вещественное число, означающее минимальное время (в секундах) между двумя запусками детектора. Используется для уменьшения нагрузки на процессор. Нулевое значение параметра отключает ограничение. Выставленные высокие значения увеличивают задержку обнаружения новых лиц.max_detection_period
– (только для трекинга) целое число, означающее максимальное время (в кадрах) между двумя запусками детектора. Нулевое значение параметра отключает ограничение. Например, если вы обрабатываете видео офлайн, можно выставить значение1
, чтобы не пропустить ни одного лица.max_occlusion_time_wait
– (только для трекинга) вещественное число (в секундах). Когда трекер обнаруживает перекрытие лица, он удерживает позицию лица и пытается отследить его на новых кадрах в течение этого времени.fda_max_bad_count_wait
– целое число. При обнаружении снижения качества изображения лица, система пытается отследить это лицо с помощью трекера общего назначения (вместо алгоритма fda, разработанного для лиц) в течение не болееfda_max_bad_count_wait
кадров.base_angle
– целое число:0
,1
,2
или3
. Ориентация камеры:0
– стандартная,1
означает 90 градусов,2
означает -90 градусов,3
означает 180 градусов. При изменении ориентации камеры установите новое значение ориентации для этого параметра, иначе качество детекции снизится.fake_detections_cnt
– целое число. Количество стартовых позиций для поиска лиц при конфигурацииvideo_worker_fdatracker_fake_detector.xml
. Стартовая позиция - это заданное положение лица на изображении. Мы можем задать параметры стартовой позиции, если мы уверены в наличии лица на заданной области изображения. Изображение с размеченной стартовой позицией поступает в fake detector, функция которого - передача изображения сразу в фиттер. Подразумевается, что на изображении уже присутствует лицо, а значит можно сразу перейти к определению антропометрических точек.fake_detections_period
– целое число. Каждая стартовая позиция будет использоваться один раз вfake_detections_period
кадров.fake_rect_center_xN
,fake_rect_center_yN
,fake_rect_angleN
,fake_rect_sizeN
– вещественные числа, которые обозначают параметры стартовых позиций. Стартовая позиция - N от0
доfake_detections_cnt – 1
включительно.fake_rect_center_xN
– x координата центра относительно ширины изображения.fake_rect_center_yN
– y координата центра относительно высоты изображения.fake_rect_angleN
– угол roll в градусах.fake_rect_sizeN
– размер относительно max(ширина изображения, высота изображения).downscale_rawsamples_to_preferred_size
– целое число,1
– включен,0
– выключен. По умолчанию этот флаг включен. Когда флаг включен,Capturer
уменьшает все образцы до предпочтительного размера (RawSample.downscaleToPreferredSize
) в целях уменьшения потребления памяти. Однако это приводит к снижению производительности. Рекомендуется отключатьdownscale_rawsamples_to_preferred_size
и использоватьRawSample.downscaleToPreferredSize
вручную для образцов, которые вам нужно сохранить или в течение длительного времени удерживать в оперативной памяти.iris_enabled
– получение расширенного набора точек глаз.1
– параметр включен (передается вектор с расширенным набором точек глаз),0
– параметр выключен (передается пустой вектор).
Запуск детекции
Подать изображение на вход детектору можно двумя способами:
- Подать данные закодированного изображения в формате JPEG, PNG, TIF или BMP в метод
Capturer.capture
. - Подать данные раскодированного изображения в метод
Capturer.capture
, используя классRawImage
.
Результат выполнения детекции лица сохраняется в интерфейсном объекте RawSample
.
- C++
- C#
- Java
- Python
// чтение изображения
cv::Mat image;
image = cv::imread(image_path, cv::IMREAD_COLOR);
// создание объекта RawImage
cv::Mat input_image;
cv::cvtColor(image, input_image, cv::COLOR_BGR2RGB);
pbio::RawImage input_rawimg(input_image.cols, input_image.rows, pbio::RawImage::Format::FORMAT_RGB, input_image.data);
// выполнение детекции
std::vector<pbio::RawSample::Ptr> samples = capturer->capture(input_rawimg);
// чтение изображения
OpenCvSharp.Mat image = OpenCvSharp.Cv2.ImRead(image_path);
// создание объекта RawImage
byte[] byte_image = new byte[image.Total() * image.Type().Channels];
Marshal.Copy(image.DataStart, byte_image, 0, (int)byte_image.Length);
RawImage input_rawimg = new RawImage(frame.Width, frame.Height, RawImage.Format.FORMAT_BGR, byte_image);
// выполнение детекции
List<RawSample> samples = capturer.capture(input_rawimg);
// чтение изображения
byte[] byte_image;
byte_image = readImage(image_path);
// создание объекта RawImage
RawImage input_rawimg = new RawImage(width, height, RawImage.Format.FORMAT_YUV_NV21, byte_image);
// выполнение детекции
Vector<RawSample> samples = capturer.capture(rawImage);
# чтение изображения
image = cv2.imread(image_path)
# создание объекта RawImage
input_rawimg = RawImage(image.shape[1], image.shape[0], Format.FORMAT_BGR, image.tobytes())
# выполнение детекции
samples = capturer.capture(input_rawimg)
Для трекинга вы также можете вызвать метод Capturer.resetHistory
, чтобы удалить из истории все кадры и лица, и начать отслеживание на новой видеопоследовательности.
Результат детекции
RawSample – это интерфейсный объект, в котором хранится результат детекции. С помощью методов RawSample можно выполнить следующие операции:
- Получить ID, назначенный сэмплу лица при детекции (
RawSample.getID
) (только для детекции, совмещенной с трекингом). - Получить степень уверенности детекции (confidence) (для детекторов BLF, REFA и ULD). Для этого необходимо вызвать метод
RawSample.getScore()
, в результате вернется число с плавающей точкой в диапазоне [0, 1]. - Получить ограничивающий прямоугольник лица (
RawSample.getRectangle
), углы поворота головы (RawSample.getAngles
), координаты левого / правого глаза (RawSample.getLeftEye
/RawSample.getRightEye
), антропометрические точки лица (RawSample.getLandmarks
), если лицо расположено фронтально. - Получить расширенный набор точек глаз, который включает в себя точки зрачков и век (
RawSample.getIrisLandmarks()
). - Уменьшить внутреннее изображение лица до предпочтительного размера (
RawSample.downscaleToPreferredSize
). - Сериализовать объект в бинарном формате (
RawSample.save
илиRawSample.saveWithoutImage
), после чего вы можете десериализовать объект методомFacerecService.loadRawSample
илиFacerecService.loadRawSampleWithoutImage
. - Выполнить нормализацию изображения лица с последующей обрезкой (
RawSample.cutFaceImage
илиRawSample.cutFaceRawImage
) (test_facecut).
Объект RawSample можно передать в методы оценки возраста, пола, качества и принадлежности лица реальному человеку (см. Оценка лиц, test_facecut, test_videocap), а также в Recognizer.processing
для создания шаблона (См. Распознавание лиц, test_identify).
Нормализация изображений лиц
Для распознавания и других операций с задетектированными лицами требуется нормализация изображений лиц с последующей обрезкой. Под нормализацией в данном случае имеется в виду разворот лица на изображении во фронтальное положение. Нормализовать лицо можно одним из следующих методов RawSample:
RawSample.cutFaceImage
: нормализованное изображение лица сохраняется в указанный поток (например, в файл), формат кодирования выбирается черезRawSample.ImageFormat
.RawSample.cutFaceRawImage
: нормализованное изображение лица возвращается в форматеRawImage
(в нем хранятся незакодированные пиксели изображения в формате RGB/BGR/GRAY (формат выбирается черезRawImage.Format
).
Примеры использования RawSample.cutFaceRawImage
:
- C++
- C#
- Java
- Python
auto raw_image_crop = sample->cutFaceRawImage(
pbio::RawImage::Format::FORMAT_BGR,
pbio::RawSample::FACE_CUT_FULL_FRONTAL);
cv::Mat img_crop(raw_image_crop.height, raw_image_crop.width, CV_8UC3, (void*) raw_image_crop.data);
RawImage raw_image_crop = sample.cutFaceRawImage(RawImage.Format.FORMAT_BGR, RawSample.FaceCutType.FACE_CUT_FULL_FRONTAL);
OpenCvSharp.Mat img_crop = new OpenCvSharp.Mat(raw_image_crop.height, raw_image_crop.width, OpenCvSharp.MatType.CV_8UC3, raw_image_crop.data);
RawImage raw_image_crop = sample.cutFaceRawImage(RawImage.Format.FORMAT_RGB, faceCutType);
int[] pixels = raw_image_crop.getPixels(RawImage.PixelFormat.BITMAP_ARGB_8888);
Bitmap img_crop = Bitmap.createBitmap(pixels, raw_image_crop.width, raw_image_crop.height, Bitmap.Config.ARGB_8888);
raw_image_crop = sample.cut_face_raw_image(Format.FORMAT_GRAY)
img_crop = np.frombuffer(raw_image_crop.data, dtype=np.uint8).reshape([raw_image_crop.height, raw_image_crop.width])
Доступные типы нормализации (RawSample.FaceCutType
):
FACE_CUT_BASE
- базовый (подходит для сэмплов всех типов).FACE_CUT_FULL_FRONTAL
- полный фронтальный ТИП (тип изображения лица) по ГОСТ Р ИСО / МЭК 19794-5 (ISO/IEC 19794-5 Full Frontal) (только для фронтальных сэмплов). Используется для сохранения изображений лица в электронных биометрических документах.FACE_CUT_TOKEN_FRONTAL
- условно фронтальный ТИП (тип изображения лица) по ГОСТ Р ИСО / МЭК 19794-5 (ISO/IEC 19794-5 Token Frontal) (только для фронтальных сэмплов).
Для предварительного просмотра нормализованного изображения лица вызовите метод RawSample.getFaceCutRectangle
, указав тип нормализации. В результате вы получите четыре точки – углы прямоугольника, которые будут использованы для обрезки.
Примеры детекции лиц и нормализации изображений на разных языках программирования доступны в разделе Сэмплы.
Файлы конфигурации для конкретных бизнес-задач
Для решения различных бизнес-задач предусмотрено использование специально настроенных под них файлов конфигурации. Тип задачи и уровень качества работы указываются в названии файла, например: access_control_system_several_faces_q1.xml
На данный момент существуют готовые конфигурации для следующих бизнес-задач:
СКУД, некооперативное распознавание (несколько лиц в кадре):
- access_control_system_several_faces_q1.xml
- access_control_system_several_faces_q2.xml
СКУД, кооперативное распознавание (одно лицо в кадре):
- access_control_system_one_face_q1.xml
- access_control_system_one_face_q2.xml
- access_control_system_one_face_q3.xml
Безопасный город (видеонаблюдение):
- safety_city_q1.xml
- safety_city_q2.xml
Удаленная идентификация в телефоне / на десктопе:
- remote_identification_q1.xml
- remote_identification_q2.xml