Перейти к основному содержимому
Версия: 3.22.0 (последняя)

Начало работы

Processing Block API (API процессинг-блоков) является масштабируемым интерфейсом, замещающим существующее Legacy API для более легкой интеграции возможностей Face SDK в ваше приложение.

Основные возможности

  • Объединение многочисленных компонентов в единую интеграцию
  • Простота и легкость изучения
  • Быстрое внедрение
  • Долгосрочная поддержка и обновления

Требования

  • Операционная система Windows x86 64-bit или Linux x86 64-bit.
  • Установлен пакет Face SDK windows_x86_64 или linux_x86_64 (см. Начало работы).

Context-контейнер

Ключевой концепцией API процессинг-блоков является использование контейнеров Context.

Context — это гетерогенный контейнер, состоящий из набора иерархически организованных данных, представленных как пары ключ-значение. Ближайший аналог Context — объект JSON. Каждый объект Context может содержать: скалярный объект (integer, real, boolean, string), указатель на область памяти, массив объектов Context, ассоциативный контейнер пар <string, Context> с неограниченной вложенностью.

Как создать и использовать Context-контейнер

  1. Создайте FacerecService.

  2. Создайте Context-контейнер:

    auto array_elem0 = service->createContext();
  3. Общий набор операций с Context:

  • создание ассоциативного контейнера по ключу ["key"] на пустом контейнере Context:

    array_elem0["name"] = "Julius Zeleny";      // передать string
    array_elem0["phone"] = 11111111111l; // передать integer (long)
    array_elem0["social_score"] = 0.999; // передать double
    array_elem0["verified"] = true; // передать bool
  • геттеры:

    ASSERT_EQ( array_elem0["name"].getString(), "Julius Zeleny" );
    ASSERT_EQ( array_elem0["phone"].getLong(), 11111111111l );
    ASSERT_EQ( array_elem0["social_score"].getDouble(), 0.999 );
    ASSERT_EQ( array_elem0["verified"].getBool(), true );
  • создание массива вызовом метода push_back на пустом контейнере Context:

    auto array == service->createContext();
    array.push_back(array_elem0);
  • итерации по массиву:


    // получить значение по индексу
    ASSERT_EQ( array[0]["phone"].getLong(), 11111111111l );

    // выполнить итерацию с индексом
    size_t array_sz = array.size();
    for(size_t i = 0; i < array_sz; ++i)
    array[i]["phone"];

    // или с итераторами
    for(auto iter = array.begin(); iter != array.end(); ++iter)
    (*iter)["phone"]; // возвращается вложенный Context

    // или с foreach
    for(auto val : array)
    val["phone"];
  • операции со вложенными ассоциативными контейнерами:

    auto full = service->createContext();
    full["friends"] = std::move(array); // использование семантики перемещения без копирования

    // доступ к вложенному объекту
    ASSERT_EQ( full["friends"][0]["social_score"].getDouble(), 0.999 );

    // перебор значений ассоциативного контейнера
    for(auto iter = full.begin(); iter != full.end(); ++iter) {
    iter.key(); // получить значение ключа из итератора
    (*iter)[0]["social_score"].getDouble(); // получить значение
    }

    // с foreach
    for(auto val : full)
    val[0]["social_score"].getDouble();
  • другие удобные методы Context:

    void clear();
    bool contains(const std::string& key); // для ассоциативного контейнера
    Context operator[](size_t index); // для последовательного массива, элемент с указанием доступа и проверкой границ
    Context operator[](const std::string& key); // для ассоциативного контейнера, доступ или вставка данных
    Context at(const std::string& key); // для ассоциативного контейнера, с проверкой границ
    size_t size(); // возвращается число элементов контейнера
    bool isNone(); // проверка на пустоту
    bool isArray(); // проверка на последовательный массив
    bool isObject(); // проверка на ассоциативный контейнер
    bool isLong(), isDouble(), isString(), isBool(); // проверка на содержание скалярного типа данных
  • методы FacerecService связанные с Context:

    pbio::Context createContextFromEncodedImage(const uint8_t* data, uint64_t dataSize);                                                 // получение Context из файла изображения
    pbio::Context createContextFromEncodedImage(const std::vector<uint8_t>& data); // получение Context из файла изображения
    pbio::Context createContextFromEncodedImage(const std::string& data); // получение Context из файла изображения
    pbio::Context createContextFromEncodedImage(const std::vector<char>& data); // получение Context из файла изображения
    pbio::Context createContextFromFrame(uint8_t* data, int32_t width, int32_t height, pbio::Context::Format format, int32_t baseAngle); // получение Context из байтов изображения

Бинарный формат изображений

Большинство процессинг-блоков выполняют операции с Context-контейнерами, содержащими изображения в бинарном формате:

{
"image" : {
"format": "NDARRAY",
"blob": "data pointer",
"dtype": "uint8_t",
"shape": [height, width, channels]
}
}

Ключ "blob" содержит умный указатель на данные. Указатель устанавливается функцией void Context::setDataPtr(void* ptr, int copy_sz), где copy_sz — размер памяти в байтах, который будет скопирован, и затем автоматически освобождается, когда заканчивается время жизни объекта Context.

