Как Python помогает восстанавливать древние фрески: алгоритмы цифровой реставрации. GAN.. GAN. inpainting.. GAN. inpainting. opencv.. GAN. inpainting. opencv. python.. GAN. inpainting. opencv. python. древние фрески.. GAN. inpainting. opencv. python. древние фрески. культура.. GAN. inpainting. opencv. python. древние фрески. культура. машинное зрение.. GAN. inpainting. opencv. python. древние фрески. культура. машинное зрение. нейросети.. GAN. inpainting. opencv. python. древние фрески. культура. машинное зрение. нейросети. цифровая реставрация.. GAN. inpainting. opencv. python. древние фрески. культура. машинное зрение. нейросети. цифровая реставрация. шум.

Цифровая реставрация культурного наследия — не то, о чём часто пишут на IT-форумах. Но Python, OpenCV и немного безумной любви к истории могут буквально вдохнуть жизнь в древние фрески. В этой статье — живая техническая история о том, как написать свои алгоритмы цифровой реставрации, использовать машинное зрение и нейросети для восстановления утраченного и, возможно, спасти кусочек человечества от забвения.

Как Python помогает восстанавливать древние фрески: алгоритмы цифровой реставрации - 1

Сначала было пятно. Вернее, сотни пятен на стенах старинного монастыря в окрестностях Перуджи. За несколько веков солнце, влага и человеческое невежество сделали своё дело: лицо святого Петра превратилось в серо-красную кашу, ангелы выгорели до неузнаваемости, а контуры зданий исчезли, как память после тяжёлой пятницы.

С тех пор как я впервые попал в архив Института цифровой реставрации, у меня свербело в мозгу одно: а можно ли доверить восстановление этих изображений алгоритму? Не просто научить его «дорисовывать», а сделать это осмысленно, с уважением к автору и эпохе. Ответ: можно, но придётся попотеть.


1. Сканирование и подготовка изображения

Всё начинается с цифры. Мы получаем фреску в виде многомегапиксельного TIFF-файла. Иногда — даже с LIDAR-данными, если повезло с финансированием. Для работы используется OpenCV и PIL. Первый шаг — привести всё это безобразие в читаемый вид.

# Язык: Python 3
from PIL import Image
import cv2
import numpy as np

# Загружаем изображение
image_path = 'damaged_fresco.tiff'
pil_image = Image.open(image_path).convert('RGB')
image = np.array(pil_image)

# Уменьшаем размер для предпросмотра
preview = cv2.resize(image, (1024, 1024))
cv2.imshow("Fresco Preview", preview)
cv2.waitKey(0)
cv2.destroyAllWindows()

На этом этапе фреска уже выглядит не как грязная стена, а как загадка. Самое время заняться шумом.


2. Удаление шума и артефактов времени

Пятна, трещины, грибок, остатки штукатурки — всё это нужно убрать, но осторожно. Мы не хотим уничтожить след кисти мастера XIV века. Поэтому никакой агрессивной фильтрации. Только bilateral filtering и ручная маска повреждений.

# Фильтрация с сохранением краёв
filtered = cv2.bilateralFilter(image, d=9, sigmaColor=75, sigmaSpace=75)

# Простой способ маскировать пятна вручную (пока без ML)
mask = cv2.inRange(filtered, (0, 0, 0), (50, 50, 50))
cv2.imshow("Damage Mask", mask)
cv2.waitKey(0)

На практике приходится постоянно настраивать параметры вручную. Один из «забавных» случаев — когда трещина пересекала радужку глаза святого, и алгоритм упрямо её удалял, оставляя героя слепым.


3. Inpainting: цифровое восстановление утраченного

Тут начинается магия. OpenCV предоставляет две классические функции для inpainting: cv2.INPAINT_TELEA и cv2.INPAINT_NS. Первая работает быстрее, вторая — мягче. В большинстве случаев Telea даёт более «живую» текстуру, что особенно важно в живописи.

inpainted = cv2.inpaint(filtered, mask, 3, cv2.INPAINT_TELEA)
cv2.imshow("Restored Fresco", inpainted)
cv2.waitKey(0)

Это уже почти искусство: иногда результат получается настолько красивым, что хочется подписать — restored by algorithmic brush of 2025.


4. Углубляемся: GAN для генерации утраченных фрагментов

Для крупных утрат (например, полностью отсутствующего лица) одного Telea недостаточно. Мы использовали генеративно-состязательные сети (GAN), обученные на выборке фресок того же периода.

Модель обучалась на 50 000 патчах из разных музеев Европы. Использовали подход DeepFill v2 с модифицированной encoder-частью.

# Пример использования обученной модели (упрощённый псевдокод)
import torch
from model import InpaintingModel

model = InpaintingModel()
model.load_state_dict(torch.load("gan_fresco_model.pth"))
model.eval()

input_image = preprocess_for_model(inpainted)
output = model(input_image)
restored_final = postprocess(output)

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


5. Контроль качества: оценка результата

Вот где всё становится субъективным. Мы не можем сравнивать с оригиналом — его нет. Но можем считать метрики по соседним участкам: SSIM, perceptual loss, цветовую согласованность.

from skimage.metrics import structural_similarity as ssim

ssim_value = ssim(original_crop, restored_crop, multichannel=True)
print(f"SSIM: {ssim_value:.3f}")

И всё равно — финальное слово за искусствоведом. Иногда он говорит: «Хм, нос Петра получился подозрительно похожим на Джастина Бибера». Тогда откатываем и ищем другой подход.


Заключение

Алгоритмы не заменят художника. Но они становятся его соавторами. Python, OpenCV, PyTorch и немного человеческой одержимости — вот инструменты цифрового Рубенса. Мы не создаём, мы воскрешаем. И пусть наш код когда-нибудь тоже кто-то найдёт и отреставрирует.

Автор: egor_kulik

Источник

Rambler's Top100