泊松图像编辑(Poisson Image Editing)的核心观点是图像融合时,用色彩梯度代替色彩强度可以产生更真实的效果。
经无缝融合(seamless cloning)后,融合图像的蒙板区域内色彩强度与源图像的蒙板区域色彩强度不一致;但融合图像的蒙板区域内色彩梯度与源图像的蒙板区域色彩梯度基本相同。此外,融合图像的在蒙板区域边界处色彩强度与目标图像的色彩强度相同。
参考文献:Rez P, Gangnet M, Blake A. Poisson image editing.[J]. Acm Transactions on Graphics, 2003, 22(3):313-318.
seamlessClone(src, dst, mask, center, flags)
源图像的纹理(梯度)保留在融合区域
融合区域的纹理(梯度)由源图像和目标图像共同决定。混合融合会选择源图像和目标图像之中的主要纹理(梯度),因此不会产生平滑区域
保留源图像的纹理(梯度),丢弃其色彩信息,使得融合区域色彩与目标图像一致,可以用来进行皮肤质地填充。
output = cv2.seamlessClone(src, dst, mask, center, flags)
%matplotlib inline
import matplotlib.pyplot as plt
import math
def plotImgs(idxFig, lstImgs, figsize=(12, 24)):
fig = plt.figure(idxFig, figsize=figsize)
fig.clf()
intNumImgs = len(lstImgs)
intNumCols = int(math.sqrt(intNumImgs))
intNumRows = int(math.ceil(intNumImgs / intNumCols))
idxImg = 0
for idxRow in range(intNumRows):
for idxCol in range(intNumCols):
ax = fig.add_subplot(intNumRows, intNumCols, idxImg + 1, frameon=False)
if lstImgs[idxImg].dtype == "uint8":
ax.imshow(cv2.cvtColor(lstImgs[idxImg], cv2.COLOR_BGR2RGB))
else:
ax.imshow(lstImgs[idxImg])
ax.get_yaxis().set_visible(False)
ax.get_xaxis().set_visible(False)
idxImg += 1
if idxImg >= intNumImgs:
break
plt.show()
# Standard imports
import cv2
import numpy as np
# Read images
src = cv2.imread("./img/airplane.jpg")
dst = cv2.imread("./img/sky.jpg")
# Create a rough mask around the airplane.
src_mask = np.zeros(src.shape, src.dtype)
poly = np.array([[4,80], [30,54], [151,63], [254,37], [298,90], [272,134], [43,122]], np.int32)
cv2.fillPoly(src_mask, [poly], (255, 255, 255))
# This is where the CENTER of the airplane will be placed
center = (800,100)
# Clone seamlessly.
# Normal Cloning
output1 = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE)
# Mixed Cloning
output2 = cv2.seamlessClone(src, dst, src_mask, center, cv2.MIXED_CLONE)
output3 = cv2.seamlessClone(src, dst, src_mask, center, cv2.MONOCHROME_TRANSFER)
# Save result
#cv2.imwrite("./output/opencv-seamless-cloning-example.jpg", output)
idxFig = 1
plotImgs(1, [src, src_mask, dst, output1, output2, output3], figsize=(12, 8))
# Read images : src image will be cloned into dst
im = cv2.imread("./img/wood-texture.jpg")
obj = cv2.imread("./img/iloveyouticket.jpg")
# Create an all white mask
mask = 255 * np.ones(obj.shape, obj.dtype)
# The location of the center of the src in the dst
width, height, channels = im.shape
center = (height // 2, width // 2)
# Seamlessly clone src into dst and put the results in output
normal_clone = cv2.seamlessClone(obj, im, mask, center, cv2.NORMAL_CLONE)
mixed_clone = cv2.seamlessClone(obj, im, mask, center, cv2.MIXED_CLONE)
mono_clone = cv2.seamlessClone(obj, im, mask, center, cv2.MONOCHROME_TRANSFER)
# Write results
#cv2.imwrite("images/opencv-normal-clone-example.jpg", normal_clone)
#cv2.imwrite("images/opencv-mixed-clone-example.jpg", mixed_clone)
idxFig += 1
plotImgs(1, [obj, im, normal_clone, mixed_clone, mono_clone], figsize=(12, 8))