DynamicTemplateIndex
DynamicTemplateIndex используется для создания базы биометрических шаблонов.
Поддерживаемые операции:
- Добавление и удаление шаблонов по UUID
- Поиск по базе 1:N
Для выполнения поиска 1:N используется MATCHER_MODULE.
Пример использования DynamicTemplateIndex для поиска по базе:
Спецификация конфигурационного Context
async
- Создание асинхронной версии DynamicTemplateIndexmax_license_count
- Максимальное число лицензийcapacity
- Зарезервированное количество шаблоновmodel_version
- Название метода и версия в форматеназвание_версия
{
"async": "<bool>",
"max_license_count": "<long>",
"capacity": "<long>",
"model_version": "<string>"
}
примечание
Режим async в DynamicTemplateIndex находится в бета режиме
Использование DynamicTemplateIndex
- Создать FacerecService
- Создать DynamicTemplateIndex(используя загруженные/созданные шаблоны или указав предварительное количество шаблонов и модификацию_версию FACE_TEMPLATE_EXTRACTOR)
- Добавить шаблоны (загрузить или создать с помощью FACE_TEMPLATE_EXTRACTOR)
- Запустить поиск по DynamicTemplateIndex с помощью MATCHER_MODULE
- C++
- Python
- Flutter
- C#
- Java
- Kotlin
// 1
pbio::FacerecService::Ptr service = pbio::FacerecService::createService("<dll_path>", "<conf_path>", "<license_path>");
// 2
pbio::Context indexConfig = service->createContext();
indexConfig["capacity"] = 1000;
indexConfig["model_version"] = "1000_1";
indexConfig["async"] = false;
indexConfig["max_license_count"] = 1000;
pbio::DynamicTemplateIndex::Ptr index = service->createDynamicTemplateIndex(indexConfig);
// 3
std::vector<std::string> imagePaths =
{
"<path_to_image>"
};
std::vector<pbio::ProcessingBlock> pipeline;
pbio::Context detectorConfig = service->createContext();
pbio::Context fitterConfig = service->createContext();
pbio::Context faceTemplateExtractorConfig = service->createContext();
pbio::Context matcherModuleConfig = service->createContext();
pipeline.reserve(3);
detectorConfig["unit_type"] = "FACE_DETECTOR";
fitterConfig["unit_type"] = "FACE_FITTER";
faceTemplateExtractorConfig["unit_type"] = "FACE_TEMPLATE_EXTRACTOR";
faceTemplateExtractorConfig["modification"] = "1000";
matcherModuleConfig["unit_type"] = "MATCHER_MODULE";
matcherModuleConfig["modification"] = "1000";
pipeline.push_back(service->createProcessingBlock(detectorConfig));
pipeline.push_back(service->createProcessingBlock(fitterConfig));
pipeline.push_back(service->createProcessingBlock(faceTemplateExtractorConfig));
pbio::ProcessingBlock matcherModule = service->createProcessingBlock(matcherModuleConfig);
std::unordered_map<std::string, pbio::ContextTemplate::Ptr> uuidToTemplate;
for (const std::string& imagePath : imagePaths)
{
std::string imageData;
{
std::ifstream image(imagePath, std::ios::binary);
std::ostringstream stream;
if (!image.is_open())
{
throw std::runtime_error("Can't open file: " + imagePath);
}
stream << image.rdbuf();
imageData = stream.str();
}
pbio::Context data = service->createContextFromEncodedImage(imageData);
for (pbio::ProcessingBlock& block : pipeline)
{
block(data);
}
for (const pbio::Context& object : data["objects"])
{
pbio::ContextTemplate::Ptr contextTemplate = object["face_template"]["template"].getContextTemplate();
std::string uuid = object["face_template"]["uuid"].getString();
index->add(contextTemplate, uuid);
uuidToTemplate.emplace(std::move(uuid), contextTemplate);
}
}
// 4
pbio::Context matcherData = service->createContext();
matcherData["template_index"] = index;
for (const auto& value : uuidToTemplate)
{
matcherData["queries"] = value.second;
matcherModule(matcherData);
std::cout << (matcherData["results"][0]["uuid"].getString() == value.first) << std::endl;
}
# 1
service: FacerecService = FacerecService.create_service("<dll_path>", "<conf_path>", "<license_path>")
# 2
index_config: Context = service.create_context({
"capacity": 1000,
"model_version": "1000_1",
"async": False,
"max_license_count": 1000
})
index: DynamicTemplateIndex = service.create_dynamic_template_index(index_config)
# 3
image_paths: List[str] = [
"<image_path>"
]
pipeline: List[ProcessingBlock] = [
service.create_processing_block({"unit_type": "FACE_DETECTOR"}),
service.create_processing_block({"unit_type": "FACE_FITTER"}),
service.create_processing_block({"unit_type": "FACE_TEMPLATE_EXTRACTOR", "modification": "1000"})
]
matcher_module: ProcessingBlock = service.create_processing_block({
"unit_type": "MATCHER_MODULE", "modification": "1000"
})
uuid_to_template: Dict[str, ContextTemplate] = {}
for image_path in image_paths:
with open(image_path, "rb") as image:
data: Context = service.create_context_from_encoded_image(image.read())
for block in pipeline:
block(data)
for obj in data["objects"]:
context_template: ContextTemplate = obj["face_template"]["template"].get_value()
uuid: str = obj["face_template"]["uuid"].get_value()
index.add(context_template, uuid)
uuid_to_template[uuid] = context_template
# 4
matcher_data: Context = service.create_context({"template_index": index})
for uuid, template in uuid_to_template.items():
matcher_data["queries"] = template
matcher_module(matcher_data)
print(matcher_data["results"][0]["uuid"].get_value() == uuid)
Для запуска примера нужны модели:
- ssyv_light
- fda
- face_template_extractor/30
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// 1
FacerecService service = await FacerecService.createService();
// 2
Context indexConfig = service.createContext({
"capacity": 1000,
"model_version": "1000_1",
"async": false,
"max_license_count": 1000
});
DynamicTemplateIndex index = service.createDynamicTemplateIndex(indexConfig);
// 3
List<String> imagePaths = ["<image_path>"];
List<ProcessingBlock> pipeline = [
service.createProcessingBlock({"unit_type": "FACE_DETECTOR", "modification": "ssyv_light"}),
service.createProcessingBlock({"unit_type": "FACE_FITTER", "modification": "fda"}),
service.createProcessingBlock({"unit_type": "FACE_TEMPLATE_EXTRACTOR", "modification": "30"})
];
ProcessingBlock matcherModule = service.createProcessingBlock({"unit_type": "MATCHER_MODULE", "modification": "30"});
Map<String, ContextTemplate> uuidToTemplate = {};
for (String imagePath in imagePaths) {
Context data = service.createContextFromEncodedImage(File(imagePath).readAsBytesSync());
for (ProcessingBlock block in pipeline) {
block.process(data);
}
for (int i = 0; i < data["objects"].len(); i++) {
Context object = data["objects"][i];
ContextTemplate contextTemplate = object["face_template"]["template"].get_value();
String uuid = object["face_template"]["uuid"].get_value();
index.addContextTemplate(contextTemplate, uuid);
uuidToTemplate[uuid] = contextTemplate;
}
}
// 4
Context matcherData = service.createContext({"template_index": index});
uuidToTemplate.forEach((uuid, contextTemplate) {
matcherData["queries"] = contextTemplate;
matcherModule.process(matcherData);
print(matcherData["results"][0]["uuid"].get_value() == uuid);
});
}
// 1
FacerecService service = FacerecService.createService
(
"<conf_path>",
"<license_path>"
);
// 2
Context indexConfig = service.CreateContext
(
new()
{
{ "capacity", 1000 },
{ "model_version", "1000_1" },
{ "async", false },
{ "max_license_count", 1000 }
}
);
DynamicTemplateIndex index = service.createDynamicTemplateIndex(indexConfig);
// 3
List<string> imagePaths =
[
"<image_path>"
];
List<ProcessingBlock> pipeline =
[
service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_DETECTOR" }
}
),
service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_FITTER" }
}
),
service.CreateProcessingBlock
(
new()
{
{ "unit_type", "FACE_TEMPLATE_EXTRACTOR" },
{ "modification", "1000" }
}
)
];
ProcessingBlock matcherModule = service.CreateProcessingBlock
(
new()
{
{ "unit_type", "MATCHER_MODULE" },
{ "modification", "1000" }
}
);
Dictionary<String, ContextTemplate> indexToTemplate = new();
foreach (string imagePath in imagePaths)
{
Context data = service.CreateContextFromEncodedImage(File.ReadAllBytes(imagePath));
foreach (ProcessingBlock processingBlock in pipeline)
{
processingBlock.Invoke(data);
}
for (int i = 0; i < (int)data["objects"].Length(); i++)
{
Context obj = data["objects"][i];
ContextTemplate contextTemplate = obj["face_template"]["template"].GetContextTemplate();
string uuid = obj["face_template"]["uuid"].GetString();
index.Add(contextTemplate, uuid);
indexToTemplate[uuid] = contextTemplate;
}
}
// 4
Context matcherData = service.CreateContext
(
new()
{
{ "template_index", index }
}
);
foreach (var (uuid, contextTemplate) in indexToTemplate)
{
matcherData.GetOrInsertByKey("queries").SetContextTemplate(contextTemplate);
matcherModule.Invoke(matcherData);
Console.WriteLine(matcherData["results"][0]["uuid"].GetString() == uuid);
}
// 1
FacerecService service = FacerecService.createService("<dll_path>", "<conf_path>", "<license_path>");
// 2
Context indexConfig = service.createContext();
indexConfig.get("capacity").setLong(1000);
indexConfig.get("model_version").setString("1000_1");
indexConfig.get("async").setBool(true);
indexConfig.get("max_license_count").setLong(1000);
DynamicTemplateIndex index = service.createDynamicTemplateIndex(indexConfig);
// 3
List<String> imagePaths = new ArrayList<>();
imagePaths.add("<image_path>");
imagePaths.add("<image_path>");
List<ProcessingBlock> pipeline = new ArrayList<>(3);
Context detectorConfig = service.createContext();
Context fitterConfig = service.createContext();
Context faceTemplateExtractorConfig = service.createContext();
Context matcherConfig = service.createContext();
detectorConfig.get("unit_type").setString("FACE_DETECTOR");
fitterConfig.get("unit_type").setString("FACE_FITTER");
faceTemplateExtractorConfig.get("unit_type").setString("FACE_TEMPLATE_EXTRACTOR");
faceTemplateExtractorConfig.get("modification").setString("1000");
matcherConfig.get("unit_type").setString("MATCHER_MODULE");
matcherConfig.get("modification").setString("1000");
pipeline.add(service.createProcessingBlock(detectorConfig));
pipeline.add(service.createProcessingBlock(fitterConfig));
pipeline.add(service.createProcessingBlock(faceTemplateExtractorConfig));
ProcessingBlock matcherModule = service.createProcessingBlock(matcherConfig);
Map<String, ContextTemplate> uuidToTemplate = new HashMap<>();
for (String imagePath : imagePaths)
{
Context data = service.createContextFromEncodedImage(Files.readAllBytes(Paths.get(imagePath)));
for (ProcessingBlock block : pipeline)
{
block.process(data);
}
for (int i = 0; i < data.get("objects").size(); i++)
{
Context object = data.get("objects").get(i);
ContextTemplate contextTemplate = object.get("face_template").get("template").getContextTemplate();
String uuid = object.get("face_template").get("uuid").getString();
index.addContextTemplate(contextTemplate, uuid);
uuidToTemplate.put(uuid, contextTemplate);
}
}
// 4
Context matcherData = service.createContext();
matcherData.get("template_index").setDynamicTemplateIndex(index);
uuidToTemplate.forEach((uuid, contextTemplate) -> {
matcherData.get("queries").setContextTemplate(contextTemplate);
matcherModule.process(matcherData);
System.out.println(matcherData.get("results").get(0).get("uuid").getString().equals(uuid));
});
// 1
val service = FacerecService.createService("<dll_path>", "<conf_path>", "<license_path>")
// 2
val indexConfig = service.createContext();
indexConfig["capacity"].long = 1000
indexConfig["model_version"].string = "1000_1"
indexConfig["async"].bool = false
indexConfig["max_license_count"].long = 1000
val index = service.createDynamicTemplateIndex(indexConfig)
// 3
val imagePaths: MutableList<String> = mutableListOf()
imagePaths.add("<image_path>")
imagePaths.add("<image_path>")
val pipeline: MutableList<ProcessingBlock> = mutableListOf()
val detectorConfig: Context = service.createContext()
val fitterConfig: Context = service.createContext()
val faceTemplateExtractorConfig: Context = service.createContext()
val matcherModuleConfig: Context = service.createContext()
detectorConfig["unit_type"].string = "FACE_DETECTOR"
fitterConfig["unit_type"].string = "FACE_FITTER"
faceTemplateExtractorConfig["unit_type"].string = "FACE_TEMPLATE_EXTRACTOR"
faceTemplateExtractorConfig["modification"].string = "1000"
matcherModuleConfig["unit_type"].string = "MATCHER_MODULE"
matcherModuleConfig["modification"].string = "1000"
pipeline.add(service.createProcessingBlock(detectorConfig))
pipeline.add(service.createProcessingBlock(fitterConfig))
pipeline.add(service.createProcessingBlock(faceTemplateExtractorConfig))
val matcherModule: ProcessingBlock = service.createProcessingBlock(matcherModuleConfig)
val uuidToTemplate: MutableMap<String, ContextTemplate> = mutableMapOf()
for (imagePath in imagePaths)
{
val data: Context = service.createContextFromEncodedImage(File(imagePath).readBytes())
for (block in pipeline)
{
block.process(data)
}
for (i in 0..<data["objects"].size())
{
val obj: Context = data["objects"][i.toInt()]
val contextTemplate: ContextTemplate = obj["face_template"]["template"].contextTemplate
val uuid: String = obj["face_template"]["uuid"].string
index.addContextTemplate(contextTemplate, uuid)
uuidToTemplate.put(uuid, contextTemplate)
}
}
// 4
val matcherData: Context = service.createContext()
matcherData["template_index"].dynamicTemplateIndex = index
for ((uuid, contextTemplate) in uuidToTemplate)
{
matcherData["queries"].contextTemplate = contextTemplate
matcherModule.process(matcherData)
println(matcherData["results"][0]["uuid"].string == uuid)
}
Методы DynamicTemplateIndex
- C++
- Python
- Flutter
- C#
- Java
- Kotlin
// Получение UUID шаблона по индексу в базе
std::string getUUID(size_t index) const;
// Получение шаблона по UUID
pbio::ContextTemplate::Ptr at(const std::string& uuid) const;
// Получение шаблона по индексу в базе
pbio::ContextTemplate::Ptr at(int64_t index) const;
// Добавление шаблона в базу
void add(pbio::Template::Ptr templ, const std::string& uuid);
void add(const std::vector<pbio::Template::Ptr>& templates, const std::vector<std::string>& uuids);
void add(pbio::ContextTemplate::Ptr templ, const std::string& uuid);
void add(const std::vector<pbio::ContextTemplate::Ptr>& templates, const std::vector<std::string>& uuids);
// Удаление шаблона из базы по UUID
void remove(const std::string& uuid);
void remove(const std::vector<std::string>& uuids);
// Количество шаблонов в базе
size_t size() const;
// Текущая вместимость базы
size_t capacity() const;
// Слияние баз шаблонов
// otherIndex становится невалидным
void concat(DynamicTemplateIndex::Ptr otherIndex);
// Получение названия метода шаблонов в базе
std::string getMethodName() const;
# Добавление шаблона в базу
def add(self, template: ContextTemplate, uuid: str) -> None:
def add(self, template: Template, uuid: str) -> None:
def add(self, templates: Union[List[Template], List[ContextTemplate]], uuids: List[str]) -> None:
# Удаление шаблона из базы
def remove(self, uuid: str) -> None:
def remove(self, uuids: List[str]) -> None:
# Количество шаблонов в базе
def size(self) -> int:
# Текущая вместимость базы
def capacity(self) -> int:
# Слияние баз шаблонов
# other_index становится невалидным
def concat(self, other_index: "DynamicTemplateIndex") -> None:
# Получение шаблона по UUID
def at(self, uuid: str) -> ContextTemplate:
# Получение UUID шаблона по индексу в базе
def get_uuid(self, i: int) -> str:
# Получение шаблона по индексу
def get(self, index: int) -> ContextTemplate:
# Получение названия метода шаблонов в базе
def get_method_name(self) -> str:
/// Получение названия метода шаблонов в базе
String getMethodName();
/// Количество шаблонов в базе
int size();
/// Текущая вместимость базы
int capacity();
/// Получение UUID шаблона по индексу в базе
String getUUID(int index);
/// Получение шаблона по UUID
ContextTemplate at(String uuid);
/// Получение шаблона по индексу
ContextTemplate get(int index);
/// Добавление шаблона в базу
void addRecognizerTemplate(Template template, String uuid);
void addRecognizerTemplates(List<Template> templates, List<String> uuids);
void addContextTemplate(ContextTemplate template, String uuid);
void addContextTemplates(List<ContextTemplate> templates, List<String> uuids);
/// Удаление шаблона из базы
void removeByUuid(String uuid);
void removeByUuids(List<String> uuids);
/// Слияние баз шаблонов
/// otherIndex становится невалидным
void concat(DynamicTemplateIndex otherIndex);
/// Удаление базы шаблонов
void dispose();
// Получение названия метода шаблонов в базе
String getMethodName();
// Количество шаблонов в базе
long size();
// Текущая вместимость базы
long capacity();
// Получение шаблона по индексу
ContextTemplate Get(int i);
// Получение шаблона по UUID
ContextTemplate At(string uuid);
// Получение UUID шаблона по индексу в базе
string GetUUID(int i);
// Добавление шаблона в базу
void Add(Template templ, string uuid);
void Add(ContextTemplate templ, string uuid);
void Add(List<Template> templates, List<string> uuids);
void Add(List<ContextTemplate> templates, List<string> uuids);
// Удаление шаблона из базы
void Remove(string uuid);
void Remove(List<string> uuids);
// Слияние баз шаблонов
void Concat(DynamicTemplateIndex other_index);
// Получение названия метода шаблонов в базе
String getMethodName();
// Количество шаблонов в базе
int size();
// Получение шаблона по индексу
ContextTemplate get(final long i);
// Текущая вместимость базы
long capacity();
// Получение UUID шаблона по индексу в базе
String getUUID(final long i);
// Получение шаблона по UUID
ContextTemplate at(final String uuid);
// Добавление шаблона в базу
void addContextTemplate(final ContextTemplate templ, final String uuid);
void addContextTemplate(final Vector<ContextTemplate> templates, final Vector<String> uuids);
void addTemplate(final Template templ, final String uuid);
void addTemplate(final Vector<Template> templates, final Vector<String> uuids);
// Удаление шаблона из базы
void remove(final String uuid);
void remove(final Vector<String> uuids);
// Слияние баз шаблонов
// otherIndex становится невалидным
void concat(final DynamicTemplateIndex otherIndex);
// Получение названия метода шаблонов в базе
String getMethodName();
// Количество шаблонов в базе
int size();
// Получение шаблона по индексу
ContextTemplate get(final long i);
// Текущая вместимость базы
long capacity();
// Получение UUID шаблона по индексу в базе
String getUUID(final long i);
// Получение шаблона по UUID
ContextTemplate at(final String uuid);
// Добавление шаблона в базу
void addContextTemplate(final ContextTemplate templ, final String uuid);
void addContextTemplate(final Vector<ContextTemplate> templates, final Vector<String> uuids);
void addTemplate(final Template templ, final String uuid);
void addTemplate(final Vector<Template> templates, final Vector<String> uuids);
// Удаление шаблона из базы
void remove(final String uuid);
void remove(final Vector<String> uuids);
// Слияние баз шаблонов
// otherIndex становится невалидным
void concat(final DynamicTemplateIndex otherIndex);