Блок проверки качества фото
В этом разделе вы узнаете, как интегрировать блок оценки качества фотографии лица в свой проект на C++ или Python.
Блок оценки качества фотографии лица (C++/Python)
Требования
- Операционная система Windows x86 64-bit или Linux x86 64-bit.
- Установлен пакет Face SDK windows_x86_64 или linux_x86_64 (см. Начало работы).
1. Создание Quality Assessment Estimator
1.1 Для создания Quality Assessment Estimator, выполните шаги 1-3, описанные в разделе Создание процессинг-блока и укажите следующие значения:
"QUALITY_ASSESSMENT_ESTIMATOR"
для ключа"unit_type"
;- Пустую строку
""
для ключа"model_path"
.
- C++
- Python
configCtx["unit_type"] = "QUALITY_ASSESSMENT_ESTIMATOR";
configCtx["model_path"] = "";
// опционально, значения по умолчанию указаны после знака "="
// пути указаны для примеров, расположенных в <sdk_dir>/bin
configCtx["sdk_path"] = "..";
configCtx["config_name"] = "quality_assessment.xml";
configCtx["facerec_conf_dir"] = sdk_path + "/conf/facerec/"
configCtx = {
"unit_type": "QUALITY_ASSESSMENT_ESTIMATOR",
"model_path": "",
# опционально, значения по умолчанию указаны после двоеточия
# пути указаны для примеров, расположенных в <sdk_dir>/bin
"sdk_path": "..",
"config_name": "quality_assessment.xml",
"facerec_conf_dir": sdk_path + "/conf/facerec/"
}
1.2 Создайте процессинг-блок Quality Assessment Estimator:
- C++
- Python
pbio::ProcessingBlock qualityAssessmentEstimator = service->createProcessingBlock(configCtx);
qualityAssessmentEstimator = service.create_processing_block(configCtx)
2. Проверка качества фотографии лица
2.1 Создайте Context-контейнер ioData
для данных ввода-вывода, используя метод createContext()
:
- C++
- Python
auto ioData = service->createContext();
ioData = {"objects": []}
2.2 Создайте Context-контейнер imgCtx
с RGB-изображением в бинарном формате, выполнив шаги (1-3, 4.b), описанные в разделе Создание контейнера Context c RGB-изображением:
- C++
- Python
// помещение изображения в контейнер
auto wholeImageCtx = imgCtx["image"];
pbio::context_utils::putImage(wholeImageCtx, input_rawimg);
// добавьте ключ `"objects"`
auto objectsCtx = imgCtx["objects"];
# копирование изображения в бинарный формат
input_rawimg = image.tobytes()
# помещение изображения в контейнер
imageCtx = {
"blob": input_rawimg,
"dtype": "uint8_t",
"format": "NDARRAY",
"shape": [dim for dim in img.shape]
}
2.3.1 Создайте объект Capturer
. Описание см. в разделе Класс Capturer:
- C++
- Python
const pbio::Capturer::Ptr capturer = service->createCapturer("common_capturer_refa_fda_a.xml");
capturer = service.create_capturer(Config("common_capturer_refa_fda_a.xml"))
2.3.2 Задетектируйте лица с помощью метода capture
:
- C++
- Python
std::vector<pbio::RawSample::Ptr> samples = capturer->capture(input_rawimg);
samples = capturer.capture(input_rawimg)
2.4 Создайте Context-контейнер capture_result
. Поместите в него бинарное изображение, используя ключ "image"
:
capture_result = service->createContext();
auto wholeImageCtx = capture_result["image"];
pbio::context_utils::putImage(wholeImageCtx, input_rawimg);
2.5.1 Для каждого задетектированного лица создайте Context-контейнер faceData
и передайте контейнер с изображением по ключу "image_ptr"
:
- C++
- Python
for(auto &sample: samples)
{
auto faceData = service->createContext();
faceData["image_ptr"] = capture_result["image"];
for sample in samples:
faceData = {"image_ptr": imageСtx}
2.5.2 Конвертируйте объект RawSample
в Context-контейнер faceData
:
- C++
- Python
pbio::context_utils::putRawSample(faceData, sample, "fda", input_rawimg.width, input_rawimg.height);
frame = sample.get_rectangle()
faceData["bbox"] = [
float(frame.x / img_shape[1]),
float(frame.y / img_shape[0]),
float((frame.x + bbx.width) / img_shape[1]),
float((frame.y + bbx.height) / img_shape[0]),
]
faceData["confidence"] = sample.get_score()
faceData["class"] = "face"
fitter_data = {}
fitter_data["keypoints"] = []
fitter_data["fitter_type"] = "fda" # "lbf29", "lbf68" или "esr"
points = sample.get_landmarks()
for pt in points:
fitter_data["keypoints"].append(pt.x)
fitter_data["keypoints"].append(pt.y)
fitter_data["keypoints"].append(pt.z)
fitter_data["left_eye"] = [sample.get_left_eye().x, sample.get_left_eye().y]
fitter_data["right_eye"] = [sample.get_right_eye().x, sample.get_right_eye().y]
faceData["fitter"] = fitter_data
faceData["angles"] = {}
faceData["angles"]["yaw"] = sample.get_angles().yaw
faceData["angles"]["pitch"] = sample.get_angles().pitch
faceData["angles"]["roll"] = sample.get_angles().roll
faceData["id"] = sample.get_id()
2.5.3 Вызовите qualityAssessmentEstimator()
и передайте Context-контейнер faceData
, содержащий изображение:
- C++
- Python
qualityAssessmentEstimator(faceData);
qualityAssessmentEstimator(faceData)
2.5.4 Переместите результаты работы блока в контейнер ioData
:
- C++
- Python
objectsCtx.push_back(std::move(faceData));
}
ioData = std::move(capture_result);
ioData["objects"].append(faceData)
Для точной оценки требуется только одно лицо человека в кадре, смотрящего в камеру, иначе общий балл будет низким, поскольку алгоритм учитывает относительный размер, положение и направленность головы. Если захвачено несколько лиц, каждое из них будет обработано независимо.
Результат вызова qualityAssessmentEstimator()
будет добавлен в контейнер ioData
. Формат выходных данных представляет собой список объектов, доступный по ключу "objects"
. Каждый объект списка имеет ключ "class"
со значением "face"
.
По ключам "quality": "qaa"
расположен контекст с полным набором оценок (результат работы метода qualityAssessmentEstimator()
).
- Ключ
"totalScore"
содержит общую оценку типа long в диапазоне [0,100]
/*
{
"quality": {
"qaa": {
"totalScore": {"type": "long", "minimum": 0, "maximum": 100},
"isSharp": {"type": "boolean"},
"sharpnessScore": {"type": "long", "minimum": 0, "maximum": 100},
"isEvenlyIlluminated": {"type": "boolean"},
"illuminationScore": {"type": "long", "minimum": 0, "maximum": 100},
"noFlare": {"type": "boolean"},
"isLeftEyeOpened": {"type": "boolean"},
"leftEyeOpennessScore": {"type": "long", "minimum": 0, "maximum": 100},
"isRightEyeOpened": {"type": "boolean"},
"rightEyeOpennessScore": {"type": "long", "minimum": 0, "maximum": 100},
"isRotationAcceptable": {"type": "boolean"},
"maxRotationDeviation": {"type": "long"},
"notMasked": {"type": "boolean"},
"notMaskedScore": {"type": "long", "minimum": 0, "maximum": 100},
"isNeutralEmotion": {"type": "boolean"},
"neutralEmotionScore": {"type": "long", "minimum": 0, "maximum": 100},
"isEyesDistanceAcceptable": {"type": "boolean"},
"eyesDistance": {"type": "long", "minimum": 0}
"isMarginsAcceptable": {"type": "boolean"},
"marginOuterDeviation": {"type": "long", "minimum": 0}
"marginInnerDeviation": {"type": "long", "minimum": 0}
"isNotNoisy": {"type": "boolean"},
"noiseScore": {"type": "long", "minimum": 0, "maximum": 100},
"watermarkScore": {"type": "long", "minimum": 0},
"hasWatermark": {"type": "boolean"},
"dynamicRangeScore": {"type": "long", "minimum": 0},
"isDynamicRangeAcceptable": {"type": "boolean"},
"isBackgroundUniform": {"type": "boolean"},
"backgroundUniformityScore": {"type": "long", "minimum": 0, "maximum": 100}
}
}
}
*/
Примеры использования Quality Assessment Estimator:
3. Ускорение на GPU
Блок оценки качества не поддерживает ускорение графического процессора, но задействованные модули, перечисленные в конфигурационном файле, могут иметь собственные возможности ускорения.