Reputation: 1320
I am trying to implement the Pikachu image on the hoarding board using warpPerspective transformation. The output doesn't have smooth edges it has dotted points instead.
import cv2
import numpy as np
image = cv2.imread("base_img.jpg")
h_base, w_base = image.shape[0], image.shape[1]
white_subject = np.ones((480,640,3),dtype="uint8")*255
h_white, w_white = white_subject.shape[:2]
subject = cv2.imread('subject.jpg')
h_sub, w_sub = subject.shape[:2]
pts2 = np.float32([[109,186],[455,67],[480,248],[90,349]])
pts3 = np.float32([[0, 0], [w_white, 0], [w_white, h_white], [0, h_white]])
transformation_matrix_white = cv2.getPerspectiveTransform(pts3, pts2)
mask = cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base))
image[mask==255] = 0
pts3 = np.float32([[0, 0], [w_sub, 0], [w_sub, h_sub], [0, h_sub]])
transformation_matrix = cv2.getPerspectiveTransform(pts3, pts2)
warped_image = cv2.warpPerspective(subject, transformation_matrix, (w_base, h_base))
Hoarding board image
Pikachu Image
Output Image
Pattern Image
Please help me out in getting the output without the dotted point at the edges.
Upvotes: 4
Views: 1699
Reputation: 53071
Here is one way to do the anti-aliased composite in Python/OpenCV. Note that I use the background color of the overlay image in the borderVal constant in warpPerspective to set the background color, since it is a constant. I also blur the mask before doing the composite.
Background Image:
Overlay Image:
import cv2
import numpy as np
import skimage.exposure
image = cv2.imread("base_img.jpg")
h_base, w_base = image.shape[0], image.shape[1]
white_subject = np.ones((480,640,3),dtype="uint8")*255
h_white, w_white = white_subject.shape[:2]
subject = cv2.imread('subject.jpg')
h_sub, w_sub = subject.shape[:2]
# get background color from first pixel at (0,0) and its BGR components
yellow = subject[0:1, 0:1][0][0]
blue = yellow[0]
green = yellow[1]
red = yellow[2]
print(yellow)
print(blue, green, red)
pts2 = np.float32([[109,186],[455,67],[480,248],[90,349]])
pts3 = np.float32([[0, 0], [w_white, 0], [w_white, h_white], [0, h_white]])
transformation_matrix_white = cv2.getPerspectiveTransform(pts3, pts2)
mask = cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base))
pts3 = np.float32([[0, 0], [w_sub, 0], [w_sub, h_sub], [0, h_sub]])
transformation_matrix = cv2.getPerspectiveTransform(pts3, pts2)
# do warping with borderVal = background color
warped_image = cv2.warpPerspective(subject, transformation_matrix, (w_base, h_base), borderMode = cv2.BORDER_CONSTANT, borderValue=(int(blue),int(green),int(red)))
# anti-alias mask
mask = cv2.GaussianBlur(mask, (0,0), sigmaX=2, sigmaY=2, borderType = cv2.BORDER_DEFAULT)
mask = skimage.exposure.rescale_intensity(mask, in_range=(0,128), out_range=(0,255))
# convert mask to float in range 0 to 1
mask = mask.astype(np.float64)/255
# composite warped image over base and convert back to uint8
result = (warped_image * mask + image * (1 - mask))
result = result.clip(0,255).astype(np.uint8)
# save results
cv2.imwrite('warped_mask.png',(255*mask).clip(0,255).astype(np.uint8))
cv2.imwrite('warped_image.png',warped_image)
cv2.imwrite('warped_image_over_background.png',result)
cv2.imshow("mask", mask)
cv2.imshow("warped_image", warped_image)
cv2.imshow("result", result)
cv2.waitKey(0)
Anti-aliased Warped Mask:
Warped Image:
Resulting Composite:
Upvotes: 7