DynamicTemplateIndex
DynamicTemplateIndex is used to create a biometric template database.
Supported operations:
- Adding and deleting templates by UUID
- 1:N database search
The MATCHER_MODULE is used for 1:N searches.
Example of using DynamicTemplateIndex for database search:
Configuration Context Specification
async
- Creates an asynchronous version of DynamicTemplateIndexmax_license_count
- Maximum number of licensescapacity
- Reserved number of templatesmodel_version
- Method name and version in the formatname_version
{
"async": "<bool>",
"max_license_count": "<long>",
"capacity": "<long>",
"model_version": "<string>"
}
note
The async
mode in DynamicTemplateIndex is currently in beta.
Using DynamicTemplateIndex
- Create FacerecService
- Create DynamicTemplateIndex (using loaded/generated templates or specifying the initial number of templates and the modification_version of FACE_TEMPLATE_EXTRACTOR)
- Add templates (load or generate using FACE_TEMPLATE_EXTRACTOR)
- Perform a search in DynamicTemplateIndex using 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)
To run the example, the following models are required:
- 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 Methods
- C++
- Python
- Flutter
- C#
- Java
- Kotlin
// Retrieving the UUID of a template by index in the database
std::string getUUID(size_t index) const;
// Retrieving a template by UUID
pbio::ContextTemplate::Ptr at(const std::string& uuid) const;
// Retrieving a template by index in the database
pbio::ContextTemplate::Ptr at(int64_t index) const;
// Adding a template to the database
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);
// Deleting a template from the database by UUID
void remove(const std::string& uuid);
void remove(const std::vector<std::string>& uuids);
// Number of templates in the database
size_t size() const;
// Current database capacity
size_t capacity() const;
// Merging template databases
// otherIndex becomes Invalid
void concat(DynamicTemplateIndex::Ptr otherIndex);
// Retrieving the method name of templates in the database
std::string getMethodName() const;
# Adding a template to the database
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:
# Deleting a template from the database
def remove(self, uuid: str) -> None:
def remove(self, uuids: List[str]) -> None:
# Number of templates in the database
def size(self) -> int:
# Current database capacity
def capacity(self) -> int:
# Merging template databases
# otherIndex becomes invalid
def concat(self, other_index: "DynamicTemplateIndex") -> None:
# Retrieving a template by UUID
def at(self, uuid: str) -> ContextTemplate:
# Retrieving the UUID of a template by index in the database
def get_uuid(self, i: int) -> str:
# Retrieving a template by index
def get(self, index: int) -> ContextTemplate:
# Retrieving the method Name of templates in the database
def get_method_name(self) -> str:
/// Retrieving the template method name in the database
String getMethodName();
/// Number of templates in the database
int size();
/// Current database capacity
int capacity();
/// Retrieving the UUID of a template by index in the database
String getUUID(int index);
/// Retrieving a template by UUID
ContextTemplate at(String uuid);
/// Retrieving a template by index
ContextTemplate get(int index);
/// Adding a template to the database
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);
/// Removing a template from the database
void removeByUuid(String uuid);
void removeByUuids(List<String> uuids);
/// Merging template databases
/// otherIndex becomes invalid
void concat(DynamicTemplateIndex otherIndex);
/// Deleting the template database
void dispose();
// Retrieving the method name of templates in the database
String getMethodName();
// Number of templates in the database
long size();
// Current database capacity
long capacity();
// Retrieving a template by index
ContextTemplate Get(int i);
// Retrieving a template by UUID
ContextTemplate At(string uuid);
// Retrieving the UUID of a template by index in the database
string GetUUID(int i);
// Adding a template to the database
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);
// Removing a template from the database
void Remove(string uuid);
void Remove(List<string> uuids);
// Merging template databases
void Concat(DynamicTemplateIndex other_index);
// Retrieving the method name of templates in the database
String getMethodName();
// Number of templates in the database
int size();
// Retrieving a template by index
ContextTemplate get(final long i);
// Current database capacity
long capacity();
// Retrieving the UUID of a template by index in the database
String getUUID(final long i);
// Retrieving a template by UUID
ContextTemplate at(final String uuid);
// Adding a template to the database
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);
// Removing a template from the database
void remove(final String uuid);
void remove(final Vector<String> uuids);
// Merging template databases
// otherIndex becomes invalid
void concat(final DynamicTemplateIndex otherIndex);
// Retrieving the method name of templates in the database
String getMethodName();
// Number of templates in the database
int size();
// Retrieving a template by index
ContextTemplate get(final long i);
// Current database capacity
long capacity();
// Retrieving the UUID of a template by index in the database
String getUUID(final long i);
// Retrieving a template by UUID
ContextTemplate at(final String uuid);
// Adding a template to the database
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);
// Removing a template from the database
void remove(final String uuid);
void remove(final Vector<String> uuids);
// Merging template databases
// otherIndex becomes invalid
void concat(final DynamicTemplateIndex otherIndex);