Reputation: 7117
I'm currently trying to implement some result of this paper published by Google on how to remove watermarks from images. I created around 80 pictures with my own watermark (font and crossing lines above the whole picture) and I'm able to detect the edges with the Laplacian filter.
My problem is that the edges are not enough to remove the watermark from the image. When the lines are wider than 1 pixel the edges leave a gap in between. The paper says the following:
Specifically, for a given watermarked image, we obtain a verbose edge map (using Canny edge detector), and compute its Euclidean distance transform, which is then convolved with the watermark edges (flipped horizontally and vertically) to get the Chamfer distance from each pixel to the closest edge. Lastly, the watermark position is taken to be the pixel with minimum distance in the map.
I can get the distance transform with following code:
### 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)
But how should I do the convolution now? What should be my kernel for this? The lines of my watermark cross the entire picture so the watermark edge image has the same size as my original image.
EDIT based on @Cris Luengo answer:
_, 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)
Upvotes: 0
Views: 324
Reputation: 60444
The quote from the paper that you give says "which is then convolved with the watermark edges (flipped horizontally and vertically)".
A convolution with an image flipped horizontally and vertically is the cross-correlation with that image. Thus, here we are computing the cross-correlation of the distance transform of the edges in the image with the edges in the watermark. The shift for which the cross-correlation is minimal is the shift for which the watermark edges best match the edges in the image.
The watermark edges are obtained using Canny, just like you obtain the edges of the image.
To compute the cross-correlation, use the Fourier domain:
Make sure the two images (distance transform and edges of watermark) are the same size. Pad them with zeros to make their sizes match.
Compute the FFT of both.
Compute the complex conjugate of the FFT of the watermark image (this corresponds to flipping the image vertically and horizontally in the spatial domain).
Multiply the two
Compute the inverse transform, and crop away the regions that correspond to the padding added to the distance transform image (if any).
Upvotes: 1