| import numpy as np
|
| import cv2
|
|
|
| def AlphaBlend(foreground, background, alpha):
|
|
|
| foreground = foreground.astype(float)
|
| background = background.astype(float)
|
|
|
|
|
| alpha = alpha.astype(float)/255
|
| if len(alpha.shape) < 3:
|
| alpha = np.expand_dims(alpha, 2)
|
| outImage = alpha * foreground + (1.-alpha) * background
|
| outImage = np.clip(outImage, 0, 255).astype(np.uint8)
|
|
|
| return outImage
|
|
|
| def blendImages(src, dst, mask, featherAmount=0.1):
|
| maskIndices = np.where(mask != 0)
|
| maskPts = np.hstack(
|
| (maskIndices[1][:, np.newaxis], maskIndices[0][:, np.newaxis]))
|
| faceSize = np.max(maskPts, axis=0) - np.min(maskPts, axis=0)
|
| featherAmount = 0.2
|
|
|
| hull = cv2.convexHull(maskPts)
|
|
|
| dists = np.zeros(maskPts.shape[0])
|
| for i in range(maskPts.shape[0]):
|
| point = (maskPts[i, 0], maskPts[i, 1])
|
| """
|
| The third paprameter can be set as "True" for more visually diverse images.
|
| We use "False" to add imperceptible image patterns to synthesize new images.
|
| """
|
| point_x, point_y = point
|
| dists[i] = cv2.pointPolygonTest(hull, (int(point_x),int(point_y)), False)
|
|
|
| weights = np.clip(dists / featherAmount, 0, 1)
|
| composedImg = np.copy(dst)
|
| composedImg[maskIndices[0], maskIndices[1]] = weights[:, np.newaxis] * \
|
| src[maskIndices[0], maskIndices[1]] + \
|
| (1 - weights[:, np.newaxis]) * \
|
| dst[maskIndices[0], maskIndices[1]]
|
| newMask = np.zeros_like(dst).astype(np.float32)
|
| newMask[maskIndices[0], maskIndices[1]] = weights[:, np.newaxis]
|
|
|
| return composedImg, newMask
|
|
|
|
|
| def colorTransfer(src_, dst_, mask):
|
| src = dst_
|
| dst = src_
|
| transferredDst = np.copy(dst)
|
| maskIndices = np.where(mask != 0)
|
| maskedSrc = src[maskIndices[0], maskIndices[1]].astype(np.int32)
|
| maskedDst = dst[maskIndices[0], maskIndices[1]].astype(np.int32)
|
| meanSrc = np.mean(maskedSrc, axis=0)
|
| meanDst = np.mean(maskedDst, axis=0)
|
| maskedDst = maskedDst - meanDst
|
| maskedDst = maskedDst + meanSrc
|
| maskedDst = np.clip(maskedDst, 0, 255)
|
| transferredDst[maskIndices[0], maskIndices[1]] = maskedDst
|
|
|
| return transferredDst
|
|
|