Skip to content

Repository files navigation

canva-like MVP: PNG/JPEG → editable layers

Локальный экспериментальный декомпозитор постеров и рекламных карточек. На выходе он создаёт versioned JSON scene graph, SVG, отдельные RGBA-объекты и маски, живые текстовые узлы, восстановленный фон и проверочный рендер.

Это уже воспроизводимый MVP, но не полный аналог Canva Magic Layers. Вторая итерация обучена одновременно на простых designs и реалистичных photo/editorial макетах с JPEG, blur, noise и resize degradations. Третья итерация добавляет semantic instance masks для объектов внутри фотографии и аудируемый итеративный selector с явным stop condition.

Четвёртая итерация добавляет overlapping multi-scale inference, мягкий отбор кандидатов без преждевременной остановки и опциональное class-agnostic уточнение SAM. Оно восстанавливает крупные объекты вне уверенного COCO-словаря (например пальму), а мелкие semantic masks больше не теряются из-за общего порога площади.

Пятая итерация заменяет радиальный OpenCV inpainting на двухрежимный background pipeline. Quality использует локальный Big-LaMa TorchScript checkpoint, затем согласует заплатку с окружением по blur и зерну и смешивает её по расширенной halo-safe маске. Нейросетевая структура считается максимум на 1280 px, но исходные пиксели, слои, текстура и итоговый canvas остаются полноразмерными. Fast смешивает локальные Telea и Navier–Stokes и остаётся fallback-режимом без нейросетевого checkpoint.

Шестая итерация добавляет ownership текста и topology-aware instance splitting. Принты внутри объектов, стилизованные заголовки и текст на цветных кнопках больше не проходят через разрушительный OCR-inpaint. Несвязанные объекты внутри одной detector/SAM mask разделяются после разрыва тонких ложных мостов; мелкие дырки от контрастных принтов закрываются без заполнения вероятного neckline.

Седьмая итерация добавляет консервативный portrait matting. Локальный MODNet уточняет только единственный уверенно выбранный слой person; предсказание принимается лишь при сильном согласии с instance mask. Это возвращает тонкие пряди волос, не превращая футболки и групповые сцены в один foreground.

Проверенный результат

Есть два независимых frozen test:

Benchmark Geometry F1 Text F1 Combined F1
v1: 40 простых макетов 0.890 0.942 0.912
v2: 24 realistic photo/editorial, held-out photo + font 0.788 0.783 0.784

На realistic-v2 исходный MVP давал combined F1 0.487; v2 pipeline поднял его до 0.784 (+0.297 absolute), одновременно улучшив v1 с 0.888 до 0.912. Среднее время на Apple M2 Pro CPU: 2.31 с для v1 384×384 и 9.30 с для v2 512×512. Полный realistic CLI-пример занял 8.70 с, создал 6 editable foreground nodes и дал reconstruction MAE 1.64/255. Внешние API во время inference не вызываются.

Semantic-v3 smoke-test отдельно проверяет объекты внутри фотографии: человек и бутылка извлечены как самостоятельные RGBA layers, а пейзаж без foreground objects корректно остановлен на нуле semantic layers. Primary-object label recall на четырёх диагностических cases — 3/3, среднее время semantic detector на CPU — 1.45 с. Это пока smoke-test, не замена real-world gold benchmark.

Подробности: первый MVP и realistic-v2. Диагностика photo objects: iterative semantic MVP. Проверка восстановления фона: background v4. Разбор hard-case с футболками: shirts text ownership. Проверка portrait matting: gated MODNet. Достраивание офисного стола: targeted SAM completion. Очистка alpha футболок и теней: poster shadow ownership.

Контрольная точка проекта

Эти документы являются контрактом следующей итерации. Изменение не считается улучшением только по reconstruction MAE или одному hard-case: оно должно пройти полный UI-path regression set и hide/delete replay без collateral damage.

Воспроизводимый прогон ключевых UI-кейсов:

uv run python scripts/run_regression_suite.py \
  --output experiments/020_regression_runner \
  --background-mode quality

