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
pip install RojakFace
Quick Start
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)
storage = RF.LocalStorage(base_path="/path/to/images")
manager = RF.RojakFaceManager(pg_conn, q_client, storage=storage)
MinIO (S3-compatible)
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
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.
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
Metadata
Release files for RojakFace 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| rojakface-1.0.0.tar.gz | 150.8 kB | Without provenance | Details for rojakface-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| rojakface-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for rojakface-1.0.0-py3-none-any.whl |
Total release size: 303.4 kB
Release files / rojakface-1.0.0.tar.gz
| Download URL | rojakface-1.0.0.tar.gz |
|---|---|
| Size | 150.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c12e8ceaf7aefefedc20a8bea69ba68a52aec56ae46322ecb397553107730ecf
|
|
BLAKE2b-256 checksum How to use checksums |
45934755d698e949fdf8a78c8972b69c319d50ff1819d360af9a82b12399d1a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / rojakface-1.0.0-py3-none-any.whl
| Download URL | rojakface-1.0.0-py3-none-any.whl |
|---|---|
| Size | 152.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6645dd8b4771c5f68cd4d083d938491d07ae5fe919f0f9b9a7f7cd79b3ca39df
|
|
BLAKE2b-256 checksum How to use checksums |
5a5594519347978655242c80f0e18fe7deccd148389c4f097ea4b2d954c578f0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Security for RojakFace 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.