I'm working on a project to detect spliced images and want 128x128 patches at the boundaries of the forged regions. I have the authentic background image and the spliced(photoshopped) one.
If I simply find difference in pixel values and apply a threshold to get the binary image, I get a lot of noise(small black patches in the white part and vice versa) which doesn't get effectively removed by
I'm assuming that this is because of different compression factors of the images before and after splicing. Also, some pixels in the spliced part are similar to the corresponding pixels in the auth. image.
So I replace the normal
cv2.threshold() function which adds the values of 4-connected neighbours of the pixel and compares that with a threshold value.
This is my threshold function :
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-1): for j in range(1,b.shape-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
This does give better results but not as good as expected.
For example, this is an authentic image :
This is the spliced image :
This is the thresholded image (I found that
thresh=2 was the optimal value) :
I tried to remove small components by removing components with few white pixels using
These are the borders after removing small connected components:
while the expected image is:
I could increase the minimum no. of pixels required for each component but there are images in my dataset where the forged part is small.
How can I get better results than this?
Edit : Also, is it possible to optimize my