def warp_image(img, triangulation, base_points, coord):
"""
Realize the mesh warping phase
triangulation is the Delaunay triangulation of the base points
base_points are the coordinates of the landmark poitns of the reference image
code inspired from http://www.learnopencv.com/warp-one-triangle-to-another-using-opencv-c-python/
"""
all_points, coordinates = preprocess_image_before_triangulation(img)
img_out = 255 * np.ones(img.shape, dtype=img.dtype)
for t in triangulation:
# triangles to map one another
src_tri = np.array([[all_points[x][0], all_points[x][1]] for x in t]).astype(np.float32)
dest_tri = np.array([[base_points[x][0], base_points[x][1]] for x in t]).astype(np.float32)
# bounding boxes
src_rect = cv2.boundingRect(np.array([src_tri]))
dest_rect = cv2.boundingRect(np.array([dest_tri]))
# crop images
src_crop_tri = np.zeros((3, 2), dtype=np.float32)
dest_crop_tri = np.zeros((3, 2))
for k in range(0, 3):
for dim in range(0, 2):
src_crop_tri[k][dim] = src_tri[k][dim] - src_rect[dim]
dest_crop_tri[k][dim] = dest_tri[k][dim] - dest_rect[dim]
src_crop_img = img[src_rect[1]:src_rect[1] + src_rect[3], src_rect[0]:src_rect[0] + src_rect[2]]
# affine transformation estimation
mat = cv2.getAffineTransform(
np.float32(src_crop_tri),
np.float32(dest_crop_tri)
)
dest_crop_img = cv2.warpAffine(
src_crop_img,
mat,
(dest_rect[2], dest_rect[3]),
None,
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_REFLECT_101
)
# Use a mask to keep only the triangle pixels
# Get mask by filling triangle
mask = np.zeros((dest_rect[3], dest_rect[2], 3), dtype=np.float32)
cv2.fillConvexPoly(mask, np.int32(dest_crop_tri), (1.0, 1.0, 1.0), 16, 0)
# Apply mask to cropped region
dest_crop_img = dest_crop_img * mask
# Copy triangular region of the rectangular patch to the output image
img_out[dest_rect[1]:dest_rect[1] + dest_rect[3], dest_rect[0]:dest_rect[0] + dest_rect[2]] = \
img_out[dest_rect[1]:dest_rect[1] + dest_rect[3], dest_rect[0]:dest_rect[0] + dest_rect[2]] * (
(1.0, 1.0, 1.0) - mask)
img_out[dest_rect[1]:dest_rect[1] + dest_rect[3], dest_rect[0]:dest_rect[0] + dest_rect[2]] = \
img_out[dest_rect[1]:dest_rect[1] + dest_rect[3], dest_rect[0]:dest_rect[0] + dest_rect[2]] + dest_crop_img
return img_out[coord[2]:coord[3], coord[0]:coord[1]]
评论列表
文章目录