Урок 21: ретуширование фотографии (залатывание дыр)
Давайте посмотрим на такой кадр из фильма:
Снизу слева заметен микрофон, что если мы хотим его удалить?
Давайте для начала создадим картинку-маску
которая сохранит наше мнение о том какие пиксели надо удалить
.
1) Дома скачайте и установите paint.net и обязательно создайте свою картинку-маску для второго примера в репозитории, на уроке же воспользуйтесь моей маской для микрофона и других тестов (маски уже есть в репозитории).
2) Откройте картинку 2_original.jpg
в paint.net и добавьте слой поверх картинки - там мы будем рисовать нашу маску:
3) Теперь аккуратно белым карандашом очертите контур вокруг микрофона:
4) Теперь залейте белым цветом весь микрофон:
5) Оригинальная картинка нам больше не нужна - уберите ее слой и залейте все остальное черным цветом:
6) Сохраните получившуюся черно-белую картинку через File->Save As->->OK->Flatten
(обязательно укажите название файла и его расширение):
7) Проверьте что все в порядке с картинками в папке репозитория, что маска идеально накладывается на микрофон (еще можно открыть картинку и нажимая стрелочки влево-вправо
, или PageUp-PageDown
помигать между картинками):
Алгоритм
1) Создаем картинку в которой для каждого пикселя храним смещение - указание откуда мы берем донора для ретуширования, откуда берем заплатку. Изначально смещение (dx=0, dy=0)
означает что донор мы сами. Но в отмаскированных пикселях надо найти кого-то другого неотмаскированного из другой части картинки.
2) Картинка хранящая такие смещения:
-
будет хранить два целых числа - относительно смещение по оси x (
dx
, т.е. смещение номера колонки) и относительное смещение по оси y (dy
, т.е. смещение номера строчки) -
тип этой картинки -
CV_32SC2
-
заполнена она изначально парами из нулей -
cv::Scalar(0, 0)
-
а какого она разрешения?
-
каждый элемент в такой картинке смещений обладает типом не
cv::Vec3b
как было сRGB-картинками
, аcv::Vec2i
(i=int) -
поэтому чтобы извлечь какой-то элемент надо написать:
cv::Vec2i dxy = shifts.at<cv::Vec2i>(j, i);
3) Теперь давайте просто много раз генерировать случайную гипотезу-смещение, и сравнивать ее качество с качеством смещения которое мы уже сохранили в этом пикселе.
4) Как оценивать качество? Приложим окрестность вокруг пикселя к окрестности вокруг пикселя на который указывает смещение.
5) В коде приведет какой-то набросок кода который может подсказать общую структуру кода.