# Golang FaceID API

The FaceID API is designed to establish a backend infrastructure for user authentication through Face Recognition. This API functions by receiving a Face Representation Vector (FRV) from a remote client, then verifying whether this provided FRV corresponds to an existing one stored in the database. Based on this verification, access is either granted or denied to the client.

The FaceID API is accessible to any client capable of sending an HTTP request. Developed using Golang and following the REST architecture, the API offers flexibility in terms of client implementation. Clients can be developed in any programming language and can originate from various platforms such as web, mobile, or desktop. This seamless integration capability enables the incorporation of Face Recognition functionality into a diverse array of applications. Notably, the process of obtaining the FRV from the client falls outside the scope of the FaceID API's responsibilities.


## API Documentation  

API Documentation is available at http://faceid.orionsoft.site/reference

Note: You can use the vectors located at file `vectors.json` in the root directory of this project to test the API. These vectors are already stored in the database.

## Tecnology Stack

- Golang
- Gin Web Framework
- QDrant Vector Database 
- Vector Similarity Search
- Docker
- AWS EC2


## Face Recognition Technology

Face recognition is a technology that involves identifying and verifying individuals by analyzing and comparing their facial features. It's a subset of biometric identification, and it has various applications, including security systems, authentication, and user access control. Here's a simplified overview of how face recognition works:

**Face Detection:** The first step is to locate and extract faces from an image or video frame. This is done using face detection algorithms, which identify potential face regions in the input data.

**Face Alignment:** Once a face is detected, the algorithm might perform face alignment, ensuring that the face is in a standardized position. This helps in normalizing the features for accurate comparison.

**Feature Extraction:** This is a crucial step where distinctive features of the face are extracted and turned into a numerical representation. These features might include the distances between key facial landmarks, the angles between certain points, and other data that can differentiate one face from another. Popular techniques for feature extraction include Local Binary Patterns (LBP), Histogram of Oriented Gradients (HOG), and more recently, deep learning-based methods.

**Feature Encoding:** The extracted features are then converted into a compact representation that can be easily compared with other face representations. This often involves reducing the dimensionality of the features while preserving their discriminatory information.

**Face Database:** In your scenario, you would have a database containing the face representations (or embeddings) of authorized users. This database could be created by collecting and processing a set of images of each user during enrollment.

**Face Matching:** When a user attempts to gain access, their submitted face is processed through the same pipeline: detection, alignment, feature extraction, and encoding. The resulting face representation is then compared with the representations in your face database using a distance metric like Euclidean distance or cosine similarity. The idea is to find the closest match.

**Thresholding:** The comparison produces a similarity score. You would set a threshold value above which the submitted face is considered a match with a face in the database. The threshold helps balance false positives and false negatives.

**Decision Making:** Based on the similarity score and the threshold, a decision is made whether to grant access or not. If the score is above the threshold and within an acceptable range, access is granted. Otherwise, access is denied.

**Continuous Learning:** To improve recognition accuracy over time, some systems implement continuous learning. This involves periodically updating the face representations in the database using new images of users. This can help account for changes in appearance due to factors like aging or facial hair.


## FRV (Face Representation Vector)

The FRV is a vector that represents the face of a person. It is a numerical representation of the face, and it is used to compare faces. The FRV is generated by a Face Recognition algorithm implemented by a library used on the client side. The client side can be any platform (web, mobile, desktop, etc). Let's take a look at the FRV structure:

```
[
	0.123, -0.456,  0.789,  0.234,  0.567,  0.123,  0.678, -0.345,
	-0.987,  0.876, -0.123, -0.456,  0.789, -0.234, -0.567,  0.123,
	0.678,  0.345, -0.987, -0.876,  0.123,  0.456, -0.789,  0.234,
	0.567, -0.123,  0.678,  0.345,  0.987, -0.876, -0.123,  0.456,
	-0.789,  0.234, -0.567, -0.123, -0.678,  0.345,  0.987,  0.876,
	0.123, -0.456,  0.789, -0.234,  0.567, -0.123, -0.678, -0.345,
	0.987, -0.876,  0.123,  0.456, -0.789, -0.234, -0.567, -0.123,
	0.678, -0.345, -0.987,  0.876, -0.123, -0.456,  0.789, -0.234,
	-0.567,  0.123,  0.678,  0.345, -0.987, -0.876,  0.123,  0.456,
	-0.789,  0.234, -0.567, -0.123, -0.678,  0.345,  0.987,  0.876,
	0.123, -0.456,  0.789, -0.234,  0.567, -0.123, -0.678, -0.345,
	0.987, -0.876,  0.123,  0.456, -0.789, -0.234, -0.567, -0.123,
	0.678, -0.345, -0.987,  0.876, -0.123, -0.456,  0.789, -0.234,
	0.123, -0.456,  0.789, -0.234,  0.567, -0.123, -0.678, -0.345,
	0.987, -0.876,  0.123,  0.456, -0.789, -0.234, -0.567, -0.123,
	0.678, -0.345, -0.987,  0.876, -0.123, -0.456,  0.789, -0.234
]
```
Above we have an 128 dimension FRV (Face Representation Vector) of a numeric representation of someone's face. Different libraries can generate different dimension FRVs, which can be 256, 512 or even more dimensions long. We can think this FRV as a numeric unic stamp of someone's face. As no one has the same face, no one has the same FRV. So, a FRV can be used to identify someone against a database of FRVs. 

This FaceID API utilizes of a FRV sent by the client to identify if the given FRV matches any FRV in the database. If the given FRV matches any FRV in the database, the API grants access to the client. Otherwise, the API denies access to the client.


## Vector Database

A vector database is something new on the world of databases, and its usage is growing fast. In our case, we are using QDrant (https://qdrant.tech), a vector database that is open source and free to use. Remember that Face Representation Vectors are basically an array of float numbers that can be huge in size. On this FaceID API we are using a 128 dimension FRV, but it can be 256, 512 or even more dimensions long. So, we need a database that can store this huge amount of data and can perform fast searches on it. 

Traditional SQL and NoSQL databases can be used to store FRVs, but they are not optimized for this kind of data. Vector databases are optimized for storing and searching vectors. They are also optimized for fast searches, and can perform searches on millions of vectors in a few milliseconds. This means a face can be identified in a few milliseconds, which is great for real time applications. 


## Conclusion

This project is a simple implementation of a Face Recognition API. It is a simple API that can be used to integrate Face Recognition in any application. The API is written in Golang and uses the REST architecture. The client can be written in any language, and can come from any platform (web, mobile, desktop, etc). If you want to implement Face Recognition in your application, you can use FaceID API as a starting point. Please, feel free to contact me at `miguelangelomello@gmail.com` if you have any questions or suggestions. Thank you!

