[英]How to separate the photoshopped part from the rest of the image if the original image is given?
我正在做一个项目来检测拼接(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 秒!
[我现在没有在我的计算机上安装 OpenCV,所以在 MATLAB 中查看您的图像。 下面的 Python 代码未经测试。]
因为您的图像是相同的,除非进行了有目的的更改(没有考虑缩放或平移),所以可以简单地减去两个图像并查看差异:
res = cv2.absdiff(image,thresh)
如果您显示此内容(带有一些对比度拉伸),您将看到:
正如你所看到的,至少有一个通道在“拼接”区域有很大的差异,在它的外面是一些非常轻的点,由有损压缩引起。
让我们对每个像素取 R、G、B 的最大值:
res = np.amax(res, axis=2) # (I think OpenCV stores the channels in the 3rd dimension?)
我发现大多数压缩伪像都低于 15,所以让我们设置阈值:
res = res > 15
最后,应用你的cv2.medianBlur()
去除最后的噪音。 您也可以尝试在阈值之前应用GaussianBlur()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.