我目前正在尝试实现由Google发布的关于如何从图像中删除水印的this paper的某些结果。我用自己的水印(整个图片上方的字体和交叉线)创建了约80张图片,并且能够使用拉普拉斯滤镜检测边缘。
我的问题是边缘不足以去除图像中的水印。当线条宽于1个像素时,边缘之间会留有间隙。文章说:
具体来说, 对于给定的水印图像,我们获得一个详细的边缘图(使用Canny边缘检测器),并计算其欧几里德距离变换,然后将其与水印边缘(水平和垂直翻转)进行卷积,以获取从每个像素到像素的倒角距离。最接近的边缘。最后,将水印位置取为地图中距离最小的像素。
我可以使用以下代码获取距离变换:
### 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)
答案 0 :(得分:1)
您在论文中引述的内容是“然后将其与水印边缘(水平和垂直翻转)进行卷积”。
具有水平和垂直翻转的图像的卷积是与该图像的互相关。因此,这里我们正在计算图像中边缘与水印中边缘的距离变换的互相关。互相关最小的偏移是水印边缘与图像边缘最匹配的偏移。
使用Canny获取水印边缘,就像获取图像的边缘一样。
要计算互相关,请使用傅立叶域:
确保两个图像(距离变换和水印边缘)的大小相同。用零填充它们以使其大小匹配。
计算两者的FFT。
计算水印图像FFT的复共轭(这对应于在空间域中垂直和水平翻转图像)。
将两者相乘
计算逆变换,并裁剪掉与添加到距离变换图像(如果有)上的填充相对应的区域。