# Getting Started with C++ API

# Prerequisites

  • C++17 compatible compiler
  • CMake 3.23+
  • Conan package manager

# Installation

Extract the SDK contents, include the headers from the include folder and link libFaceVerificationLibrary to your C++ project.

# Quick Start Example

#include "faceverifier.h"

#include <opencv2/core.hpp>
#include <opencv2/imgcodec.hpp>

#include <iostream>

int main()
{
   fvl::FaceVerifier verifier("model/model.realZ");

   cv::Mat image1 = cv::imread("image1.jpg");
   cv::Mat image2 = cv::imread("image2.jpg");

   // Detect faces
   auto faces1 = verifier.detectFaces({image1.ptr(), image1.cols, image1.rows,
       static_cast<int>(image1.step1()), fvl::ImageFormat::BGR}).get();
   auto faces2 = verifier.detectFaces({image2.ptr(), image2.cols, image2.rows,
       static_cast<int>(image2.step1()), fvl::ImageFormat::BGR}).get();

   // Compute embeddings
   std::vector<std::vector<float>> embeddings1, embeddings2;
   for (const auto& face : faces1)
       embeddings1.push_back(verifier.embedFace(face).get());
   for (const auto& face : faces2)
       embeddings2.push_back(verifier.embedFace(face).get());

   // Compare
   for (size_t i = 0; i < embeddings1.size(); ++i)
       for (size_t j = 0; j < embeddings2.size(); ++j)
           if (verifier.compareFaces(embeddings1[i], embeddings2[j]).similarity > 0.3)
               std::cout << "Match found!" << std::endl;

   return 0;
}

# Common Patterns

# Async Operations

Both detectFaces() and embedFace() are non-blocking. Each has two overloads:

std::future API — returns a std::future you can .get() on:

std::future<std::vector<fvl::Face>> result = verifier.detectFaces(imageHeader);
auto faces = result.get(); // blocks until complete

Callback API — invokes a callback when complete:

verifier.detectFaces(imageHeader, [](fvl::ResultOrError<std::vector<fvl::Face>> result) {
    if (auto* faces = std::get_if<std::vector<fvl::Face>>(&result)) {
        // process faces
    } else {
        auto& error = std::get<fvl::ErrorType>(result);
        // handle error
    }
});

You can submit multiple frames without waiting for prior results. Use getConcurrentCalculations() to monitor in-flight work.

# Image Data

Construct an ImageHeader to describe your frame data. The ImageHeader is a non-owning view — the underlying data must remain valid during the detectFaces() call, but is copied internally so it can be freed immediately after.

# Error Handling

The callback API uses ResultOrError<T> (std::variant<ResultType, ErrorType>) to represent success or failure.

# Next Steps