Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Отчёт

Скрипт превращает изображение в seamless текстуру, которую можно тайлить любое число раз ($2×2$, $5×5$, $10×10$, …) без видимых стыков, без неровностей, без обрезанных досок и с одинаковым размером всех досок/плиток на каждом стыке тайлов. Качество выходного изображения идентично входному.

Задача

Вход: 4 изображения — images/main.png (основное) и images/01.png, images/02.png, images/03.png (для проверки). Для каждого нужно получить seamless текстуру. После тайлинга все внутренние доски/плитки должны сохранять одинаковый размер (особенно при переходе одного тайла в другой), без стыков, неровностей и обрезанных досок. Разрешение/соотношение сторон выходного изображения может отличаться от входного, но качество текстуры должно быть не хуже входного.

Результаты

Изображение Узор Результат текстуры 3x3
main.png каменная сетка Отличный (нет стыков, неровностей, обрезанных плит; одинаковый размер плиток)
01.png паркет «ёлочка» Хороший, но требует небольших доработок (есть малозаметные стыки при переходе одного тайла в другой, но одинаковый размер плиток)
02.png светлые деревянные доски Отличный (нет стыков, неровностей, обрезанных досок; одинаковый размер досок)
03.png тёмные деревянные доски Отличный (нет стыков, неровностей, обрезанных досок; одинаковый размер досок)

Полноразмерные результаты в results/: *_seamless.png и *_tiled_3x3.png. Разметка модели в marked/.

Рассмотренные методы

Метод Seamless? Одинаковый размер досок / нет обрезки Качество в сравнении с оригиналом Универсальность
Простая обрезка и зацикливание нет случайная обрезка режет доски = оригинал да
Зеркальное отображение (отражение) да разный размер, нет обрезки (ещё минус: видна симметрия) = оригинал да
Периодическая обрезка + растушёвка не всегда (шов может попасть в середину тайла) гарантировано алгоритмом = оригинал да
Генеративный SD / Нейронные сети да разный размер досок могут быть галлюцинации, качество может быть хуже да
Детекция швов (Оцу) + обрезка по шву, растушёвка / min-cut / зеркало да да = оригинал нет — ветвление методов и пороги, подогнанные под конкретные картинки
Offset + перерисовывание креста швов через нейронную сеть да да модель иногда галлюцинирует да
Разметка seamless текстуры через нейронную сеть + детерминированная сборка (выбран) да да = оригинал да

Выбранный метод — разметка seamless текстуры через нейронную сеть + детерминированная сборка

Ключевая идея. У регулярного пола узор повторяется: на фото есть группа целых плиток/досок, копии которой, приложенные друг к другу со сдвигом, выстилают весь пол. Если найти такую группу, seamless-текстура собирается из реальных пикселей снимка чисто геометрически, а все разрезы проходят по межплиточным швам (ни одна плитка/доска не режется). Нейронная сеть обводит такую группу красным контуром на фото, а все остальное выполняется детерминированным алгоритмом для обработки изображений.

