Тематические фото для привлечения внимания.
Привлек? Отлично, далее идет описание проекта и остальные детали.
Проект реализует автоулучшение фото. Фокус был направлен на фото с недостаточной экспозицией в категории "Недвижимость". Проект реализован в виде сервиса с временем ответа менее 1 секунды. Для оценки качества улучшений был создан ещё один проект Dual-Choice. В финальное решение не вошли ML модели, но они были использованы в процессе анализа и прототипирования.
Название: Ассоциация Анонимных Аналитиков
- Ермаков Павел @pyrogn
- Иванов Артем @aert14
src/aaa_image_enhancement/
- устанавливаемый Python проект с запускаемыми fastapi приложениямиexperiments/
- различный кодnotebooks/
- ноутбуки с output, если потребуется для демонстрацииmodels/
- модели или fastapi приложения, задекларированные в Dockerfilebenchmarks/
- бенчмаркиdemo/
- простой сервис для демонстрации работы исправления изображенийtests/
- тесты- Dual-Choice - проект с оценкой субъективного качества фото
make demo
илиdocker compose --profiles demo up
- Смотреть Flask приложение на порту 5555. К примеру, http://127.0.0.1:5555/
- Можно вставить множество картинок
- Картинки отправляются на эндпоинт
/enhance_image
. Слева — оригинальная фотография. Если улучшения нет, то правая фотография будет отсутствовать.
make up
илиdocker compose up
для запуска главного приложения, приложения-детектора и приложения-улучшалки- Взаимодействовать с портом 8000 по эндоинтам, описанным в главном приложении.
- Код главного приложения с описанием эндпоинтов
- Код приложения-детектора
- Код приложения-улучшалки
make down
илиdocker compose --profile "*" down
- Поднять сервис на сервере через
make up
. - Установить Rye на другом устройстве/сервере. Выполнить
rye sync --features test
. (знаю, что сложно, возможно, подключу devcontainers или запуск через докер) locust -f benchmarks/benchmark_app.py --host=http://51.250.19.218:8000
(вставить адрес сервера, который будем нагружать и запустить нагрузку через интерфейс http://localhost:8089/).
На сервере с двумя 2GHz ядрами достигается ~ 15 RPS с временем ответа 100-300ms.
- Иметь запущенный Docker Engine
make test
- Контейнеры удалятся по окончанию тестирования
- Rye для менеджмента зависимостей
- FastAPI, uvicorn для бэкенда
- Docker Compose
- pytest внутри Docker для тестирования
- CI для независимого запуска тестов и линтера
- locust для нагрузочного тестирования
Это эксперимент в mermaid.
graph LR
subgraph "Internet"
style Internet fill:transparent, stroke-dasharray: 5 5
client[Client]
subgraph "Server (Docker network)"
main[Main App]
detector[Detector App]
enhancer[Enhancer App]
end
end
client <--> main
main <--> detector
main <--> enhancer
graph LR
A[Client] -->|Upload Image| B["/detect_problems"]
B -->|JSON with Defects| A
graph LR
A[Client] -->|Upload Image| C["/enhance_image"]
C -->|"Enhanced Image or 204 (no enhancement)"| A
graph LR
A[Client] -->|Upload Image and Defect Name| D["/fix_defect"]
D -->|Enhanced Image| A
Красивую автоматическую документацию также можно посмотреть, если
- Поднять сервис
make up
- Зайти на http://{host}:8000/docs или http://{host}:8000/redoc
Сложно передать диаграммой, здесь поверхностно и упущена часть взаимодействий и атрибутов, но по сути.
Пояснения:
ImageConversions
- вспомогательный класс для манипулирования картинками.ImageDefects
- это датакласс, который создаётся из EnumDefectsNames
и используется для передачи информации о дефектах.DefectsDetector
содержит в себе список из функций-детекторов, которые по картинке выдают найденные дефекты, которые будут отображены в возвращаемомImageDefects
.ImageEnhancer
имеет мапу из функций (DefectNames => Callable), и для конкретного дефекта вызывает соответсвующую функцию над картинкой для исправления.EnhanceStrategy
нужен для принятия решения об исправлении ряда дефектов. К примеру,EnhanceStrategyFirst
исправляет только первый (самый важный). И надо соответствовать интерфейсу.
classDiagram
class DefectsDetector {
+find_defects(image: ImageConversions) : ImageDefects
}
class ImageEnhancer {
+fix_defect(defect: DefectNames) : np.ndarray
}
class EnhanceStrategy {
<<interface>>
+enhance_image() : np.ndarray
}
class EnhanceStrategyFirst {
+enhance_image() : np.ndarray
}
class ImageDefects {
+has_defects() : bool
}
class DefectNames {
<<enumeration>>
BLUR
LOW_LIGHT
LOW_CONTRAST
POOR_WHITE_BALANCE
NOISY
...
}
class ImageConversions {
+to_numpy() : np.ndarray
+to_pil() : Image.Image
+to_cv2() : np.ndarray
+to_grayscale() : np.ndarray
}
DefectsDetector --> ImageDefects
DefectsDetector --> ImageConversions
ImageEnhancer --> DefectNames
EnhanceStrategy <|.. EnhanceStrategyFirst
EnhanceStrategyFirst --> ImageDefects
EnhanceStrategyFirst --> ImageEnhancer
- Относимся к main ветке осторожно, добавляем коммиты через PR. Работаем в своей ветке.
- Используем пакетный менеджер Rye (
rye sync --all-features
). - Не заливаем данные:
- В jupyter notebook перед отправкой удаляем весь output (Папка
notebooks/
добавлена в исключение, там может быть output). - Картинки и гифки не оставляем в репо, а заливаем на хранилище GitHub через вставку через веб-интерфейс.
- В jupyter notebook перед отправкой удаляем весь output (Папка
- Прогоняем код через Ruff (
rye run lint
, source находится в pyproject). Индивидуально: (rye lint --fix
,rye fmt
, либоruff check --fix
,ruff format
). - Проверяем тесты
make test
. - Все или почти все эти операции можно включить через
pre-commit install
. Можно запустить все проверки черезrye run pre
илиpre-commit run --all-files
. - Если инструмент работает некорректно, можно добавлять точечно
noqa: <code>
,type: ignore
или добавить исключения в конфиге вpyproject.toml
. Или подредактировать.pre-commit-config.yaml
. - Можно переносить и переименовывать файлы, функции, переменные. Но только через рефакторинг (как F2 или Refactor... в VSCode), чтобы ничего не сломалось.
Типизацияmypy ./src
- Проект интересный, с точки зрения ML части слабоватый. С точки зрения анализа пробемы хороший.
- Тесты неплохие, но по-хорошему надо добавить тесты на fastapi с моками, так будет правильнее, чем тестировать на реальном сервисе через docker.