Processing Block
Требования
- Добавленные ссылки на библиотеку
FacerecCSharpWrapper.dll
и OpenCvSharp4
Создание процессинг-блоков
Для детекции лиц и выполнения оценки качества изображении используется объект ProcessingBlock
(Тип блока
Модификация).
Порядок действий при использовании объекта ProcessingBlock
:
Создать объект
ProcessingBlock
ProcessingBlock processingBlock = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "<Тип блока>" },
{ "modification", "<Модификация>" },
{ "version", <Версия> }
}
);Прочитать изображение из файла:
byte[] imageData = File.ReadAllBytes(imagePath);
Создать
Context
Context data = service.CreateContextFromImage(imageData);
Вызвать метод
Invoke
уProcessingBlock
processingBlock.Invoke(data);
Выходные данные находятся в
data["objects"]
Пример использования данныхПолучение координат левой верхней и правой нижней точек bbox.
for (int i = 0; i < (int)objects.Length(); i++)
{
Context obj = objects[i];
Context bbox = obj["bbox"];
// Левая верхняя точка bbox
double x1 = bbox[0].GetDouble() * <ширина изображения>;
double y1 = bbox[1].GetDouble() * <высота изображения>;
// Правая нижняя точка bbox
double x2 = bbox[2].GetDouble() * <ширина изображения>;
double y2 = bbox[3].GetDouble() * <высота изображения>;
}
1. Создание объекта ProcessingBlock FaceDetector
FaceDetector
используется для детекции лиц на изображении.
ProcessingBlock faceDetector = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_DETECTOR" },
{ "modification", "uld" },
{ "precision_level", 3 }
}
);
2. Создание объекта ProcessingBlock FaceFitter
FaceFitter
используется для нахождения ключевых точек лиц на изображении.
Для работы некоторых ProcessingBlock'ов
необходимо использовать связку FaceDetector + FaceFitter.
ProcessingBlock fitter = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_FITTER" },
{ "modification", "tddfa" }
}
);
3. Верификация (1:1)
FaceTemplateExtractor
используется для извлечения шаблона лица.
VerificationModule
используется для верификации лиц (1:1).
static Context ExtractTemplates(string imagePath, FacerecService service, List<ProcessingBlock> pipeline)
{
byte[] imageData = File.ReadAllBytes(imagePath);
Context data = service.CreateContextFromImage(imageData);
foreach (ProcessingBlock processingBlock in pipeline)
{
processingBlock.Invoke(data);
}
return data;
}
static void Main(string[] args)
{
FacerecService service = FacerecService.createService
(
"<Путь до /conf/facerec>",
"<Путь до /license>"
);
string firstImagePath = "<Путь до первого изображения>";
string secondImagePath = "<Путь до второго изображения>";
ProcessingBlock faceDetector = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_DETECTOR" },
{ "modification", "uld" },
{ "precision_level", 3 }
}
);
ProcessingBlock faceFitter = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_FITTER" },
{ "modification", "tddfa" }
}
);
ProcessingBlock faceTemplateExtractor = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_TEMPLATE_EXTRACTOR" },
{ "modification", "1000" }
}
);
ProcessingBlock verificationModule = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "VERIFICATION_MODULE" },
{ "modification", "1000" }
}
);
List<ProcessingBlock> pipeline = [
faceDetector,
faceFitter,
faceTemplateExtractor
];
Context first = ExtractTemplates(firstImagePath, service, pipeline);
Context second = ExtractTemplates(secondImagePath, service, pipeline);
Context verificationData = service.CreateContext
(
new Dictionary<object, object>
{
{ "template1", first["objects"][0]["template"] },
{ "template2", second["objects"][0]["template"] }
}
);
verificationModule.Invoke(verificationData);
double distance = verificationData["result"]["distance"].GetDouble();
double score = verificationData["result"]["score"].GetDouble();
double far = verificationData["result"]["far"].GetDouble();
double frr = verificationData["result"]["frr"].GetDouble();
Console.WriteLine($"Verification result\ndistance: {distance}\nscore: {score}\nfar: {far}\nfrr: {frr}");
}
4. Идентификация (1:N)
FaceTemplateExtractor
используется для извлечения шаблона лица.
TemplateIndex
используется для поиска по шаблонам.
MatcherModule
используется для идентификации лиц (1:N)
static Context ExtractTemplates(string imagePath, FacerecService service, List<ProcessingBlock> pipeline)
{
byte[] imageData = File.ReadAllBytes(imagePath);
Context data = service.CreateContextFromImage(imageData);
foreach (ProcessingBlock processingBlock in pipeline)
{
processingBlock.Invoke(data);
}
return data;
}
static void Main(string[] args)
{
FacerecService service = FacerecService.createService
(
"<Путь до /conf/facerec>",
"<Путь до /license>"
);
string firstImagePath = "<Путь до первого изображения>";
string secondImagePath = "<Путь до второго изображения>";
ProcessingBlock faceDetector = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_DETECTOR" },
{ "modification", "uld" },
{ "precision_level", 3 }
}
);
ProcessingBlock faceFitter = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_FITTER" },
{ "modification", "tddfa" }
}
);
ProcessingBlock faceTemplateExtractor = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_TEMPLATE_EXTRACTOR" },
{ "modification", "1000" }
}
);
ProcessingBlock templateIndex = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "TEMPLATE_INDEX" },
{ "modification", "1000" }
}
);
ProcessingBlock matcherModule = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "MATCHER_MODULE" },
{ "modification", "1000" }
}
);
Context templates = service.CreateContext(new());
List<ProcessingBlock> pipeline = [
faceDetector,
faceFitter,
faceTemplateExtractor
];
Context first = ExtractTemplates(firstImagePath, service, pipeline);
Context second = ExtractTemplates(secondImagePath, service, pipeline);
for (int i = 0; i < (int)second["objects"].Length(); i++)
{
templates.PushBack(second["objects"][i]["template"]);
}
second["templates"] = templates;
templateIndex.Invoke(second);
Context matcherData = service.CreateContext
(
new Dictionary<object, object>
{
{ "knn", 1 },
{ "template_index", second["template_index"] },
{ "queries", new List<object> { first["objects"][0] } }
}
);
matcherModule.Invoke(matcherData);
long findIndex = matcherData["results"][0]["index"].GetLong();
double distance = matcherData["results"][0]["distance"].GetDouble();
double score = matcherData["results"][0]["score"].GetDouble();
Console.WriteLine($"Identify result\ndistance: {distance}\nscore: {score}\nindex: {findIndex}");
}