Используйте изображение в качестве ядра свертки - PullRequest
0 голосов
/ 29 октября 2018

В настоящее время я пытаюсь реализовать какой-то результат этой статьи , опубликованной Google, о том, как удалять водяные знаки с изображений. Я создал около 80 изображений со своим собственным водяным знаком (шрифт и линии пересечения над всем изображением), и я могу определять края с помощью фильтра Лапласа.

Моя проблема в том, что краев недостаточно, чтобы удалить водяной знак с изображения. Когда линии шире, чем 1 пиксель, края оставляют промежуток между ними. В документе говорится следующее:

В частности, для данного изображения с водяным знаком мы получаем подробную карту краев (используя детектор краев Canny) и вычисляем его евклидово преобразование расстояния, которое затем сворачивается с краями водяного знака (отраженными по горизонтали и вертикали), чтобы получить расстояние Chamfer от каждого пикселя до ближайший край. Наконец, позиция водяного знака принимается за пиксель с минимальным расстоянием на карте.

Я могу получить преобразование расстояния с помощью следующего кода:

### Detect water mark edges
imgs = glob.glob("images/*.jpg")
mean = np.zeros((1200, 1600))

for i, filename in enumerate(imgs):
    img = cv2.imread(filename,0)
    mean += cv2.Laplacian(img,cv2.CV_64F,ksize=3)

mean /= len(imgs)

#### Edge map & distance transform
img = cv2.imread("images/1.jpg", 0)

can = cv2.Canny(img, 100, 200)
dist = cv2.distanceTransform(can, cv2.DIST_L2, 3)

Но как мне теперь сделать свертку? Каким должно быть мое ядро ​​для этого? Линии моего водяного знака пересекают всю картинку, поэтому изображение края водяного знака имеет тот же размер, что и мое исходное изображение.

РЕДАКТИРОВАТЬ на основе @Cris Luengo ответа:

_, mean = cv2.threshold(mean, 64, 255, cv2.THRESH_BINARY)

meanFFT = np.fft.fft2(mean)
distFFT = np.fft.fft2(dist)

conj = np.conjugate(meanFFT)
res = distFFT * meanFFT

cv2.imwrite('watermark.png', np.fft.ifft(res).real)

1 Ответ

0 голосов
/ 29 октября 2018

Цитата из бумаги, которую вы даете, гласит: «которая затем свернута с краями водяного знака (перевернутыми по горизонтали и вертикали)».

Свертка с изображением, перевернутым по горизонтали и вертикали, является взаимной корреляцией с этим изображением. Таким образом, здесь мы вычисляем взаимную корреляцию преобразования расстояний краев изображения с краями водяного знака. Сдвиг, для которого взаимная корреляция минимальна, - это сдвиг, для которого края водяного знака лучше всего соответствуют краям изображения.

Края водяного знака получаются с помощью Canny, точно так же, как вы получаете края изображения.

Чтобы вычислить взаимную корреляцию, используйте домен Фурье:

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

  2. Вычислить БПФ обоих.

  3. Вычислить комплексное сопряжение БПФ изображения водяного знака (это соответствует переворачиванию изображения по вертикали и горизонтали в пространственной области).

  4. Умножить два

  5. Вычислить обратное преобразование и обрезать области, которые соответствуют заполнению, добавленному к изображению с преобразованием расстояния (если есть).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...