【发布时间】:2019-04-14 04:16:55
【问题描述】:
我正在开展一个检测拼接(photoshopped)图像的项目,并希望在伪造区域的边界处使用 128x128 补丁。我有真实的背景图片和伪造的。
如果我只是发现像素值的差异并应用阈值来获取二进制图像,我会得到很多噪声(白色部分中的小黑块,反之亦然),cv2.medianBlur() 无法有效去除这些噪声.
我假设这是因为拼接前后图像的压缩系数不同。此外,拼接部分中的某些像素与 auth 中的相应像素相似。图片。
所以我替换了普通的 cv2.threshold() 函数,该函数将像素的 4 连接邻居的值相加,并将其与阈值进行比较。
这是我的阈值函数:
def threshold(image,thresh):
b,g,r= cv2.split(image)
res=np.zeros(b.shape,dtype=np.uint8)
#Not considering boundary pixels for the binary image
for i in range(1,b.shape[0]-1):
for j in range(1,b.shape[1]-1):
sumb = b[i][j] + b[i+1][j] + b[i-1][j] + b[i][j+1] + b[i][j-1]
sumg = g[i][j] + g[i+1][j] + g[i-1][j] + g[i][j+1] + g[i][j-1]
sumr = r[i][j] + r[i+1][j] + r[i-1][j] + r[i][j+1] + r[i][j-1]
res[i][j]=255 if sumb<=5*thresh or sumg<=5*thresh or sumr<=5*thresh else 0
res=res[1:-1,1:-1]
res=cv2.copyMakeBorder(res,1,1,1,1,cv2.BORDER_REFLECT_101)
return res
这确实提供了更好的结果,但不如预期的那么好。
例如,这是一张真实的图片:
这是拼接好的图片:
这是阈值图像(我发现thresh=2 是最佳值):
我尝试通过使用connectedComponentsWithStats() 移除具有少量白色像素的组件来移除小组件。
这些是移除小的连接组件后的边框:
而预期的图像是:
我可以增加每个组件所需的最小像素数,但我的数据集中有些图像的伪造部分很小。
我怎样才能得到比这更好的结果?
另外,是否可以优化我的threshold 功能?现在处理一张图像至少需要 2 秒!
【问题讨论】:
-
Neal Krawetz 博士关于照片伪造的有趣论文在这里...hackerfactor.com/papers/bh-usa-07-krawetz-wp.pdf
-
JPEG(即有损/引入噪声的图像压缩可能会使这变得更加困难。
标签: python numpy opencv image-processing