How can shifted pixels be adjusted to same position after doing cv.filter2D

Viewed 22

In a video frame, I am trying to sharpen the part where human face is visible, then imposing it on the background. But after using the sharpening filter i.e. [[-1,-1,-1],[-1,9,-1],[-1,-1,-1]] on the image, the pixels get shifted and on superimposing the face on the background, image gets pixelated. Here is a sample input and output image

# using canny edge detection to get the face pixels.    
edges = cv2.Canny(input_image, 10, 200)
edges = cv2.dilate(edges, None)
edges = cv2.erode(edges, None)
contours,_ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
mask = np.zeros(edges.shape)
cv2.fillConvexPoly(mask, max_contour[0], (255))
mask = cv2.dilate(mask, None, iterations=MASK_DILATE_ITER)
mask = cv2.erode(mask, None, iterations=MASK_ERODE_ITER)
mask = cv2.GaussianBlur(mask, (BLUR, BLUR), 0)
mask_stack = np.dstack([mask]*3) 

# sharpening the input_image
kernel = np.ones((3,3),np.float32)*-1
kernel[1][1] = 9
sharp = cv2.filter2D(input_image,-1,kernel)

# using mask_stack to impose filtered pixels.
final_img = (((1-mask_stack) * input_image)+((mask_stack) * sharp) )

How can this issue be

1 Answers

You need to use the ddepth argument to cv2.filter2D to choose a signed type for the output image. For example,

sharp = cv2.filter2D(input_image, CV_64F, kernel)

When ddepth = -1 as you do, then the output image will have the same type as the input image, and negative values will roll over and become large values (bright colors). This is what you see. I don't think there's a shift or pixelation occurring.

Next, after computing the final_img, you'll have to properly clamp the values and cast back to uint8:

final_img = (((1-mask_stack) * input_image)+((mask_stack) * sharp) )
final_img = np.clip(final_img, 0, 255).astype(np.uint8)
Related