Служебные блоки
Служебные блоки
Служебные блоки — это процессинг-блоки, реализующие вспомогательные функции. В настоящий момент доступна единственная модификация типа UTILITY_MODULE — face_cut.
face_cut
Для распознавания и других операций с задетектированными лицами требуется нормализация изображений лиц с последующей обрезкой. Под нормализацией в данном случае имеется в виду разворот лица на изображении во фронтальное положение.
В рамках пайплайна распознавания данная операция выполняется внутри модуля FACE_TEMPLATE_EXTRACTOR, но зачастую удобно использовать нормализованные изображения для сохранения задетектированных лиц.
Параметры конфигурации
При создании блока face_cut используются следующие параметры:
{
"unit_type": "UTILITY_MODULE",
"modification": "face_cut",
"version": 1,
"cut_type": {"FACE_CUT_BASE", "FACE_CUT_TOKEN_FRONTAL", "FACE_CUT_FULL_FRONTAL"}
}
В параметре cut_type задается тип применяемой нормализации:
- "FACE_CUT_BASE" — базовый (подходит для сэмплов всех типов). Является значением параметра
cut_typeпо умолчанию. - "FACE_CUT_FULL_FRONTAL" — полный фронтальный ТИП (тип изображения лица) по ГОСТ Р ИСО / МЭК 19794-5 (ISO/IEC 19794-5 Full Frontal) (только для фронтальных сэмплов). Используется для сохранения изображений лица в электронных биометрических документах.
- "FACE_CUT_TOKEN_FRONTAL" — условно фронтальный ТИП (тип изображения лица) по ГОСТ Р ИСО / МЭК 19794-5 (ISO/IEC 19794-5 Token Frontal) (только для фронтальных сэмплов).
Спецификация процессинг-блока
Входной контейнер Context должен содержать бинарное изображение и массив объектов, полученных после работы процессинг-блоков детекции лица и фиттера:
Нажмите, чтобы развернуть спецификацию входного контейнера Context
{
"image" : {
"format": "NDARRAY",
"blob": "data pointer",
"dtype": "uint8_t",
"shape": [height, width, channels]
},
"objects": [{
"id": {"type": "long", "minimum": 0},
"class": "face",
"confidence": {"double", "minimum": 0, "maximum": 1},
"bbox": [x1, y2, x2, y2]
"keypoints": {
"left_eye_brow_left": {"proj" : [x, y]},
"left_eye_brow_up": {"proj" : [x, y]},
"left_eye_brow_right": {"proj" : [x, y]},
"right_eye_brow_left": {"proj" : [x, y]},
"right_eye_brow_up": {"proj" : [x, y]},
"right_eye_brow_right": {"proj" : [x, y]},
"left_eye_left": {"proj" : [x, y]},
"left_eye": {"proj" : [x, y]},
"left_eye_right": {"proj" : [x, y]},
"right_eye_left": {"proj" : [x, y]},
"right_eye": {"proj" : [x, y]},
"right_eye_right": {"proj" : [x, y]},
"left_ear_bottom": {"proj" : [x, y]},
"nose_left": {"proj" : [x, y]},
"nose": {"proj" : [x, y]},
"nose_right": {"proj" : [x, y]},
"right_ear_bottom": {"proj" : [x, y]},
"mouth_left": {"proj" : [x, y]},
"mouth": {"proj" : [x, y]},
"mouth_right": {"proj" : [x, y]},
"chin": {"proj" : [x, y]},
"points": ["proj": [x, y]]
}
}]
}Пример работы процессинг-блоков детекции лица и фиттера можно найти на странице Пример детекции лиц и определения антопометрических точек лица.
После вызова процессинг-блока каждому объекту из массива
"objects"будут добавлены новые атрибуты:{
"cut_rect": [x1, y1, x2, y2, x3, y3, x4, y4], // координаты углов нормализованного кропа начиная с верхнего левого и далее апротив часовой стрелки
"face_crop": { // нормализованный кроп
"format": "NDARRAY",
"blob": "data pointer",
"dtype": "uint8_t",
"shape": [height, width, channels]
},
}
Пример работы
Для получения нормализованных кропов выполните следующие действия:
- Создайте Processing Block модификации
face_cut. - Передайте Context-контейнер, полученный после работы процессинг-блоков детекции лица и фиттера.
- Вызовете процессинг-блок
face_cut. - Получите результат работы процессинг-блока.
- C++
- Python
- Flutter
- C#
- Java
- Kotlin
- NodeJS
- Go
auto configCtx = service->createContext();
configCtx["unit_type"] = "UTILITY_MODULE";
configCtx["modification"] = "face_cut";
pbio::ProcessingBlock blockFaceCut = service->createProcessingBlock(configCtx);
//------------------
// создание процессинг-блоков FACE_DETECTOR, FACE_FITTER и Context-контейнера с бинарным изображением
//------------------
faceDetector(ioData);
faceFitter(ioData);
blockFaceCut(ioData);
configCtx = {"unit_type": "UTILITY_MODULE",
"modification": "face_cut"
}
blockFaceCut = service.create_processing_block(configCtx)
#------------------
# создание процессинг-блоков FACE_DETECTOR, FACE_FITTER и Context-контейнера с бинарным изображением
#------------------
faceDetector(ioData)
faceFitter(ioData)
blockFaceCut(ioData)
ProcessingBlock blockFaceCut = service.createProcessingBlock({"unit_type": "UTILITY_MODULE", "modification": "face_cut"});
//------------------
// создание процессинг-блоков FACE_DETECTOR, FACE_FITTER и Context-контейнера с бинарным изображением
//------------------
faceDetector.process(ioData);
faceFitter.process(ioData);
blockFaceCut.process(ioData);
Dictionary<object, object> configCtx = new();
configCtx["unit_type"] = "UTILITY_MODULE";
configCtx["modification"] = "face_cut";
ProcessingBlock blockFaceCut = service.CreateProcessingBlock(configCtx);
//------------------
// создание процессинг-блоков FACE_DETECTOR, FACE_FITTER и Context-контейнера с бинарным изображением
//------------------
faceDetector.Invoke(ioData);
faceFitter.Invoke(ioData);
blockFaceCut.Invoke(ioData);
Context configCtx = service.createContext();
configCtx.get("unit_type").setString("UTILITY_MODULE");
configCtx.get("modification").setString("face_cut");
ProcessingBlock blockFaceCut = service.createProcessingBlock(configCtx);
//------------------
// создание процессинг-блоков FACE_DETECTOR, FACE_FITTER и Context-контейнера с бинарным изображением
//------------------
faceDetector.process(ioData);
faceFitter.process(ioData);
blockFaceCut.process(ioData);
val configCtx = service.createContext()
configCtx["unit_type"].string = "UTILITY_MODULE"
configCtx["modification"].string = "face_cut"
val blockFaceCut = service.createProcessingBlock(configCtx)
//------------------
// создание процессинг-блоков FACE_DETECTOR, FACE_FITTER и Context-контейнера с бинарным изображением
//------------------
faceDetector.process(ioData)
faceFitter.process(ioData)
blockFaceCut.process(ioData)
let configCtx = new facerec.Context();
configCtx.get("unit_type").value = "UTILITY_MODULE";
configCtx.get("modification").value = "face_cut";
let blockFaceCut = new facerec.ProcessingBlock(configCtx);
//------------------
// создание процессинг-блоков FACE_DETECTOR, FACE_FITTER и Context-контейнера с бинарным изображением
//------------------
faceDetector.process(ioData);
faceFitter.process(ioData);
blockFaceCut.process(ioData);
config, err := facesdk.CreateContext()
context, err = config.GetOrInsertByKey("unit_type")
err = context.SetString("UTILITY_MODULE")
context, err = config.GetOrInsertByKey("modification")
err = context.SetString("face_cut")
defer config.Close()
blockFaceCut, err := service.CreateProcessingBlock(config)
defer blockFaceCut.Close()
//------------------
// создание процессинг-блоков FACE_DETECTOR, FACE_FITTER и Context-контейнера с бинарным изображением
//------------------
err = faceDetector.Process(ioData)
err = faceFitter.Process(ioData)
err = blockFaceCut.Process(ioData)