Skip to main content
Data model classes for storing face embeddings, person records, and recognition performance metrics.

FaceImageRecord

Entity class for storing face embeddings with vector search indexing.
@Entity
data class FaceImageRecord(
    @Id var recordID: Long = 0,
    @Index var personID: Long = 0,
    var personName: String = "",
    @HnswIndex(
        dimensions = 512,
        distanceType = VectorDistanceType.COSINE
    ) var faceEmbedding: FloatArray = floatArrayOf()
)

Fields

recordID
Long
default:"0"
Primary key of the face image record, auto-generated by ObjectBox
personID
Long
default:"0"
Foreign key reference to PersonRecord. Indexed for efficient queries by person
personName
String
default:""
Name of the person for quick access without joining PersonRecord
faceEmbedding
FloatArray
default:"floatArrayOf()"
512-dimensional face embedding vector from FaceNet model. Indexed with HNSW for efficient vector similarity search using cosine distance

Vector indexing

The faceEmbedding field uses HNSW (Hierarchical Navigable Small World) indexing:
dimensions
Int
default:"512"
Vector dimensionality matching FaceNet-512 model output
distanceType
VectorDistanceType
default:"COSINE"
Cosine distance metric for measuring similarity between embeddings

Usage example

// Create and store a face record
val embedding = faceNet.getFaceEmbedding(croppedFaceBitmap)
val record = FaceImageRecord(
    personID = 123,
    personName = "John Doe",
    faceEmbedding = embedding
)
imagesVectorDB.addFaceImageRecord(record)

// Query by person ID
val personFaces = imagesBox
    .query(FaceImageRecord_.personID.equal(personID))
    .build()
    .find()

PersonRecord

Entity class for storing person metadata and tracking enrolled faces.
@Entity
data class PersonRecord(
    @Id var personID: Long = 0,
    var personName: String = "",
    var numImages: Long = 0,
    var addTime: Long = 0
)

Fields

personID
Long
default:"0"
Primary key of the person record, auto-generated by ObjectBox
personName
String
default:""
Name of the person
numImages
Long
default:"0"
Number of face images enrolled for this person. Used for tracking enrollment completeness
addTime
Long
default:"0"
Timestamp (in milliseconds) when the person was added to the database

Usage example

// Create a new person
val person = PersonRecord(
    personName = "John Doe",
    numImages = 0,
    addTime = System.currentTimeMillis()
)
val personID = personBox.put(person)

// Update image count after enrolling faces
person.numImages = 5
personBox.put(person)

// Query all persons sorted by name
val allPersons = personBox
    .query()
    .order(PersonRecord_.personName)
    .build()
    .find()

RecognitionMetrics

Data class for tracking face recognition pipeline performance metrics.
data class RecognitionMetrics(
    val timeFaceDetection: Long,
    val timeVectorSearch: Long,
    val timeFaceEmbedding: Long,
    val timeFaceSpoofDetection: Long
)

Fields

timeFaceDetection
Long
Time in milliseconds for face detection step
Time in milliseconds for vector database nearest neighbor search
timeFaceEmbedding
Long
Time in milliseconds for FaceNet embedding generation
timeFaceSpoofDetection
Long
Time in milliseconds for face spoof/liveness detection

Usage example

// Metrics are automatically collected during recognition
val (metrics, results) = imageVectorUseCase.getNearestPersonName(
    frameBitmap = cameraBitmap,
    flatSearch = false
)

if (metrics != null) {
    println("Face Detection: ${metrics.timeFaceDetection}ms")
    println("Embedding Generation: ${metrics.timeFaceEmbedding}ms")
    println("Vector Search: ${metrics.timeVectorSearch}ms")
    println("Spoof Detection: ${metrics.timeFaceSpoofDetection}ms")
    
    val totalTime = metrics.timeFaceDetection + 
                    metrics.timeFaceEmbedding + 
                    metrics.timeVectorSearch + 
                    metrics.timeFaceSpoofDetection
    println("Total: ${totalTime}ms")
}

Pipeline stages

The metrics correspond to the face recognition pipeline stages:
  1. Face detection: Detect and crop faces from camera frame
  2. Face embedding: Generate 512-dimensional vectors using FaceNet
  3. Vector search: Find nearest neighbor in database
  4. Spoof detection: Detect presentation attacks
Metrics are averaged when multiple faces are detected in a frame:
val metrics = RecognitionMetrics(
    timeFaceDetection = t1.toLong(DurationUnit.MILLISECONDS),
    timeFaceEmbedding = avgT2 / faceDetectionResult.size,
    timeVectorSearch = avgT3 / faceDetectionResult.size,
    timeFaceSpoofDetection = avgT4 / faceDetectionResult.size
)
Source: data/DataModels.kt

Build docs developers (and LLMs) love