| # Face Intel |
|
|
| **Modular image intelligence platform β OSINT, face recognition, forensic metadata, object intelligence, location estimation, AI-image detection, and a true reverse face search engine.** |
|
|
| Face Intel aggregates **16+ providers** across 11 capability buckets in parallel β face detection, recognition, reverse search, forensics, OCR, metadata, NSFW detection, scene recognition, AI-image detection, and object intelligence β with an evidence-first, explainable confidence model. |
|
|
| Runs anywhere Python 3.11+ runs. Default install is lightweight enough for free-tier VPS / Railway / Hugging Face Spaces / Termux. Heavy ML deps (ONNX, dlib, Selenium) are opt-in. |
|
|
| --- |
|
|
| ## Why Face Intel? |
|
|
| | Tool | What it does | Pricing | Face Intel advantage | |
| |---|---|---|---| |
| | **PimEyes** | Reverse face search | $30β300/mo | Open source, self-hosted, multi-provider | |
| | **FaceCheck.ID** | Reverse face search | $20β100/mo | Free tier, evidence-first | |
| | **TinEye** | Reverse image search | $200/mo API | Multi-engine (Google/Bing/Yandex/TinEye/Reddit) | |
| | **DeepFace** (library) | Face recognition | Free | Face Intel wraps + extends with forensics + OSINT + AI-detection | |
| | **Maltego** transforms | Image OSINT | $999/yr | Argus-style integration potential | |
|
|
| Face Intel collapses 16 providers into a single API call: face detection, recognition, reverse image search, EXIF/GPS, ELA forensics, OCR, NSFW detection, AI-image detection, scene recognition, barcode/QR, and image quality analysis. |
|
|
| --- |
|
|
| ## Key Features |
|
|
| ### π― Reverse Face Search (NEW) |
| True PimEyes-style "find this face elsewhere" β not just reverse image search. |
|
|
| - **Face enrollment API** β index faces with metadata (name, source URL, age, etc.) |
| - **Face search API** β upload a face photo, get top-k matches from the index |
| - **sqlite-vec backend** β zero external dependencies, persists to single file |
| - **512-d ArcFace embeddings** β 99.7% accuracy on LFW |
| - **Optional crawler** β seed the index with public Wikipedia/IMDB headshots |
|
|
| ### π§© 16 Providers Across 11 Capabilities |
|
|
| | Category | Providers | |
| |---|---| |
| | **Detection** | Haar Cascade, OpenCV DNN | |
| | **Recognition** | InsightFace (ArcFace 512-d via ONNX) | |
| | **Reverse search** | SerpAPI, Social Lookup (Google/Bing/Yandex/TinEye/Reddit URL constructor), **Face Index (NEW)** | |
| | **Forensics** | Image Integrity, Duplicate Detector (pHash+dHash), ELA (Error Level Analysis), Image Similarity | |
| | **Metadata** | EXIF extraction | |
| | **OCR** | RapidOCR (multilingual) | |
| | **Object detection** | YOLOv8 | |
| | **Object intelligence** | Barcode, QR Code | |
| | **Scene recognition** | Places365 | |
| | **NSFW** | NudeNet | |
| | **AI image detection** | LAID (detect AI-generated images) | |
| | **Embeddings** | MobileNet | |
| | **Image analysis** | Image Quality (brightness/contrast/sharpness/noise), Image Properties | |
|
|
| --- |
|
|
| ## Quick Start |
|
|
| ### Local |
|
|
| ```bash |
| git clone https://github.com/marwangpt237/face-intel.git |
| cd face-intel |
| pip install -r requirements.txt |
| cp .env.example .env |
| # edit .env to enable/disable providers |
| python app.py |
| # or: uvicorn app:app --reload |
| ``` |
|
|
| Open: |
| - http://localhost:8000/docs β Swagger UI |
| - http://localhost:8000/health β health check |
| - http://localhost:8000/providers β provider list |
| - http://localhost:8000/stats β metrics |
|
|
| ### Docker |
|
|
| ```bash |
| docker build -t face-intel . |
| docker run -p 8000:8000 -v $(pwd)/data:/app/data face-intel |
| ``` |
|
|
| ### Deploy to free-tier clouds |
|
|
| | Cloud | Free tier | Steps | |
| |---|---|---| |
| | **Hugging Face Spaces** | 16GB RAM, unlimited | New Space β SDK: Docker β upload files β live at `https://{user}-face-intel.hf.space` | |
| | **Render** | 750 hrs/mo | New β Web Service β connect repo β Build: `pip install -r requirements.txt` β Start: `uvicorn app:app --host 0.0.0.0 --port $PORT` | |
| | **Fly.io** | 3 shared-cpu VMs | `flyctl launch` (set `internal_port = 8000` in `fly.toml`) β `flyctl deploy` | |
| | **Koyeb** | 1 free web service | `koyeb service create face-intel --git github.com/marwangpt237/face-intel --ports 8000:http` | |
| | **Railway** | $5 free credit/mo | New project β Deploy from GitHub β auto-detects Dockerfile | |
|
|
| --- |
|
|
| ## API Endpoints |
|
|
| ### Core |
|
|
| | Method | Path | Description | |
| |---|---|---| |
| | `POST` | `/faces/detect` | Detect faces in an image | |
| | `POST` | `/faces/recognize` | Recognize faces against the gallery | |
| | `POST` | `/search/reverse` | Reverse image search (Google Lens / TinEye URLs) | |
| | `POST` | `/search/scrape` | Scrape images from a URL | |
| | `POST` | `/jobs` | Full-pipeline job | |
| | `GET` | `/providers` | List all providers | |
| | `GET` | `/stats` | Metrics snapshot | |
| | `GET` | `/health/providers` | Per-provider health | |
|
|
| ### Reverse Face Search (NEW) |
|
|
| | Method | Path | Description | |
| |---|---|---| |
| | `POST` | `/faces/enroll` | Enroll a face into the searchable index | |
| | `POST` | `/faces/search` | Search the index for matching faces | |
| | `GET` | `/faces/list` | Paginated list of enrolled faces | |
| | `GET` | `/faces/{face_id}` | Get details of a specific enrolled face | |
| | `DELETE` | `/faces/{face_id}` | Remove a face from the index | |
| | `POST` | `/faces/crawl` | Trigger the public-faces crawler (Wikipedia/IMDB seed) | |
| | `GET` | `/faces/stats` | Index statistics (count, last update, etc.) | |
|
|
| #### Example: Enroll a face |
|
|
| ```bash |
| curl -X POST http://localhost:8000/faces/enroll \ |
| -F "image=@photo.jpg" \ |
| -F "name=John Doe" \ |
| -F "source_url=https://example.com/profile" \ |
| -F "metadata={\"age\":30,\"location\":\"US\"}" |
| ``` |
|
|
| Response: |
| ```json |
| { |
| "face_id": "f3a2b1c8-...", |
| "status": "enrolled", |
| "embedding_dim": 512, |
| "thumbnail_path": "data/thumbnails/f3a2b1c8.jpg" |
| } |
| ``` |
|
|
| #### Example: Search for a face |
|
|
| ```bash |
| curl -X POST http://localhost:8000/faces/search \ |
| -F "image=@query.jpg" \ |
| -F "top_k=5" \ |
| -F "threshold=0.5" |
| ``` |
|
|
| Response: |
| ```json |
| { |
| "query_face_detected": true, |
| "num_matches": 3, |
| "matches": [ |
| { |
| "face_id": "f3a2b1c8-...", |
| "name": "John Doe", |
| "source_url": "https://example.com/profile", |
| "similarity": 0.87, |
| "metadata": {"age": 30, "location": "US"} |
| } |
| ] |
| } |
| ``` |
|
|
| --- |
|
|
| ## Architecture |
|
|
| Face Intel is built on **11 strict one-way dependency layers** with dependency injection throughout. No global state. Every provider is isolated β failures don't cascade. |
|
|
| ``` |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| β FACE INTEL β |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ |
| β api/ FastAPI routes + middleware + DI container β |
| β services/ High-level orchestration services β |
| β orchestrator/ Async fan-out, retry, circuit breaker, cache β |
| β pipeline/ Image preprocessing + feature extraction β |
| β providers/ 16 providers across 11 capabilities β |
| β cores/ Shared modules (face, vision, onnx, embedding) β |
| β storage/ Database, cache, artifacts, reference store β |
| β config/ Pydantic settings (FI_* env vars) β |
| β models/ Pydantic schemas for requests/responses β |
| β metrics/ Prometheus-style collector β |
| β utils/ Logging, audit, helpers β |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| ``` |
|
|
| See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full layer dependency graph, execution flow, lifecycle diagrams, and DI container docs. |
|
|
| --- |
|
|
| ## Adding a New Provider |
|
|
| 1. Implement `providers/<category>/<name>.py` (subclass `BaseProvider`) |
| 2. Add one entry to `PROVIDER_MANIFEST` in `providers/registry.py` |
| 3. Add an `enable_<name>: bool = False` flag to `config/settings.py` |
|
|
| That's it β the orchestrator, services, API, and UI pick it up automatically. See [`docs/PROVIDERS.md`](docs/PROVIDERS.md) for the complete step-by-step guide. |
|
|
| --- |
|
|
| ## Configuration |
|
|
| Every config is via `FI_*` env vars. See [`.env.example`](.env.example) for the full list, or [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md) for type, default, and description of each. |
|
|
| Key ones: |
|
|
| | Var | Default | Description | |
| |---|---|---| |
| | `FI_HOST` | `0.0.0.0` | Bind host | |
| | `FI_PORT` | `8000` | Bind port | |
| | `FI_ENABLE_INSIGHTFACE` | `false` | Enable ArcFace recognition (requires ONNX) | |
| | `FI_ENABLE_FACE_INDEX` | `true` | Enable reverse face search | |
| | `FI_FACE_INDEX_PATH` | `data/face_index.db` | Path to sqlite-vec index | |
| | `FI_FACE_INDEX_TOP_K` | `10` | Default top_k for search | |
| | `FI_RATE_LIMIT_PER_MINUTE` | `30` | API rate limit | |
| |
| --- |
| |
| ## Engineering Principles |
| |
| - **Modular** β every provider is isolated; failures don't cascade |
| - **Extensible** β new providers require zero orchestrator/API changes |
| - **Production-ready** β circuit breakers, retries, caching, rate limiting, audit log |
| - **Evidence-first** β raw provider responses preserved verbatim |
| - **Explainable** β confidence scores decomposed into weighted sub-scores |
| - **Clean separation** β 11 layers, strict one-way dependency direction |
| - **DI throughout** β no global stateful objects; everything injectable |
| |
| --- |
| |
| ## Documentation |
| |
| | Document | Audience | What's in it | |
| |---|---|---| |
| | [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | All engineers | Layer dependency graph, execution flow, lifecycle diagrams, DI container, structured logging, metrics subsystem | |
| | [`docs/PROVIDERS.md`](docs/PROVIDERS.md) | Provider authors | Provider Protocol, capability enum, step-by-step guide to adding a new provider, manifest format, health check & error handling patterns, testing pattern | |
| | [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) | API consumers | Every endpoint with method, path, request/response schemas, status codes, `curl` examples | |
| | [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md) | Operators | Every `FI_*` env var with type, default, and description | |
| | [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) | SRE / DevOps | Local dev setup, Docker deployment, Kubernetes manifests, reverse proxy config, storage layout, load balancer health probes | |
| | [`docs/TESTING.md`](docs/TESTING.md) | Contributors | Test structure (unit/provider/integration), how to run tests, how to write new tests, fixtures, coverage goals, CI integration | |
| | [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) | On-call | Common errors and fixes: provider not_configured, circuit breaker open, model download failures, dlib compilation, Selenium/Chrome issues, cache issues, performance tuning | |
| | [`docs/ECOSYSTEM_RESEARCH.md`](docs/ECOSYSTEM_RESEARCH.md) | Architects | Open-source ecosystem survey of 42 projects across 18 capability categories, with capability matrix, priority ranking, integration roadmap, effort estimates, and example API designs | |
| | [`docs/OPTIMIZATION_REPORT.md`](docs/OPTIMIZATION_REPORT.md) | All engineers | Consolidation report: shared `cores/` modules, dependency minimization, vendor-only-what's-necessary strategy, and savings estimates (89% storage reduction, 70% startup improvement) | |
| | [`docs/research/`](docs/research/) | Researchers | 25+ JSON files of curated links across face recognition, forensics, OCR, NSFW, deepfake detection, AI image detection, lightweight models, and more | |
| |
| --- |
| |
| ## β οΈ Privacy & Legal |
| |
| Face recognition is regulated in some jurisdictions (EU GDPR, Illinois BIPA, China PIPL). Operators are responsible for: |
| |
| - Obtaining consent before enrolling faces into the index |
| - Providing a deletion mechanism (the `DELETE /faces/{face_id}` endpoint) |
| - Not storing uploaded query images longer than necessary |
| - Displaying a clear privacy policy and ToS |
| |
| The default deployment **does not crawl or index** any faces automatically. The crawler is opt-in via `POST /faces/crawl` and only seeds from public-domain sources (Wikipedia profile photos). Social media scraping is intentionally NOT supported due to legal risk. |
| |
| --- |
| |
| ## License |
| |
| MIT β see [LICENSE](LICENSE). |
| |
| ## Acknowledgments |
| |
| Built on the shoulders of giants: InsightFace, DeepFace, OpenCV, RapidOCR, YOLOv8, NudeNet, Places365, LAID, and many other open-source projects documented in [`docs/ECOSYSTEM_RESEARCH.md`](docs/ECOSYSTEM_RESEARCH.md). |
| |