Команда создаёт contact sheet и preview после скрытия каждого слоя. Быстрый subset задаётся через background-mode fast и параметр cases.

Установка

Требования: macOS, Python 3.12, uv, локальный tesseract. Проверенная команда:

brew install tesseract uv
cd ~/programming/my/canva-like
UV_CACHE_DIR="$PWD/.cache/uv" uv sync --python 3.12
.venv/bin/python scripts/download_models.py

Semantic checkpoint Mask R-CNN занимает около 177 MB, SAM — около 358 MB, Big-LaMa — около 196 MB, MODNet — около 26 MB, optional BiRefNet HR-matting — около 444 MB; все хранятся в локальных model caches, а не в git. Без Mask R-CNN система продолжит работать в primitive/text-only режиме. Без SAM останется multi-scale semantic pipeline, а sam_status будет checkpoint_missing. Без Big-LaMa запрос Quality автоматически переключится на Fast и запишет причину fallback в metadata. Без MODNet decomposition продолжит работать с исходной instance alpha, а matting_status будет checkpoint_missing. Загруженный ONNX проверяется по опубликованному SHA-256 перед установкой. BiRefNet pin-ится на конкретную ревизию и проверяется по SHA-256. Сейчас он уточняет только визуально проверенные классы bottle и umbrella; instance mask и masks соседей остаются обязательным gate. Без checkpoint pipeline продолжает работать как раньше. Отключить локально можно через CANVA_LIKE_BIREFNET=0. Переменная CANVA_LIKE_LAMA_MAX_SIDE меняет компромисс скорость/детализация фонового inference; значение по умолчанию — 1280. Переменная CANVA_LIKE_DEVICE задаёт устройство PyTorch: auto (по умолчанию), cpu, cuda или mps. На Apple Silicon локальный GPU-запуск выглядит так:

CANVA_LIKE_DEVICE=mps .venv/bin/canva-like-api

Внешние модели и условия использования

В репозитории нет весов моделей. Базовая установка загружает только публичные checkpoint'ы с проверенной совместимой лицензией. Два дополнительных checkpoint'а не устанавливаются по умолчанию: перед их использованием необходимо самостоятельно проверить и принять условия соответствующего upstream-поставщика.

# Только после самостоятельной проверки условий upstream:
.venv/bin/python scripts/download_models.py --modnet
.venv/bin/python scripts/download_models.py --birefnet

Полная таблица происхождения компонентов, моделей и ограничений — в THIRD_PARTY_NOTICES.md.

Текущая модель лежит в artifacts/proposal_scorer_v2/. Если её нужно пересобрать с нуля:

.venv/bin/python scripts/generate_dataset_v1.py
.venv/bin/python scripts/generate_dataset_v2.py
.venv/bin/python scripts/train_proposal_scorer_v2.py

Локальный web-интерфейс

.venv/bin/canva-like-api

Откройте http://127.0.0.1:8000. В интерфейсе можно загрузить свой PNG/JPEG или выбрать один из realistic-примеров, сравнить оригинал с реконструкцией, скрывать отдельные слои и менять распознанный текст. Вкладка «Редактор» позволяет перетаскивать raster- и text-объекты по очищенному фону; выбранный объект также двигается стрелками (с Shift — по 10 px), а позиции можно сбросить одной кнопкой. Режим «Кандидаты» показывает каждую semantic/primitive mask, score, решение selector и причину accept/reject/stop. Swagger API остаётся доступен на /docs.

CLI

.venv/bin/canva-like decompose input.png output/
.venv/bin/canva-like render output/document.json rerendered.png

По умолчанию работает --engine auto: быстрый pipeline проверяет собственный результат и при явном провале переключается на LayerD. Для фиксированного режима:

.venv/bin/canva-like decompose input.png output/ --engine fast
.venv/bin/canva-like decompose input.png output/ --engine fast --background-mode quality
.venv/bin/canva-like decompose input.png output/ --engine fast --background-mode fast
.venv/bin/canva-like decompose input.png output/ --engine fast --no-semantic
.venv/bin/canva-like decompose input.png output/ --engine layerd --max-iterations 3

