KEJEPRET-AI
Public sourceA face recognition service for sports event photos: enrollment, embedding extraction, and similarity search.
My contribution highlights
- Designed FastAPI-Pydantic endpoints/schemas for enrollment, photo embeddings, search, health, and API key checks.
- Built enrollment from selfie URLs, largest-face selection, missing-face validation, and runner reference upserts.
- Worked on multiple-face extraction per photo, face index relationships, and embedding replacement on reprocessing.
Contents · 8 contribution modules
Main workflow
6 stepsTwo inputs—runner selfies and event photos—become face vectors. These paths meet when a client requests matching photos.
01Prepare runner references
Send an enrollment request
Marketplace backend & FastAPICreate a reference embedding
InsightFace & OpenCV
02Index event photo faces
Send candidate photos
Marketplace backendStore each face vector
Model & PostgreSQL/pgvector
03Compare and rank
Define the search scope
Client & search serviceCalculate cosine similarity
NumPy & result API
Process details & branches
Send an enrollment requestMarketplace backend & FastAPI
The client sends a runner identity and selfie URL through an API-key-protected endpoint. The service loads and decodes the image.
Create a reference embeddingInsightFace & OpenCV
The largest face is selected for enrollment, then its embedding is upserted under the runner’s identity.
Does the selfie contain a face?
- Face found. Save or update the runner reference for search.
- No face. Return an input failure instead of creating an arbitrary reference.
Send candidate photosMarketplace backend
The event photo path loads images from URLs and detects multiple faces that may appear in a single photo.
Store each face vectorModel & PostgreSQL/pgvector
512-dimensional embeddings are linked to photos and face indices. Reprocessing replaces the photo’s old embeddings.
Define the search scopeClient & search service
The client provides a runner identity and photo list. The service retrieves the relevant reference and candidate embeddings.
Calculate cosine similarityNumPy & result API
Compare vectors, take the best score per photo, apply a threshold, and sort results.
Does the score pass the threshold?
- Threshold passed. Return photo IDs and scores for mapping into the marketplace interface.
- Below threshold. The photo is excluded from matching results.
Selfies and event photos follow separate input paths. The service uses a pretrained model and compares candidate embeddings with cosine similarity in NumPy.
About KEJEPRET-AI
KEJEPRET-AI is a face recognition service connecting runner selfies with faces in sports event photos. The KeJepret marketplace backend sends runner references and candidate photos, then uses search results to display matching photos.
I built this Python/FastAPI service, from pretrained InsightFace model initialisation and image processing to embedding storage and search APIs. KeJepret uses the service as its marketplace AI integration.
My contributions
Model initialisation and inference runtime
I prepared the pretrained InsightFace buffalo_l model with ONNX Runtime on CPU. I connected model requirements to OpenCV/NumPy processing and configured model artefact locations. This underpins the service’s ability to accept images and produce comparable face vector representations.
Endpoint contracts and access checks
I designed FastAPI and Pydantic request/response schemas for enrollment, photo embeddings, search, embedding deletion, and health. Mutation and search endpoints check an API key. These contracts connect runner identities, image URLs, photo lists, and service outputs to the marketplace backend.
Enrollment and runner face references
I built image fetching from URLs, image decoding, face detection, and selection of the largest face as the enrollment reference. Embeddings are linked to runner identities through upserts so subsequent enrollment updates the same reference. Images without faces return an input failure.
Extracting multiple faces from a photo
I developed event photo processing that can handle more than one face. Each embedding is associated with a photo and face index. When a photo is reprocessed, old embeddings are replaced so search data follows the latest processing result stored by the service.
Embedding storage and data relationships
I stored 512-dimensional face vectors in PostgreSQL with pgvector, along with runner or photo relationships. References and candidates are reused when the client requests a search. Separating runner, photo, and face index relationships helps map comparison results back to application objects.
Cosine similarity and result ranking
I worked on retrieving embeddings from candidate photo lists, vector normalisation, and cosine similarity calculations in NumPy. I selected the best score per photo, mapped scores to the application scale, applied thresholds, and sorted results before returning them to the client. Candidate comparisons run in the Python application layer.
Data deletion and marketplace integration
I provided endpoints to delete runner or photo embeddings and aligned identity and photo-list input contracts. This connects AI data maintenance to marketplace data changes, while ensuring photo IDs and scores can be used by KeJepret’s search workflow.
Containers and model hosting requirements
I adjusted containers, permissions, model locations, and service startup requirements for hosting. I also fixed API contracts used by the backend. The focus is preparing an inference service the main application can call with consistent inputs and outputs.
Fields & core technologies
Project fields
Core technologies
14 commits in the last 12 months
All branches| Nov | Dec | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sept | Oct | Nov | |||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Sunday | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Monday | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Tuesday | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Wednesday | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Thursday | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Friday | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Saturday |
How it is counted · 1 repo · 1 branch
My authored commits reachable from all remote branches at sync time. Each SHA is counted once, even across branches or forks. Merge commits are excluded. Dates use the author timestamp in Western Indonesia Time (UTC+7), rather than push time. The current streak remains active when the last commit was yesterday and today is still in progress.
This calendar covers commits across all branches. Its totals may differ from GitHub’s contribution calendar, which includes other activity types and follows its own branch rules. This calendar covers only the project you are viewing.
Contribution history
14 of my non-merge commits · All branches · Data as of 3 November 2026.