本帖最后由 fantomas 于 2018-10-19 09:55 编辑
使用OpenCV进行无缝克隆
图1:无缝克隆示例:一架飞机克隆到傍晚天空的照片中 OpenCV 3中引入的令人兴奋的新功能之一称为无缝克隆。使用此新功能,你可以从一个图像复制对象,并将其粘贴到另一个图像中,使组合看起来无缝且自然。上面的图像是使用天空和飞机的场景创建的。如果我简单地将飞机图像覆盖在天空图像的顶部,结果将显得荒谬(参见图2) 图2:飞机重叠的天空 当然,在他们正确的思想中,没有人会做这样的组合。你显然会仔细地掩盖图像,也许在Photoshop中花了半天后得到一张如图3所示的图像。 图3:天空图像,飞机上覆盖着仔细的遮蔽 如果你是一名艺术家,你将花费另外半天时间,仔细调整飞机上的灯光,使其成为天空图像的照明,并创造出美丽的构图。但是有两个问题。首先,你没有半天的时间。其次,你可能不是艺术家! 如果你能在飞机周围制作一个非常粗糙的面具,然后创造一个看起来像图1的漂亮构图,那不是很酷吗?如果你只用10行代码就能做到这一点怎么办? 在我向您展示代码之前,让我花一个小时来解释无缝克隆背后令人兴奋的理论。我们先来看看代码吧。 无缝克隆实例: 快速浏览一下python的用法 - # 导入相关的包
- import cv2
- import numpy as np
- # 读图像
- src = cv2.imread("images/airplane.jpg")
- dst = cv2.imread("images/sky.jpg")
- # 构建一个在飞机周围粗略的掩模
- 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))
- # 这是飞机的中心点
- center = (800,100)
- # 无缝克隆.
- output = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE)
- # 保存结果
- cv2.imwrite("images/opencv-seamless-cloning-example.jpg", output);
复制代码
上面的例子中,我使用的克隆类型(标志)是NORMAL_CLONE。还有另一种类型MIXED_CLONE,与NORMAL_CLONE略有不同。让我们看看这两种类型在细节上有何不同。 正常克隆(NORMAL_CLONE)与混合克隆(MIXED_CLONE) 我有一个5岁的儿子,如果我对他很好,他会给我“我爱你”的门票。有一段时间,孩子们渴望得到父母的认可,但这些天父母们必须尽力赚取“我爱你”的门票。无论如何,回到克隆。我将在计算机视觉服务中使用其中一个“我爱你的门票”(参见图4)。 让我们尝试将这个图像克隆到图5所示的木质纹理上。我们将是懒惰的并且使用全白的掩模,并将源图像克隆在木质纹理图像的中心。 - # 导入相关的包
- import cv2
- import numpy as np
- # 读图像:源图像将被克隆到目标图像上
- im = cv2.imread("images/wood-texture.jpg")
- obj= cv2.imread("images/iloveyouticket.jpg")
- # 构建全白的掩模
- mask = 255 * np.ones(obj.shape, obj.dtype)
- # 源图像在目标图像的中位置
- width, height, channels = im.shape
- center = (height/2, width/2)
- # 将源图像无缝克隆到目标图像上并将结果输出
- normal_clone = cv2.seamlessClone(obj, im, mask, center, cv2.NORMAL_CLONE)
- mixed_clone = cv2.seamlessClone(obj, im, mask, center, cv2.MIXED_CLONE)
- # 保存结果
- cv2.imwrite("images/opencv-normal-clone-example.jpg", normal_clone)
- cv2.imwrite("images/opencv-mixed-clone-example.jpg", mixed_clone)
复制代码
如果我们使用NORMAL_CLONE标志使用正常克隆,我们将得到如图6所示的结果。现在我们没有使用好的掩模,你可以看到单词“I”和“Love”之间以及“you”和“Paa”之间的过度平滑。当然我们很懒。我们可以创建一个粗糙的掩模并改进结果。但如果你懒惰而聪明,你会使用混合克隆。 图6:OpenCV正常克隆示例 混合克隆结果: 在正常克隆中,源图像的纹理(渐变)将保留在克隆区域中。在混合克隆中,克隆区域的纹理(梯度)由源图像和目标图像的组合确定。混合克隆不会产生平滑区域,因为它会选择源图像和目标图像之间的主要纹理(渐变)。混合克隆的结果如图7所示。请注意,“I”和“Love”以及“you”和“Paa”之间的纹理不再平滑。懒人欢呼! 图7:OpenCV混合克隆示例
无缝克隆视频结果 我拍摄了飞机和天空的图像,并改变了飞机的位置来创建这个动画。MIXED_CLONE给出了更好的结果,你几乎没有注意到任何文物。将300×194图像(飞机)克隆到1000×560图像(天空)上大约需要0.4秒。 Poisson Image Editing OpenCV中的无缝克隆是由Patrick Perez,Michel Gangnet和Andrew Blake撰写的具有影响力的SIGGRAPH 2003论文题为“ Poisson Image Editing”的实现。 现在我们知道如果我们使用精心创建的掩模将源图像(飞机)的强度(RGB值)与目标图像(天空)混合,我们将获得如图3所示的结果。本文的核心见解是使用图像渐变而不是图像强度可以产生更真实的结果。在无缝克隆之后,掩模区域中的结果图像的强度与掩模区域中的源区域的强度不同。相反,掩模区域中的结果图像的梯度与掩模区域中的源区域的梯度大致相同。另外,在掩模区域的边界处的结果图像的强度与目标图像(天空)的强度相同。 作者表明,这是通过求解泊松方程来完成的,因此也就是论文的标题 - Poisson Image Editing。该论文的理论和实现细节实际上非常酷,但超出了本文的范围。但是,如果您阅读论文并有疑问,请随时在评论部分询问。
|