{"id":48680844,"url":"https://github.com/prasadus92/face-recognition","last_synced_at":"2026-06-15T12:01:45.969Z","repository":{"id":18127427,"uuid":"21205928","full_name":"prasadus92/face-recognition","owner":"prasadus92","description":"A Java-based face recognition system that uses eigenfaces for face recognition under various conditions including expressions, occlusions, and pose variations.","archived":false,"fork":false,"pushed_at":"2026-04-14T08:00:19.000Z","size":5425,"stargazers_count":172,"open_issues_count":14,"forks_count":55,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-04-14T09:30:02.137Z","etag":null,"topics":["face-detection","face-recognition","image-processing","java","mysql"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prasadus92.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2014-06-25T14:24:28.000Z","updated_at":"2026-04-14T07:45:52.000Z","dependencies_parsed_at":"2022-09-24T04:52:01.746Z","dependency_job_id":null,"html_url":"https://github.com/prasadus92/face-recognition","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/prasadus92/face-recognition","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasadus92%2Fface-recognition","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasadus92%2Fface-recognition/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasadus92%2Fface-recognition/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasadus92%2Fface-recognition/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prasadus92","download_url":"https://codeload.github.com/prasadus92/face-recognition/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasadus92%2Fface-recognition/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34361403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["face-detection","face-recognition","image-processing","java","mysql"],"created_at":"2026-04-11T01:00:36.072Z","updated_at":"2026-06-15T12:01:45.963Z","avatar_url":"https://github.com/prasadus92.png","language":"Java","funding_links":[],"categories":["人工智能"],"sub_categories":["计算机视觉"],"readme":"\u003ch1 align=\"center\"\u003eFace Recognition\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eA classical face-recognition library for the JVM — Eigenfaces, Fisherfaces, LBPH — wrapped in a Spring Boot REST API and a Picocli CLI.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/prasadus92/face-recognition/actions/workflows/build.yml\"\u003e\n    \u003cimg src=\"https://github.com/prasadus92/face-recognition/actions/workflows/build.yml/badge.svg?branch=master\" alt=\"Build Status\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/prasadus92/face-recognition\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/prasadus92/face-recognition/branch/master/graph/badge.svg\" alt=\"Code Coverage\"/\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/java-17%2B-blue.svg\" alt=\"Java 17+\"/\u003e\n  \u003cimg src=\"https://img.shields.io/badge/spring--boot-3.2-brightgreen.svg\" alt=\"Spring Boot 3.2\"/\u003e\n  \u003ca href=\"License.txt\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/license-Apache%202.0-blue.svg\" alt=\"License\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/prasadus92/face-recognition/stargazers\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/stars/prasadus92/face-recognition?style=social\" alt=\"Stars\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#status\"\u003eStatus\u003c/a\u003e ·\n  \u003ca href=\"#quick-start\"\u003eQuick Start\u003c/a\u003e ·\n  \u003ca href=\"#algorithms\"\u003eAlgorithms\u003c/a\u003e ·\n  \u003ca href=\"#rest-api\"\u003eREST API\u003c/a\u003e ·\n  \u003ca href=\"#cli\"\u003eCLI\u003c/a\u003e ·\n  \u003ca href=\"#benchmarks\"\u003eBenchmarks\u003c/a\u003e ·\n  \u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Status\n\n\u003e **Actively maintained.** Originally released in 2014 as a university project (`TSCD` + Swing GUI); fully rewritten for v2 as a service-shaped library with clean-architecture layering, a REST/CLI surface, and a classical-vision pipeline. v2 is **not yet** published to Maven Central — install from source (see below). See [ROADMAP.md](ROADMAP.md) for what is landed vs. planned and [CHANGELOG.md](CHANGELOG.md) for recent changes.\n\nThis repository is a learning-friendly reference implementation of the classical face-recognition pipeline — not a competitor to `dlib`, OpenCV DNN, or modern CNN-based libraries. If you need state-of-the-art accuracy, bring a real model via the [Deep-learning backend](#deep-learning-backend-experimental).\n\n## Features\n\n- **Three classical feature extractors** — Eigenfaces (PCA), Fisherfaces (LDA), LBPH\n- **Pluggable** `FeatureExtractor` / `FaceClassifier` / `FaceDetector` interfaces\n- **Clean architecture** — `domain` / `application` / `infrastructure` / `api` layers\n- **REST API** with OpenAPI 3 / Swagger UI, request correlation IDs, validation, rate limiting, Prometheus metrics\n- **CLI** (Picocli) for `enroll`, `train`, `recognize`, `serve`, `benchmark`\n- **Model persistence** — auto-save/auto-load + REST export/import\n- **Docker image** — multi-stage build, non-root user, container-aware JVM\n- **Experimental ONNX backend** scaffold for FaceNet/ArcFace-style embeddings (bring your own weights)\n\n## Status matrix\n\n| Capability | State | Notes |\n|---|---|---|\n| Eigenfaces extractor | Stable | PCA via JAMA |\n| Fisherfaces extractor | Stable | LDA on top of PCA |\n| LBPH extractor | Stable | Uniform LBP histograms, configurable grid |\n| KNN classifier | Stable | Euclidean / Cosine / Manhattan / Chi-square |\n| Haar cascade face detector | Experimental | Vendored stub; real cascade data required for production |\n| Face aligner (eye-centered affine) | Stable (opt-in) | Enabled via `facerecognition.image.face-alignment` |\n| Model persistence | Stable | `FileModelRepository` + `TrainedModel` |\n| REST + OpenAPI | Stable | `/api/v1/*` + `/swagger-ui.html` |\n| Prometheus / health / metrics | Stable | Micrometer + custom `ModelReadyHealthIndicator` |\n| Rate limiting | Stable | Per-IP token bucket (Bucket4j) |\n| CLI (picocli) | Stable | `serve`, `recognize`, `enroll`, `train`, `benchmark` |\n| ONNX deep-learning extractor | Experimental scaffold | Bring your own model weights |\n| Published Maven artifact | Planned | Not yet on Central |\n\n## Quick Start\n\n### Prerequisites\n\n- JDK 17+\n- Maven 3.9+\n\n### Build\n\n```bash\ngit clone https://github.com/prasadus92/face-recognition.git\ncd face-recognition\nmvn clean package\n```\n\nThe build produces two jars in `target/`:\n- `face-recognition-\u003cversion\u003e.jar` — library jar\n- `face-recognition-\u003cversion\u003e-exec.jar` — Spring Boot executable (REST + CLI)\n\n### Run the REST API\n\n```bash\njava -jar target/face-recognition-*-exec.jar\n# → http://localhost:8080/swagger-ui.html\n# → http://localhost:8080/actuator/health\n```\n\n### Run the CLI\n\n```bash\njava -jar target/face-recognition-*-exec.jar --help\njava -jar target/face-recognition-*-exec.jar enroll --image john.jpg --name \"John Doe\"\njava -jar target/face-recognition-*-exec.jar train\njava -jar target/face-recognition-*-exec.jar recognize --image unknown.jpg\n```\n\n### Run with Docker\n\n```bash\ndocker build -t face-recognition:latest .\ndocker run --rm -p 8080:8080 -v \"$PWD/data:/app/data\" face-recognition:latest\n```\n\n### Use as a library\n\n```java\nimport com.facerecognition.application.service.FaceRecognitionService;\nimport com.facerecognition.infrastructure.extraction.EigenfacesExtractor;\nimport com.facerecognition.infrastructure.classification.KNNClassifier;\nimport com.facerecognition.domain.model.FaceImage;\nimport com.facerecognition.domain.model.RecognitionResult;\n\nimport java.io.File;\n\nFaceRecognitionService service = FaceRecognitionService.builder()\n    .extractor(new EigenfacesExtractor(10))\n    .classifier(new KNNClassifier())\n    .build();\n\nservice.enrollFromFile(new File(\"john.jpg\"), \"John Doe\");\nservice.enrollFromFile(new File(\"jane.jpg\"), \"Jane Smith\");\nservice.train();\n\nRecognitionResult result = service.recognizeFromFile(new File(\"unknown.jpg\"));\nresult.getBestMatch().ifPresent(match -\u003e\n    System.out.printf(\"%s (conf=%.2f)%n\",\n        match.getIdentity().getName(), match.getConfidence()));\n```\n\n## Algorithms\n\n| Algorithm | Idea | Best for | Tradeoffs |\n|---|---|---|---|\n| **Eigenfaces (PCA)** | Project faces onto principal components of training set. | Fast, controlled environments. | Sensitive to lighting and pose. |\n| **Fisherfaces (LDA)** | Maximize between-class / within-class scatter. | Varied lighting with ≥2 samples/identity. | Requires multiple labelled samples per identity. |\n| **LBPH** | Concatenate histograms of local binary patterns over a grid. | Texture-based matching under lighting changes. | Pose-sensitive; higher memory. |\n\nThe classical extractors live under `com.facerecognition.infrastructure.extraction` and are selected declaratively via `application.yml` (`facerecognition.extraction.algorithm = eigenfaces | fisherfaces | lbph | onnx`) or programmatically via the service builder.\n\n### Deep-learning backend (experimental)\n\nAn `OnnxDeepFeatureExtractor` scaffold is included for running modern embedding networks (FaceNet, ArcFace, etc.) via ONNX Runtime. **It ships without model weights** — you must supply your own (`.onnx`) and configure the model path in `application.yml`. See `docs/onnx.md` (forthcoming) for the contract.\n\n## REST API\n\n| Endpoint | Method | Purpose |\n|---|---|---|\n| `/api/v1/enroll` | POST multipart | Register a face sample for a name |\n| `/api/v1/recognize` | POST multipart | Identify a face in an uploaded image |\n| `/api/v1/train` | POST | Train / retrain on all enrolled samples |\n| `/api/v1/identities` | GET | List enrolled identities (paginated) |\n| `/api/v1/identities/{id}` | GET / PATCH / DELETE | Read, update, soft-delete an identity |\n| `/api/v1/model/status` | GET | Model state, algorithm, identity counts |\n| `/api/v1/model/export` | POST | Download a serialized `TrainedModel` |\n| `/api/v1/model/import` | POST multipart | Load a previously exported model |\n| `/actuator/health` | GET | Liveness + custom `model-ready` indicator |\n| `/actuator/prometheus` | GET | Micrometer metrics in Prometheus format |\n| `/swagger-ui.html` | GET | Interactive OpenAPI 3 docs |\n\nEvery response that represents an error uses the [`ErrorResponse`](src/main/java/com/facerecognition/api/rest/dto/ErrorResponse.java) shape and carries a `traceId` (echoed from the `X-Request-ID` request header or generated if absent).\n\n### Security and limits\n\n- **Rate limit**: per-IP token bucket (default 60 req/min, configurable via `facerecognition.ratelimit.*`).\n- **Upload limit**: `spring.servlet.multipart.max-file-size` (10 MB default).\n- **CORS**: disabled by default; enable via `facerecognition.cors.*`.\n- **Authentication**: no auth by default. Deploy behind an API gateway / reverse proxy, or enable the optional API-key filter (`facerecognition.security.api-key`).\n\n## CLI\n\n```text\nUsage: face-recognition [COMMAND]\nCommands:\n  enroll      Enroll a face image under a name.\n  train       Train or retrain the model.\n  recognize   Recognize a face from an image or directory.\n  benchmark   Run accuracy/performance benchmarks on a dataset.\n  serve       Start the HTTP API server.\n```\n\nAll commands honour `--model \u003cpath\u003e` and `--config \u003capplication.yml\u003e` for reproducible runs.\n\n## Configuration\n\nAll runtime settings live in `src/main/resources/application.yml` and can be overridden via environment variables (`FACERECOGNITION_EXTRACTION_ALGORITHM=lbph`) or a custom `application.yml` passed to `--spring.config.location`. Core keys:\n\n```yaml\nfacerecognition:\n  detection:\n    min-face-size: 30\n    min-confidence: 0.5\n  extraction:\n    algorithm: eigenfaces      # eigenfaces | fisherfaces | lbph | onnx\n    num-components: 10\n    onnx:\n      model-path: \"\"           # path to a .onnx model for the deep backend\n  classification:\n    algorithm: knn\n    k-neighbors: 3\n    distance-metric: euclidean # euclidean | cosine | manhattan | chi_square\n  recognition:\n    threshold: 0.6\n  quality:\n    min-score: 0.3\n  image:\n    target-width: 100\n    target-height: 100\n    face-alignment: true\n  model:\n    auto-save: true\n    auto-load: true\n    save-path: data/models/default.frm\n  ratelimit:\n    enabled: true\n    requests-per-minute: 60\n```\n\n## Benchmarks\n\n\u003e **Honest disclaimer.** The numbers currently checked into [docs/benchmarks/](docs/benchmarks/) come from the bundled micro-dataset (`src/test/resources/datasets/mini/`) and are not directly comparable to LFW or Yale B. Classical algorithms on aligned frontal faces typically land in the 80–95% range depending on dataset; don't expect deep-learning-level accuracy.\n\nRun the benchmark suite locally:\n\n```bash\nmvn -P benchmarks exec:java\n# or via the CLI\njava -jar target/face-recognition-*-exec.jar benchmark \\\n    --dataset src/test/resources/datasets/mini \\\n    --algorithm all \\\n    --report docs/benchmarks/mini.json\n```\n\nThe benchmark harness lives under `com.facerecognition.benchmark` and reports top-1 accuracy, per-stage latency, and confusion matrices as JSON / Markdown.\n\n## Observability\n\n- **Logs** — structured via Logback, per-request `traceId` via MDC; file appender rolls daily with 1 GB cap.\n- **Metrics** — custom Micrometer timers `facerecognition.detect`, `facerecognition.extract`, `facerecognition.match`, `facerecognition.recognize.total`; counters for recognitions / enrollments / errors.\n- **Health** — `/actuator/health` exposes a custom `model-ready` component reflecting `FaceRecognitionService#isTrained()`.\n- **Tracing** — propagate `X-Request-ID` from your upstream and it will appear in every log line and response body.\n\n## Project layout\n\n```\nface-recognition/\n├── src/\n│   ├── main/\n│   │   ├── java/com/facerecognition/\n│   │   │   ├── FaceRecognitionApplication.java     # Spring Boot entry point\n│   │   │   ├── config/                             # @ConfigurationProperties + bean factories\n│   │   │   ├── domain/                             # Pure domain model + service interfaces\n│   │   │   │   ├── model/\n│   │   │   │   └── service/\n│   │   │   ├── application/service/                # Orchestrator (FaceRecognitionService)\n│   │   │   ├── infrastructure/\n│   │   │   │   ├── classification/\n│   │   │   │   ├── detection/\n│   │   │   │   ├── extraction/\n│   │   │   │   ├── persistence/\n│   │   │   │   └── preprocessing/\n│   │   │   ├── api/\n│   │   │   │   ├── rest/                           # Controllers, DTOs, advice, filters\n│   │   │   │   └── cli/                            # Picocli commands\n│   │   │   └── benchmark/                          # Accuracy + performance harness\n│   │   └── resources/\n│   │       ├── application.yml\n│   │       └── logback-spring.xml\n│   └── test/java/com/facerecognition/              # Unit + integration tests\n├── docs/\n│   ├── architecture.md\n│   ├── benchmarks/\n│   └── onnx.md\n├── .github/\n│   ├── workflows/                                  # CI, CodeQL, Dependabot, release\n│   ├── ISSUE_TEMPLATE/\n│   └── PULL_REQUEST_TEMPLATE.md\n├── CHANGELOG.md\n├── CONTRIBUTING.md\n├── CODE_OF_CONDUCT.md\n├── SECURITY.md\n├── ROADMAP.md\n├── Dockerfile\n└── pom.xml\n```\n\n## Contributing\n\nContributions are very welcome — bug fixes, extractors, distance metrics, deep-learning adapters, documentation. Start with [CONTRIBUTING.md](CONTRIBUTING.md), which covers the development loop, coding standards, and how to run the full test + quality-gate suite locally. Please also read the [Code of Conduct](CODE_OF_CONDUCT.md).\n\n## Security\n\nReport vulnerabilities privately — see [SECURITY.md](SECURITY.md). Do **not** file public issues for security bugs.\n\n## References\n\nThis implementation builds on foundational papers:\n\n1. Turk, M. \u0026 Pentland, A. (1991). *Eigenfaces for Recognition.*\n2. Belhumeur, P. N., Hespanha, J. P. \u0026 Kriegman, D. J. (1997). *Eigenfaces vs. Fisherfaces: Recognition Using Class Specific Linear Projection.*\n3. Ahonen, T., Hadid, A. \u0026 Pietikäinen, M. (2006). *Face Description with Local Binary Patterns.*\n4. Schroff, F., Kalenichenko, D. \u0026 Philbin, J. (2015). *FaceNet: A Unified Embedding for Face Recognition and Clustering.*\n5. Deng, J., Guo, J., Xue, N. \u0026 Zafeiriou, S. (2019). *ArcFace: Additive Angular Margin Loss for Deep Face Recognition.*\n\n## License\n\nLicensed under the **Apache License, Version 2.0** — see [License.txt](License.txt). The project was originally released under the GNU General Public License v3.0 in 2014 and was relicensed to Apache 2.0 in April 2026; the `License.txt` file explains the transition in full.\n\n## Acknowledgements\n\n- [JAMA](https://math.nist.gov/javanumerics/jama/) for numerical linear algebra.\n- [Spring Boot](https://spring.io/projects/spring-boot), [picocli](https://picocli.info/), [Micrometer](https://micrometer.io/), [Bucket4j](https://bucket4j.com/), [springdoc-openapi](https://springdoc.org/).\n- Maintainer: **[Prasad Subrahmanya](https://github.com/prasadus92)** · prasadus92@gmail.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprasadus92%2Fface-recognition","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprasadus92%2Fface-recognition","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprasadus92%2Fface-recognition/lists"}