Веб-приложение для автоматической семантической сегментации зданий и объектов городской инфраструктуры на аэрофотоснимках с использованием глубокого обучения (U-Net + ResNet34).
Система выполняет попиксельную классификацию аэрофотоснимков на 6 классов:
- 🛣️ Дороги (roads) — дорожное покрытие, парковки
- 🏢 Здания (buildings) — жилые и промышленные здания
- 🌿 Низкая растительность (low vegetation) — газоны, кустарники
- 🌳 Деревья (trees) — деревья, лесные насаждения
- 🚗 Автомобили (cars) — транспортные средства
- 🔴 Прочее (clutter) — прочие объекты
Архитектура: U-Net с предобученным энкодером ResNet34
Датасет: Potsdam (2400 патчей 300×300 px)
Качество: IoU 71.56%, F1-Score 82.73%, Accuracy 87.22%
Backend:
- FastAPI 0.95.0 — REST API
- TensorFlow 2.20.0 — инференс модели
- Segmentation Models 1.0.1+ — предобученные архитектуры
- OpenCV — обработка изображений
- Uvicorn 0.21.1 — ASGI сервер
Frontend:
- Streamlit 1.51.0 — интерактивный веб-интерфейс
- Pillow 9.5.0 — работа с изображениями
- Requests 2.28.2 — HTTP-клиент
ML:
- Архитектура: U-Net + ResNet34 encoder
- Framework: TensorFlow/Keras
- Transfer Learning: ImageNet weights
- Регуляризация: Dropout 30%, L2 weight decay
- Loss: Weighted Categorical Crossentropy
- Python 3.12
- 8 ГБ RAM
- 15 ГБ свободного места на диске (модель + зависимости)
- Windows 10/11, Linux (Ubuntu 20.04+), macOS 11+
- Python 3.12
- 16 ГБ RAM
- NVIDIA GPU с 6+ ГБ VRAM (опционально, для ускорения)
- CUDA 11.8+ и cuDNN 8.6+ (для GPU с TensorFlow 2.20.0)
git clone <repository-url>
cd segmentation-buildingsWindows:
python -m venv venv
venv\Scripts\activateLinux/macOS:
python3.12 -m venv venv
source venv/bin/activatepip install --upgrade pip
pip install -r requirements.txtУбедитесь, что обученная модель находится в директории models/:
models/
└── best_segmentation_model.h5 (~280 МБ)
Терминал 1 — Backend (FastAPI):
uvicorn main:app --host 0.0.0.0 --port 8000 --reloadТерминал 2 — Frontend (Streamlit):
streamlit run app.py --server.port 8501- Frontend: http://localhost:8501
- API Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
segmentation-buildings/
├── app.py # Frontend (Streamlit)
├── main.py # Backend API (FastAPI)
├── config.py # Конфигурация
├── requirements.txt # Зависимости Python
├── models/ # Обученные модели
│ ├── best_segmentation_model.h5
│ ├── training_history.csv
│ ├── training_plots.png
│ ├── validation_results.png
│ └── confusion_matrix.png
├── utils/ # Утилиты
│ ├── image_processing.py # Обработка изображений
│ ├── model_loader.py # Загрузка модели и генераторы
│ ├── prediction.py # Функции потерь и метрики
│ └── window.py # Обработка больших изображений
├── data/ # Данные (опционально)
│ └── patches/
│ ├── Images/
│ └── Labels/
└── notebooks/ # Jupyter notebooks
└── segmentation_buildings.ipynb
GET /Ответ:
{
"сообщение": "API модели сегментации работает"
}POST /predict/Параметры:
file(required) — изображение (JPEG, PNG, TIFF)
Ограничения:
- Максимальный размер: 4096×4096 пикселей
Пример запроса (cURL):
curl -X POST "http://localhost:8000/predict/" \
-H "accept: image/png" \
-H "Content-Type: multipart/form-data" \
-F "file=@aerial_image.jpg" \
--output result_segmentation.pngПример запроса (Python):
import requests
from PIL import Image
import io
with open('aerial_image.jpg', 'rb') as f:
files = {'file': ('aerial_image.jpg', f, 'image/jpeg')}
response = requests.post('http://localhost:8000/predict/', files=files)
if response.status_code == 200:
result = Image.open(io.BytesIO(response.content))
result.save('result_segmentation.png')Ответ:
- Content-Type:
image/png - Размер: 256×256 пикселей
- Формат: PNG с цветовой маской
Цветовая схема:
- Белый
#FFFFFF— дороги - Синий
#0000FF— здания - Голубой
#00FFFF— низкая растительность - Зелёный
#00FF00— деревья - Жёлтый
#FFFF00— автомобили - Красный
#FF0000— прочее
Архитектура: U-Net с ResNet34 энкодером (ImageNet weights)
Параметры:
- Всего параметров: 24.4 млн
- Размер модели: 280 МБ
- Входное разрешение: 256×256×3
- Выходные классы: 6
Качество на валидационной выборке:
- IoU Score: 71.56%
- F1-Score: 82.73%
- Accuracy: 87.22%
- Jaccard Coefficient: 70.05%
Качество по классам (Accuracy):
- Roads: 92%
- Buildings: 97% ⭐
- Low vegetation: 86%
- Trees: 96%
- Cars: 99% ⭐
- Clutter: 97%
Производительность:
- Время обработки: ~250-450 мс (GPU Tesla T4)
- Пропускная способность: ~180 запросов/минуту (4 workers)
Backend (main.py):
- Загрузка модели при старте
- Валидация входных данных
- Предобработка изображений
- Инференс модели
- Постобработка и возврат результата
Frontend (app.py):
- Загрузка файлов (drag-and-drop)
- Отправка запросов к API
- Визуализация результатов
- Экспорт результатов (download)
Утилиты (utils/):
image_processing.py— загрузка, конвертация, цветовое кодированиеmodel_loader.py— генераторы данных, препроцессингprediction.py— функции потерь, метрики, веса классовwindow.py— обработка больших изображений (sliding window)
# Backend
uvicorn main:app --reload
# Frontend
streamlit run app.py# Backend с несколькими workers
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
# Frontend в headless режиме
streamlit run app.py --server.headless trueОбучение модели выполнено в Google Colab (notebook: notebooks/segmentation_buildings.ipynb)
Ключевые особенности:
- Dataset: Potsdam (2400 патчей, train/val 80/20)
- Augmentation: horizontal flip, vertical flip
- Batch size: 16
- Epochs: 30 (с Early Stopping)
- Optimizer: Adam (lr=5e-5, weight decay=1e-5)
- Loss: Weighted Categorical Crossentropy (для борьбы с дисбалансом классов)
- Callbacks: ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
Веса классов (для борьбы с дисбалансом):
- Roads: 0.582
- Buildings: 0.610
- Low vegetation: 0.699
- Trees: 1.321
- Cars: 9.260 (редкий класс, вес увеличен в 15.9×)
- Clutter: 2.884
# Health check
curl http://localhost:8000/
# Тестовая сегментация
curl -X POST "http://localhost:8000/predict/" \
-F "file=@test_image.jpg" \
--output test_result.pngfrom keras.models import load_model
from utils.prediction import jacard_coef, weighted_loss
model = load_model(
'models/best_segmentation_model.h5',
custom_objects={
'jacard_coef': jacard_coef,
'loss': weighted_loss
}
)
print(model.summary())Этот проект разработан в рамках итоговой аттестационной работы.
Статус проекта: ✅ Готов к использованию
Последнее обновление: 2025