Копирование не будет выполнено, если в качестве аргумента copy_sz будет передан 0. В этом случае объект Context не контролирует время жизни объекта, на который он указывает. Вы также можете аллоцировать "сырую" память, например, чтобы скопировать данные позже, передавая nullptr и размер в качестве аргументов setDataPtr.

Ключ "dtype" может содержать одно из следующих значений: "uint8_t", "int8_t", "uint16_t", "int16_t", "int32_t", "float", "double". Каждому значению соответствует определенный тип OpenCV: CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F.

Создание Context-контейнера c RGB-изображением

  1. Создайте FacerecService.
  1. Прочитайте изображение из файла:
// read the image from file
std::string inputImagePath = "{path_to_image}";
std::ifstream imageFile(inputImagePath, std::ios::binary);
std::istreambuf_iterator<char> start(file);
std::vector<char> imageData(start, std::istreambuf_iterator<char>());

3 Создайте контейнер с изображением

pbio::Context ioData = service->createContextFromEncodedImage(imageData);

Процессинг-блоки

Типы процессинг-блоков

  • FACE_DETECTOR
  • HUMAN_BODY_DETECTOR
  • HUMAN_POSE_ESTIMATOR
  • OBJECT_DETECTOR
  • FACE_FITTER
  • EMOTION_ESTIMATOR
  • AGE_ESTIMATOR
  • GENDER_ESTIMATOR
  • MASK_ESTIMATOR
  • LIVENESS_ESTIMATOR
  • QUALITY_ASSESSMENT_ESTIMATOR
  • FACE_TEMPLATE_EXTRACTOR
  • TEMPLATE_INDEX
  • MATCHER_MODULE
  • VERIFICATION_MODULE
примечание

Примеры использования Processing Block API демонстрируются в:

Настраиваемые параметры процессинг-блоков

  • unit_type: string — главный параметр процессинг-блока, определяет тип создаваемого модуля.
  • modification: string — опциональный параметр, определяет модификацию процессинг-блока. Если не указан, то будет использоваться значение по умолчанию.
  • version: int64 — опциональный параметр, определяет версию модификации процессинг-блока. Если не указан, то будет использоваться значение по умолчанию.
  • model_path: string — опциональный параметр, определяет путь до модели процессинг-блока. Если не указан, то будет использоваться значение по умолчанию.
  • use_cuda: bool — опциональный параметр, отвечает за запук процессинг-блока на GPU. Значение по умолчанию — false.
  • use_legacy: bool — опциональный параметр, нужен для использования более старой билиотеки onnxruntime. Значение по умолчанию — false.
  • ONNXRuntime — ключ для параметров конфигурации onnxruntime:
    • library_path: string — путь до библиотек onnxruntime, по умолчанию путь до директории с libfacerec.so.
    • intra_op_num_threads: int64 – число потоков для распараллеливания модуля, по умолчанию равно 1.

Создание процессинг-блока

  1. Создайте Context-контейнер, укажите нужные вам параметры и передайте его в метод FacerecService.createProcessingBlock().

    // обязательно, укажите имя процессинг-блока
    auto configCtx = service->createContext();
    configCtx["unit_type"] = "{name_of_processing_block}";

    // если не указать, то будет использоваться значение по умолчанию
    configCtx["modification"] = "{modification}";

    // если не указать, то будет использоваться первая версия модификации
    configCtx["version"] = {version};

    // модели по умолчанию расположены в директории дистрибутива Face SDK: share/processing_block/{modification}/({version}/ или {version}.enc)
    // вы можете задать ваш собственный путь до модели
    configCtx["model_path"] = "{path_to_model_file}";

    // библиотека onnxruntime по умолчанию расположена в директории дистрибутива Face SDK: "lib" для платформы Linux или "bin" для платформы Windows
    // вы можете задать ваш собственный путь до библиотеки onnxruntime
    // если путь до библиотеки не указан, то будет использоваться стандартный порядок поиска, используемый в данной ОС
    configCtx["ONNXRuntime"]["library_path"] = "../lib"; // для Linux
    configCtx["ONNXRuntime"]["library_path"] = "../bin"; // для Windows

    // опционально, значение "true" для ускорения процессинг-блоков на GPU (только для блоков с поддержкой CUDA)
    configCtx["use_cuda"] = false;
    pbio::ProcessingBlock processing_block = service->createProcessingBlock(configCtx);
  2. Подготовьте входной Context-контейнер с изображением и передайте в процессинг-блок.

    std::string inputImagePath = "{path_to_image}";
    std::ifstream imageFile(inputImagePath, std::ios::binary);
    std::istreambuf_iterator<char> start(file);
    std::vector<char> imageData(start, std::istreambuf_iterator<char>());

    // формирование входного контейнера Context
    pbio::Context ioData = service->createContextFromEncodedImage(imageData);

    // Вызов процессинг-блока
    processing_block(ioData);

Ускорение на GPU

Процессинг-блоки могут быть использованы с ускорением на GPU. Для этого необходимо определить ключ "use_cuda" со значением true для Context-контейнера процессинг-блока.

Для запуска процессинг-блоков на CUDA версии 10.1 необходимо дополнительно определить ключ "use_legacy" со значением true для Context-контейнера процессинг-блока. (См. Настраиваемые параметры процессинг-блоков).

Поддерживаемые версии CUDA см. на странице Системные требования для использования GPU