The objective is to create a service that "googlifies" (or, in layman terms, to convert human eyes in googly, fun eyes) every image taken as an input.
This README has the following sections:
- Getting Started
- Setting up
- Invoking the endpoints
- Relevant considerations
Each image's prediction seems to take around 30 to 40 ms to run (results obtained in notebooks/basic.ipynb)
For the sake of reproducibility, we'll use conda to create an environment.
conda create --name googly python=3.8
conda activate googly
####Install the project requirements
(Note: one of the libraries, dlib, depends on cmake.
If your operative system is MacOS, you can install it with brew install cmake)
python -m pip install -r requirements.txt
PYTHONPATH is necessary, as throughout the service the modules' calls take in account absolute paths,
rooting from thesrc folder.
export PYTHONPATH="$PYTHONPATH:."
####Run test coverage for the whole service To run the tests and obtain the coverage, you can run
pytest --cov-report term-missing --cov=src/ tests/ --cov-fail-under=100
There are two ways to run this service: Locally, and by running it as a Docker container, and invoking the POST endpoint.
To start the service locally, it's as simple as running the supposed script:
python src/server.py
Alternatively, to build and run the Docker container, run the following instructions (it might take a while, as it'll install dlib, which is a weighty distribution):
docker build -t googly:latest .
docker run -v ~/path/to/upload/googly_images:/app/googly_images -p 5000:5000 googly
As you might have noticed, we are adding a volume to our container. This will be the destination of the googly images!
Now, the service is running! As you might have noticed in views.py, there are two possible endpoints.
They both follow the use case specified, although with different approaches:
- /googlify - takes in the image as multipart/form-data, and saves the resulting googlified picture in a specified directory.
- /googlify_base64 - takes the image in the form of a base64 string, and returns the image as a base64 string.
Input:
To invoke the first endpoint, it's as simple as running the following code:
curl -F "file=@path/to/your/file.png" http://localhost:5000/googlify
This will add the image to the googly_images folder, where you can peruse the googlified images!
Output:
Locally, the destination folder can't be modified without accessing the code (CONFIG_DIR variable in views_utils).
But, when we run the service as a container, we bind the googly_folder to an external path of the user's liking,
providing the freedom to decide where the googlified pictures will be added.
Input:
This second endpoint comes as a solution entirely deprived of actual files! You can invoke the endpoint through the following command:
curl -H "Content-Type: application/json" -d '{"img":"yourbase64string"}' http://localhost:5000/googlify_base64
To make the user's life easier, you can find downwards a one-liner that would take the path of a picture, convert it into base64 and invoke the endpoint with it:
(echo -n '{"img": "'; base64 ~/path/to/your/image.png; echo '"}') | curl -H "Content-Type: application/json" -d @- http://localhost:5000/googlify_base64
Output:
The user obtains a base64 string as a result.
You can decode the base64 string into an image here: https://codebeautify.org/base64-to-image-converter
-
There's a config file! In
config.yaml, feel free to play with the variables insideservice. These variables do the following:- confidence_threshold - between 0 and 1, how confident we need to be to validate a detected face. Default: 0.5 (50%)
- size_multiplier - considering the actual human eye's size, how many times bigger do we want the googly eye to be? Default: 2 (two times the fun!)
- random_max_percent_inc - every googly eye's size is subject to a random increase! This defines the maximum threshold that the eye can increase in size, relative to the original googly eye. Default: 0.2 (20%)
- googly_path - the path for the googly eye's image! There's two googly options for now.
-
To test the code programmatically, a jupyter notebook can be found and booted up in the
notebooksfolder. You can also find images to test the code with here! -
Models and config taken from the following sources:
- Ricardo Soares - rmssoares
For any inquiries, feel free to open up an issue.