Pipeline (main.py):

  1. Разметка (ensure_markedgenerate_marked). Если файла marked/<имя>.jpg ещё нет, модель (GEMINI_IMAGE_MODEL из .env) получает фото и рисует поверх него красный контур вокруг подходящей группы плиток. Модель может ошибаться, поэтому генерируется несколько вариантов, и каждый проверяется численно (score_marked): действительно ли обведённая область повторяется по фото со сдвигами, аккуратно ли контур обведён по швам, компактная ли получается текстура. Сохраняется лучший вариант; если все негодны, генерация повторяется (до двух раз). Готовая разметка кэшируется — повторные запуски не тратят API.
  2. Извлечение контура (extract_masks, align_masks). Красная линия находится по цвету, замыкается и заливается — получается маска обведённой области. Разметка — это перерисованная моделью копия фото (возможно, чуть сдвинутая), поэтому маска совмещается с оригиналом по фазовой корреляции.
  3. Векторы повторения (lattice_pairs). Дальше нужно узнать, на какие сдвиги смещать область, чтобы её копии сошлись краями. У правильно обведённой группы противоположные края контура лежат на «одинаковых» швах: если сдвинуть контур на шаг узора, он совпадёт сам с собой. Такие сдвиги ищутся автокорреляцией контура — её сильные пики и есть кандидаты в пару векторов повторения. Ложные кандидаты (случайные частичные совпадения) отсекаются.
  4. Выравнивание наклона (estimate_theta, refine_theta). Пол почти всегда снят на доли градуса неровно, из-за чего «горизонтальный» сдвиг чуть уводит вниз. Угол наклона вычисляется прямо из найденных векторов и снимается одним поворотом картинки (для ровных снимков — нулевым).
  5. Прямоугольная ячейка (axis_cell, coset_shifts). Для np.tile нужен прямоугольник, который повторяется строго вправо и вниз, а найденные сдвиги могут быть «косыми». Тогда из целочисленных комбинаций сдвигов строится прямоугольник побольше, в котором укладывается ровно целое число копий области (например, 2 или 5 со смещением друг относительно друга).
  6. Выравнивание освещения (flatten_lighting). Из фото вычитается плавный градиент яркости. Без этого даже идеально сшитая текстура тайлится «полосами»: каждый тайл чуть темнее с одного края.
  7. Сборка (assemble). Пиксели области раскладываются по прямоугольной ячейке во всех положенных копиях; то, что выходит за край ячейки, продолжается с противоположного края. Сборка «мягкая»: контур модели не идеален, поэтому вокруг области берётся запас до 64 px, и на стыках копии плавно перетекают друг в друга (вес пикселя быстро падает с удалением от «своей» области). Щели от неточной обводки заполняются пикселями пришовной зоны, нахлёсты решаются в пользу ближайшей копии. Финальная проверка: если копии не покрыли ячейку целиком, сдвиги выбраны неверно — кандидат отклоняется.

Результат тайлится по построению: границы тайла и все внутренние разрезы идут по межплиточным швам, выбранным моделью, а доски/плитки сохраняют реальный размер. np.tile даёт проверочные изображения N×N.

Сильные стороны

  • Качество = вход: текстура состоит из реальных пикселей фотографии; генерация нигде не подменяет контент (модель только рисует контур).
  • Геометрия гарантирована: разрезы и границы тайла лежат на межплиточных швах, выбранных по узору; доски не режутся, размеры не меняются.
  • End-to-end pipeline, без ветвления по типу узора и подогнанных порогов: все изображения проходят через одни и те же шаги.
  • Самопроверка: каждый кандидат разметки проходит численную валидацию (решётка, площадь, покрытие сборки); негодные отбрасываются и перегенерируются автоматически.
  • Экономно: разметка кэшируется в marked/; повторные запуски полностью локальны и детерминированы.

Слабые стороны

  • Нужен API-ключ (Gemini) при первом прогоне или перегенерации разметки; сама разметка недетерминирована — от запуска к запуску модель может выбрать другую группу (кэш это скрывает).
  • «Эффект обоев»: ячейка повторяет один и тот же контент; чем меньше выбранная группа, тем заметнее повторение.
  • Результат недетерминирован из-за выделения контура

Запуск

cp .env.example .env            # вписать GEMINI_API_KEY (ключ Gemini API)
uv sync
uv run main.py                  # создаёт results/ для всех четырёх изображений

Готовая разметка лежит в marked/, поэтому запуск по умолчанию не делает обращений к API. Чтобы перегенерировать разметку для картинки — удалите marked/<имя>.jpg и запустите снова (uv run main.py). Модель задаётся переменной GEMINI_IMAGE_MODEL (по умолчанию models/gemini-3-pro-image).

Структура проекта

.
├── images/                 # входные изображения (main, 01, 02, 03)
├── marked/                 # разметка модели (красный контур)
├── results/                # seamless текстуры + тайтлинг 3x3
├── main.py                 # весь pipeline
└── pyproject.toml          # зависимости

About

Скрипт превращает изображение в seamless текстуру, которую можно тайлить любое число раз (2×2, 5×5, 10×10, …) без видимых стыков, без неровностей, без обрезанных досок и с одинаковым размером всех досок/плиток на каждом стыке тайлов. Качество выходного изображения идентично входному.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages