# Face Data Classes

## Overview

Face data in `degirum-face` is represented by two related classes:

* **`FaceAttributes`** - Contains face identity data (embeddings, attributes, images)
* **`FaceRecognitionResult`** - Includes all `FaceAttributes` properties plus detection metadata (bounding box, scores, landmarks)

## FaceAttributes

Contains face identity data without detection-specific information. Used primarily for enrollment workflows.

### Properties

| Property     | Type                | Description                                                                                                                                                                                                                 |
| ------------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `attributes` | dict or str or None | Person metadata. Can be any Python dictionary containing person information (first name, last name, address, etc.) or a simple string for the person's name. Examples in this documentation use simple strings for clarity. |
| `db_id`      | str or None         | Database ID if stored                                                                                                                                                                                                       |
| `embeddings` | list                | Face embedding vector(s) (512-D each). May contain multiple embeddings when returned by `find_faces_in_file()` / `find_faces_in_clip()`                                                                                     |
| `images`     | list                | Cropped face images (numpy arrays) corresponding to embeddings. May contain multiple images when returned by `find_faces_in_file()` / `find_faces_in_clip()`                                                                |

### When It's Used

`find_faces_in_file()` and `find_faces_in_clip()` return `Dict[int, FaceAttributes]` - a mapping of track IDs to face data. Each `FaceAttributes` object contains:

* **Multiple embeddings** - One for each frame where the face was detected (or sampled based on reid\_expiration\_frames)
* **Multiple images** - Corresponding cropped face images for each embedding
* This accumulated data across frames provides robust face representations for enrollment

Also used as input to `FaceTracker.enroll()` for batch enrollment.

### Usage Example

```python
# Analyze video to extract faces
faces = tracker.find_faces_in_file("video.mp4")

# faces is Dict[int, FaceAttributes] - maps track_id to face data
for track_id, face_data in faces.items():
    print(f"Track {track_id}:")
    print(f"  Person: {face_data.attributes}")
    print(f"  Embeddings: {len(face_data.embeddings)}")  # Multiple per track
    print(f"  Images: {len(face_data.images)}")  # Multiple per track
    
    # Enroll if unknown
    if not face_data.attributes:
        # Assign person identifier - could be a name, ID, or dict with metadata
        face_data.attributes = f"Person_{track_id}"
        tracker.enroll(face_data)
```

## FaceRecognitionResult

Subclasses `FaceAttributes` to add detection-specific metadata. Used for real-time recognition results.

### Properties

Inherits all `FaceAttributes` properties (`attributes`, `db_id`, `embeddings`, `images`) plus:

| Property           | Type          | Description                                |
| ------------------ | ------------- | ------------------------------------------ |
| `bbox`             | list          | Bounding box `[x1, y1, x2, y2]`            |
| `detection_score`  | float         | Face detection confidence 0.0-1.0          |
| `similarity_score` | float or None | Match confidence 0.0-1.0 (None if unknown) |
| `landmarks`        | array         | Facial keypoints (eyes, nose, mouth)       |
| `frame_id`         | int or None   | Frame number (when applicable)             |

**Important notes:**

* The `embeddings` and `images` lists contain a **single item** when returned by `enroll_image()`, `enroll_batch()`, `predict()`, or `predict_batch()`. Access using `result.embeddings[0]` and `result.images[0]`. This is different from `find_faces_in_file()` / `find_faces_in_clip()` which return multiple embeddings/images per track.
* When using FaceTracker, `track_id` is in `InferenceResults.results`, not as a property. Access via `result.results[i].get("track_id")`

### When It's Used

* Returned by `enroll_image()` and `enroll_batch()`
* Contained in `InferenceResults.faces` from `predict()` and `predict_batch()`

### Usage Examples

**Check if face was detected:**

```python
result = recognizer.enroll_image("photo.jpg", "Alice")
if result:
    print(f"Enrolled: {result.attributes}")
else:
    print("No face detected")
```

**Access detection properties:**

```python
result = recognizer.predict("photo.jpg")

for face in result.faces:
    if face.attributes:
        print(f"Known: {face.attributes} (confidence: {face.similarity_score:.2f})")
    else:
        print(f"Unknown person (detection score: {face.detection_score:.2f})")
    
    # Access bounding box
    x1, y1, x2, y2 = face.bbox
    print(f"Face location: ({x1}, {y1}) to ({x2}, {y2})")
```

**Access embeddings and cropped images:**

```python
result = recognizer.enroll_image("photo.jpg", "Alice")
embedding_vector = result.embeddings[0]  # 512-D numpy array
cropped_face = result.images[0]  # Aligned 112×112 face image

print(f"Embedding shape: {embedding_vector.shape}")  # (512,)
cv2.imwrite("cropped_face.jpg", cropped_face)
```

**FaceTracker - Access tracking data:**

```python
for result in tracker.predict_batch(video_source):
    # result.faces and result.results correspond at the same index
    for i in range(len(result.faces)):
        track_id = result.results[i].get("track_id")
        person = result.faces[i].attributes
        print(f"Track {track_id}: {person}")
```

## Return Types by Method

### FaceRecognizer

| Method            | Return Type                                                                   |
| ----------------- | ----------------------------------------------------------------------------- |
| `enroll_image()`  | `Optional[FaceRecognitionResult]`                                             |
| `enroll_batch()`  | `List[FaceRecognitionResult]`                                                 |
| `predict()`       | `InferenceResults` (`.faces` property yields `FaceRecognitionResult` objects) |
| `predict_batch()` | Iterator of `InferenceResults`                                                |

### FaceTracker

| Method                 | Return Type                                                                               |
| ---------------------- | ----------------------------------------------------------------------------------------- |
| `predict_batch()`      | Iterator of `InferenceResults` (`.faces` property yields `FaceRecognitionResult` objects) |
| `find_faces_in_file()` | `Dict[int, FaceAttributes]`                                                               |
| `find_faces_in_clip()` | `Dict[int, FaceAttributes]`                                                               |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.degirum.com/face-recognition/reference/face-recognition-result.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
