Урок 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) В коде приведет какой-то набросок кода который может подсказать общую структуру кода.