Перейти к содержанию

Face Search

Описание#

Face Search Api - это сервис для поиска лиц по индексу, сгенерированному с помощью алгоритма FAISS (сокр. от " Facebook AI Research Similarity Search").

Сервис производит поиск лица из отправленной фотографии в базе данных уже присутствующих фотографий. В результате поиска данной фотографии выдается список похожих фотографий в виде url-ссылки фотографии и процента похожести лиц в найденных фотографиях в дробном соотношении.

Для использования данного сервиса необходима базы данных фотографий, среди которых будет производиться поиск лиц, а также фотография, содержащая лицо человека.

Проект передается в зашифрованном виде в целях нераспространения исходного кода в формате zip-архива.

Ниже подробнее описаны этапы для использования данного проекта.


Этапы:#

1. Распаковка проекта#

Для распаковки проекта необходимо установить утилиту unzip. Скачать ее можно используя команду:

$ sudo apt install unzip

После установки утилиты необходимо распаковать архив с проектом. Для этого необходимо перейти в папку, в которой находится архив, и выполнить команду:

$ unzip face_search.zip

2. Заполнение переменных среды проекта#

Проект содержит .envs папку, в которой находятся файлы для определения переменных среды. В данных файлах уже присутствуют переменные среды с заполненными значениями, которые менять не рекомендуется.

В некоторых случаях также будет необходимо заполнить переменные среды внутри docker-compose файлов.

Важно: заполнение всех переменных среды обязательно для корректной работы проекта.

Ниже отображена таблица, по которой можно определить, какие переменные среды необходимо заполнить.

