Давайте посмотрим на такой кадр из фильма:

Image with mic

Снизу слева заметен микрофон, что если мы хотим его удалить?

Давайте для начала создадим картинку-маску которая сохранит наше мнение о том какие пиксели надо удалить.

1) Дома скачайте и установите paint.net и обязательно создайте свою картинку-маску для второго примера в репозитории, на уроке же воспользуйтесь моей маской для микрофона и других тестов (маски уже есть в репозитории).

2) Откройте картинку 2_original.jpg в paint.net и добавьте слой поверх картинки - там мы будем рисовать нашу маску:

Add layer

3) Теперь аккуратно белым карандашом очертите контур вокруг микрофона:

Add layer

4) Теперь залейте белым цветом весь микрофон:

Fill mic with white

5) Оригинальная картинка нам больше не нужна - уберите ее слой и залейте все остальное черным цветом:

Fill black around mic

6) Сохраните получившуюся черно-белую картинку через File->Save As->->OK->Flatten (обязательно укажите название файла и его расширение):

Fill black around mic

7) Проверьте что все в порядке с картинками в папке репозитория, что маска идеально накладывается на микрофон (еще можно открыть картинку и нажимая стрелочки влево-вправо, или PageUp-PageDown помигать между картинками):

Fill black around mic

Алгоритм

1) Создаем картинку в которой для каждого пикселя храним смещение - указание откуда мы берем донора для ретуширования, откуда берем заплатку. Изначально смещение (dx=0, dy=0) означает что донор мы сами. Но в отмаскированных пикселях надо найти кого-то другого неотмаскированного из другой части картинки.

Shifts

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