Metadata-Version: 2.4
Name: RojakFace
Version: 1.0.0
Summary: A modern face recognition library with automatic learning, vector search, and AI assistant support
Author: lqmnwido
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: opencv-python
Requires-Dist: imgbeddings
Requires-Dist: numpy
Requires-Dist: Pillow
Requires-Dist: onnxruntime
Requires-Dist: huggingface_hub
Requires-Dist: transformers
Dynamic: author
Dynamic: description
Dynamic: description-content-type
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# RojakFace

A modern face recognition library with automatic learning, vector search, and AI assistant support.

Built with YuNet (deep-learning face detector) and CLIP-based embeddings (imgbeddings) for accurate face detection and recognition.

## Features

- **YuNet Face Detector** — Deep-learning ONNX model from OpenCV Zoo. More accurate than Haar cascades, detects faces at various angles and sizes.
- **Automatic Learning** — Upload a group photo and it will detect every face, recognize known identities, and automatically learn new ones with unique IDs.
- **Smart Deduplication** — Two-phase batch processing prevents cross-matching within the same image. Each face is compared against the existing database before any new vectors are inserted.
- **Hybrid Storage** — PostgreSQL for metadata and sighting records, Qdrant for 768-d vector similarity search (cosine distance).
- **Pluggable Storage** — Swap between local filesystem and MinIO (S3-compatible) without changing code.
- **AI-Ready** — Built for LLM integration. Provides structured identity context with image URLs for AI assistants (Ollama, OpenAI, etc.).
- **Identity Renaming** — Rename across both PostgreSQL and Qdrant with one call.

## Installation

```bash
pip install RojakFace
```

## Quick Start

```python
import RojakFace as RF
import psycopg2
from qdrant_client import QdrantClient

# 1. Setup connections
pg_conn = psycopg2.connect(database="faces_db", user="dev", password="password")
q_client = QdrantClient("localhost", port=6333)

# 2. Initialize manager
manager = RF.RojakFaceManager(pg_conn, q_client)
manager.init_storage()

# 3. Upload and auto-learn
stats = manager.auto_learn("group_photo.jpg", filename="family.jpg")
print(f"{stats['new_faces']} new faces, {stats['known_faces']} known")

# 4. Rename an identity
manager.update_identity("Person_abc123", "Mom")

# 5. Recognize without saving
results = manager.recognize("new_photo.jpg")
for face in results:
    print(f"{face['identity']} ({face['confidence']:.2f})")
```

## Storage

### LocalStorage (default)

```python
storage = RF.LocalStorage(base_path="/path/to/images")
manager = RF.RojakFaceManager(pg_conn, q_client, storage=storage)
```

### MinIO (S3-compatible)

```python
storage = RF.MinioStorage(
    endpoint="localhost:9000",
    access_key="minioadmin",
    secret_key="minioadmin",
    bucket_name="rojakface",
)
manager = RF.RojakFaceManager(pg_conn, q_client, storage=storage)
```

### Custom Storage

```python
from RojakFace import BaseStorage

class MyStorage(BaseStorage):
    def save_image(self, image_data, folder, filename): ...
    def get_url(self, folder, filename): ...
```

## API

### `RojakFace`

Low-level detector with YuNet + imgbeddings.

```python
detector = RF.RojakFace()
results = detector.extract_features("image.jpg")
# Returns: [{ 'box': [x,y,w,h], 'confidence': 0.92, 'embedding': [...], 'face_image': np.array }]
```

### `RojakFaceManager`

| Method | Description |
|--------|-------------|
| `init_storage()` | Create PostgreSQL table and Qdrant collection |
| `auto_learn(image, threshold=0.85, filename=None)` | Detect, recognize known, learn new |
| `recognize(image, limit=1, threshold=0.7)` | Recognize without saving |
| `update_identity(old, new)` | Rename across all storage backends |

## Requirements

- Python >= 3.8
- PostgreSQL (with `psycopg2`)
- Qdrant vector database
- Ollama (optional, for AI chat features)

---

Made by **lqmnwido**