Название Описание Пример значения Путь к файлу переменных среды
MINIO_ROOT_USER Логин для локального хранилища minio admin .envs/.base
docker-compose.base.yml
MINIO_ROOT_PASSWORD Пароль для локального хранилища minio qwerty12345 .envs/.base
docker-compose.base.yml
RABBIT_USERNAME Логин для брокера сообщений RabbitMQ rabbit_admin .envs/.base
RABBIT_PASSWORD Пароль для брокера сообщений RabbitMQ qwerty12345 .envs/.base
RABBITMQ_DEFAULT_USER Логин брокера сообщений RabbitMQ, должен совпадать с RABBIT_USERNAME rabbit_admin docker-compose.base.yml
RABBITMQ_DEFAULT_PASS Пароль для брокера сообщений RabbitMQ, должен совпадать с RABBIT_PASSWORD qwerty12345 docker-compose.base.yml
AWS_REGION_NAME Регион AWS us-east-1 .envs/.base
AWS_ACCESS_KEY_ID AWS Access Key ID .envs/.base
AWS_SECRET_ACCESS_KEY AWS Secret Access Key .envs/.base
AWS_IMAGES_BUCKET_PATH Путь к бакету с фотографиями images .envs/.base
INDEX Название файла индекса test .envs/.base
LIMIT Количество pickle-файлов, которые будут извлечены для индексирования 500 .envs/.indexer
TRAIN_BLOCK_SIZE Количество pickle-файлов, которые будут отправлены на индексацию 100 (значение должно быть меньше LIMIT) .envs/.indexer
BATCH_SIZE Количество эмбеддингов, которые будут сериализованы в один pickle-файл 40 (значение должно быть меньше количества фотографий в хранилище s3 .envs/.indexer

3. Запуск проекта#

Краткую инструкцию по запуску проекта можно найти в README.md файле в корне проекта.

Для запуска проекта необходимо наличие установленного docker и compose V2, а также утилиты make. При этом, все команды запускаются с правами суперпользователя - sudo, поэтому необходимо убедиться, что текущий пользователь имеет права на выполнение команд суперпользователя.

После установки необходимых утилит, необходимо перейти в папку с проектом и выполнить команды:

# Создание сети для взаимодействия контейнеров docker
$ docker network create face-net
# Запуск базовых сервисов - minio, rabbitmq, mongodb
$ make base

Важно: При запуске векторизации, необходимо убедиться, что в хранилище s3 присутствуют фотографии, которые необходимо векторизовать. Фотографии должны быть расположены в бакете, который указан в переменной среды AWS_IMAGES_BUCKET_PATH. В названии фотографии, так же как и в названии бакета не должно быть пробелов. Фотографии также должны быть доступны для публичный доступ для всех пользователей на чтениею

После успешного запуска базовых сервисов, необходимо запустить сервис векторизации:

# Векторизация фотографий
$ make vectorize

Важно: Векторизация может занять продолжительное время, в зависимости от количества фотографий в хранилище s3. Команду векторизации рекомендуется запускать единожды.

Чтобы посмотреть ход векторизации, можно выполнить команду:

# Просмотр логов векторизации
$ make vectorize-logs

Затем необходимо запустить сервис индексации:

# Индексация эмбеддингов
$ make index
Чтобы посмотреть ход индексации, можно выполнить команду:
# Просмотр логов индексации
$ make index-logs

После успешного запуска сервиса индексации, необходимо запустить сервис поиска:

# Запуск сервиса поиска
$ make api

Также, необходимо запустить периодическую задачу, которая будет обновлять индекс:

# Запуск периодической задачи
$ make setup-cronjob

Важно: Путь до папки с проектом не должен содержать в названиях пробелов. В противном случае, периодическая задача не будет работать.

Удалить периодическую задачу можно с помощью команды:

# Удаление периодической задачи
$ make remove-cronjob
Документация OpenApi сервиса поиска будет доступна локально по данному адресу.

4. Использование сервиса#

Сервис содержит два эндпойнта:

  1. Эндпойнт для поиска по фотографии
  2. Эндпойнт для загрузки фотографий в хранилище s3 и загрузки векторов и эмбеддингов в базу данных MongoDB

Важно: API-KEY будет убран в дальнейших обновлениях проекта. Его текущее значение - 123123123

4.1 Использования эндпойнта для поиска лиц по фотографии#

В запросах к сервису используются данные в формате multipart/form-data. Ответные данные от сервиса будут представлены в формате JSON.

URL запроса для поиска фотографий:

https://{server_api}/api/v1/search/

server_ip - адрес сервера, на котором запущен сервис поиска. Необходимо заменить на реальный адрес сервера.

Формат запроса Метод запроса
multipart/form-data POST

API KEY необходимо передать в заголовках запроса:

Наименование поля Тип Обязательно Описание
img File Да Фотография лица для поиска

Примеры запроса:

curl -X 'POST' \
  'http://{server-ip}/api/v1/search/' \
  -H 'accept: application/json' \
  -H 'X-API-KEY: 123123123' \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@<path_to_face_photo>;type=image/jpeg'
import pprint
import requests

url = 'http://{server-ip}/api/v1/search/'
headers = {
    'accept': 'application/json',
    'X-API-KEY': '123123123',
}
files = {
    'file': ('face_photo.jpg', open('<path_to_face_photo>', 'rb'), 'image/jpeg')
}

response = requests.post(url, headers=headers, files=files)

pprint.pprint(response.json())

В качестве ответа придет массив JSON со следующими полями:

  • url - адрес фотографии в хранилище s3;
  • prediction - процентное значение похожести лица на искомое;

Пример ответа:

{
  "url": "https://face2face-storage.s3.eu-central-1.amazonaws.com/face_photo.jpg",
  "prediction": 81,
}

Ошибки при поиске фотографий#

Код состояния Ответ Описание
404 No faces found on provided image Лицо не найдено. Возникает если на фотографии нет лица
400 File must be an image Недопустимое расширение файла. Возникает, если файл с изображением лица не имеет расширения .jpeg, .jpg или .png

4.2 Использования эндпойнта для загрузки фотографий#

В запросах к сервису используются данные в формате multipart/form-data. Ответные данные от сервиса будут представлены в формате JSON

URL запроса для загрузки фотографий:

https://{server_api}/api/v1/search/

server_ip - адрес сервера, на котором запущен сервис поиска. Необходимо заменить на реальный адрес сервера.

Формат запроса Метод запроса
multipart/form-data POST

API KEY необходимо передать в заголовках запроса:

Наименование поля Тип Обязательно Описание
img File Да Фотография лица для поиска

Примеры запроса:

curl -X 'POST' \
  'http://{server-ip}/api/v1/upload/' \
  -H 'accept: application/json' \
  -H 'X-API-KEY: 123123123' \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@<path_to_face_photo>;type=image/jpeg'
import requests

url = 'http://{server-ip}/api/v1/upload/'
headers = {
    'accept': 'application/json',
    'X-API-KEY': '123123123',
}
files = {
    'file': ('face_photo.jpg', open('<path_to_face_photo>', 'rb'), 'image/jpeg')
}

response = requests.post(url, headers=headers, files=files)

print(response.text)

В качестве ответа должен прийти следующий JSON:

{
  "message": "File was successfully uploaded"
}

Ошибки при загрузке фотографий#

Код состояния Ответ Описание
400 File must be an image Недопустимое расширение файла. Возникает, если файл с изображением лица не имеет расширения .jpeg, .jpg или .png