Результат:

output/
├── document.json
├── document.svg
├── rendered.png
├── verification.json
├── source.png
└── assets/
    ├── background.png
    ├── object_001.png
    ├── object_001_mask.png
    └── ...

document.json содержит bbox, z-order, confidence, роль слоя, тип fitted primitive, ссылку на mask и настоящие TextLayer с распознанным текстом, шрифтом, размером и цветом.

API

.venv/bin/canva-like-api
curl -X POST http://127.0.0.1:8000/v1/decompose \
  -F file=@input.png -F use_ocr=true -o layers.zip

GET /health сообщает готовность модели. POST /v1/decompose принимает PNG/JPEG до 20 MB и до 4096 px по длинной стороне, автоматически уменьшая анализ до 1024 px, и возвращает ZIP со всем bundle. HTTP smoke-test реально выполнен: health 200, decompose 200, ZIP содержит 10 ожидаемых файлов.

Как устроено

  1. Mask R-CNN строит class-aware instance masks людей и предметов внутри фото; OpenCV параллельно строит design candidates из цветовых кластеров, контуров, raw outline/line components и Hough segments в fixed 384 px analysis space.
  2. Random Forest ранжирует 23 геометрических/цветовых признака; semantic score учитывает detector confidence и стабильность alpha. Итеративный selector выбирает следующий полезный слой, отбрасывает дубли/contained masks и сохраняет полный selection trace.
  3. OCR ensemble читает исходник, бинаризации, цветовые сегменты и локальные object crops; строки объединяются в редактируемые TextLayer.
  4. Выбранные маски превращаются в RGBA-слои; для совместимого одиночного person граница уточняется MODNet, после чего освобождённый фон восстанавливает inpainting.
  5. Renderer повторно собирает документ; verifier считает MAE, coverage, confidence, oversegmentation и решает, нужен ли LayerD fallback.

Крупная генеративная модель для обычного запроса не нужна. LayerD остаётся медленным fallback: на исходном CPU benchmark лучший fixed depth 3 дал F1 0.667 при примерно 35.5 с/изображение.

Воспроизведение проверок

.venv/bin/ruff check src scripts tests
.venv/bin/pytest -q
.venv/bin/python scripts/evaluate_mvp.py
.venv/bin/python scripts/evaluate_mvp_v2.py
.venv/bin/python scripts/evaluate_background_v4.py

Сейчас suite: 51 тест. Два regression-теста synthetic-v1 корректно пропускаются в чистом clone, пока не создан исключённый из git датасет; его можно создать через scripts/generate_dataset_v1.py. Realistic-v2 test полностью отделён по исходной фотографии и шрифту. Полные финальные метрики лежат в experiments/012_realistic_v2_final/metrics.json и experiments/013_v1_regression/metrics.json.

Что делать дальше

  • дотянуть realistic-v2 выше 0.8: основной остаток — тонкие decorative rules и мелкий текст после JPEG;
  • собрать замороженный real-world gold set минимум из 100–200 легально используемых макетов;
  • заменить macOS-only font catalogue на поставляемый кроссплатформенный набор;
  • добавить русский OCR и тестовый split;
  • превратить fitted candidates в настоящие SVG primitives с fill/stroke;
  • обучить alpha/matting refiner для теней и полупрозрачности;
  • оценивать delete/move/recolor/replace-text через edit replay, а не только исходную реконструкцию.

Архитектурный roadmap: docs/PLAN.md. Данные и метрики: docs/DATA_AND_EVAL.md.

Лицензия

Исходный код этого репозитория распространяется по Apache License 2.0. Веса моделей, загружаемые во время установки, не являются частью релиза и имеют свои условия. Перед коммерческим использованием проверьте THIRD_PARTY_NOTICES.md.

About

Decompose raster designs into editable layers, text, SVG, and RGBA assets.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages