Purpose: The goal of FIndex is to learn more about vector databases by building a practical system for face recognition and similarity search. This project demonstrates how to generate, store, and query facial embeddings using a vector database and RESTful APIs.
FIndex explores two approaches to face similarity search:
- A service-oriented application that uses
FIndex.Api,Findex.Embedder, and Qdrant. - A standalone console sample that uses local embedding generation and PostgreSQL with
pgvector.
Both approaches use the same core idea: turn face images into embedding vectors, store those vectors, and search for the nearest matches.
This is the main runtime path:
client -> FIndex.Api -> Findex.Embedder -> Qdrant -> search results
FIndex.Apiexposes the public search endpoint.Findex.Embeddergenerates embeddings through an HTTP/embedendpoint.- Qdrant stores and searches vectors.
FIndex.Consoleseeds Qdrant from local images and is launched manually from Aspire asseed-faces.
This is a standalone experiment:
images -> FIndex.VectorDataSample -> PostgreSQL + pgvector -> search results
FIndex.VectorDataSampleis a console app, not a public API.- It generates embeddings in-process using the ONNX model.
- It stores and searches vectors in PostgreSQL with the
pgvectorextension. - It recreates its sample collection when run.
- It is launched manually from Aspire as
vector-data-sample.
- ASP.NET Core Web API service that takes an image and returns a 512-dimensional facial embedding.
- Powered by ONNX Runtime and OpenCvSharp, using a pre-trained ResNet50 (WebFace600K) model. Download Link: Google Drive.
- High-performance vector search engine for similarity search.
- Stores all embedded facial vectors.
- Accepts image uploads via REST.
- Sends them to the embedding service, gets vector back.
- Searches similar vectors in Qdrant and returns matches with confidence scores.
- Manual seeding tool that uploads local face images into Qdrant for the service application.
- Legacy FastAPI-based embedding service that uses InsightFace.
- Not started by Aspire or Docker Compose; the main runtime path uses the C# embedder.
- Standalone console sample that demonstrates embedding a small face dataset and performing searches backed by PostgreSQL with the
pgvectorextension. - Expects the same
webface_r50.onnxmodel as the embedder; place it underFIndex.VectorDataSample/Data/after downloading from the link above.
- Ensure Docker Desktop (or another Docker host) is running locally.
- Download the
webface_r50.onnxmodel and place it underFindex.Embedder/Data/. - Start the system through the Aspire AppHost:
dotnet run --project FIndex.AppHostThe Aspire AppHost starts only the required runtime services: the C# embedder, Qdrant, and the public API. The .NET services run as projects, while Aspire manages Qdrant and shows resource status in the Aspire dashboard.
The seed-faces resource is also registered in Aspire, but it uses explicit start and does not run automatically. Start it manually from the Aspire dashboard when you want to seed the faces collection from FIndex.Console/faces.
The vector-data-sample resource is also explicit-start. It runs the standalone PostgreSQL/pgvector sample against the Aspire-managed vector-postgres container and is separate from the Qdrant-backed API flow.
To stop the services, stop the AppHost process with Ctrl+C.
Docker Compose remains available as a fallback:
docker compose up --buildTo stop the services press Ctrl+C, or run docker compose down in another terminal to remove the containers.
- The API is wired to the C# embedder by default (
embedder, exposed on port 5443). - The Python embedding service under
Embedder/is kept as an alternative implementation, but it is not started by Aspire or Docker Compose.
This project consists of three main services: the C# embedder, the Qdrant vector database, and the .NET API. Below are the details for accessing each service:
| Service | Host URL |
|---|---|
| FIndex Embedder | http://localhost:5443 |
| Qdrant | http://localhost:6333 |
| FIndex API | http://localhost:5181 |
This project's code is licensed under the MIT License. You are free to use, modify, and distribute the code with proper attribution.
Some images used in this project are for personal use and local experimentation only.
By using this repository, you agree not to use any of the stored or uploaded images (I'm not that pretty).