How to separate spliced(photoshopped) part from the rest of the spliced image?

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 cv2.medianBlur(). 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 connectedComponentsWithStats().

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 threshold function?

• Where did you get the third image from? Is this a ground truth from a given dataset or did you manually generate it? Also, must you generate a border map for the spliced region or is a binary classification of spliced\not spliced is enough? – havakok Apr 14 at 13:28