使用OpenCV(Python,C ++)无缝克隆
图1:无缝克隆示例:一架飞机被克隆到傍晚的天空中。
https://www.learnopencv.com/seamless-cloning-using-opencv-python-cpp/
OpenCV 3中引入的令人兴奋的新功能之一称为无缝克隆。使用此新功能,您可以从一个图像中复制对象,然后将其粘贴到另一图像中,从而使合成看起来无缝自然。上面的图像是使用天空和飞机场景创建的。如果我只是简单地将飞机图像覆盖在天空图像上,则结果看起来很可笑(见图2)。
图2:天空与飞机重叠。
当然,现在没有人在他们的头脑中会做这样的构图。您显然会仔细掩盖该图像,也许在Photoshop中呆了半天后,得到的图像如图3所示。
图3:飞机遮盖了仔细遮罩的天空图像。
如果您是艺术家,则需要花费半天时间,然后仔细调整飞机上的照明以适应天空图像的照明,并创造出美丽的构图。
但是,有两个问题。首先,您没有半天的时间。其次,您可能不是艺术家!
如果您可以在飞机周围做一个非常粗糙的面具,却又创造出如图1所示的漂亮构图,这不是很酷吗?如果仅用10行代码便会怎样呢?现在,这不仅很酷,还将是严重的坏蛋!
在向您展示代码之前,让我花一个小时来解释无缝克隆背后令人兴奋的理论。哦,等等,我有个更好的主意。让我们先深入研究代码。
无缝克隆实例
快速了解用法
Python
0
|
output = cv2.seamlessClone(src, dst, mask, center, flags)
|
C ++
0
|
seamlessClone(Mat src, Mat dst, Mat mask, Point center, Mat output, int flags)
|
src | 将被复制到目标图像的源图像。在我们的示例中是飞机。 |
dst | 源映像将被克隆到的目标映像。在我们的示例中,它是天空图像。 |
面具 | 要克隆的对象周围的粗糙蒙版。这应该是源图像的大小。如果您很懒,请将其设置为全白图像! |
中央 | 源图像中心在目标图像中的位置。 |
标志 | 当前工作的两个标志是NORMAL_CLONE和MIXED_CLONE。我提供了一个例子来说明差异。 |
输出 | 输出/结果图像。 |
现在,让我们看一下我用来生成上面图像的代码。
Python范例
1
|
# Standard imports
|
2
|
import cv2
|
3
|
import numpy as np
|
4
|
5
|
# Read images
|
6
|
src = cv2.imread( "images/airplane.jpg" )
|
7
|
dst = cv2.imread( "images/sky.jpg" )
|
8
|
9
|
10
|
# Create a rough mask around the airplane.
|
11
|
src_mask = np.zeros(src.shape, src.dtype)
|
12
|
poly = np.array([ [ 4 , 80 ], [ 30 , 54 ], [ 151 , 63 ], [ 254 , 37 ], [ 298 , 90 ], [ 272 , 134 ], [ 43 , 122 ] ], np.int32)
|
13
|
cv2.fillPoly(src_mask, [poly], ( 255 , 255 , 255 ))
|
14
|
15
|
# This is where the CENTER of the airplane will be placed
|
16
|
center = ( 800 , 100 )
|
17
|
18
|
# Clone seamlessly.
|
19
|
output = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE)
|
20
|
21
|
# Save result
|
22
|
cv2.imwrite( "images/opencv-seamless-cloning-example.jpg" , output);
|
C ++示例
1
|
using namespace cv;
|
2
|
3
|
// Read images : src image will be cloned into dst
|
4
|
Mat src = imread( "images/airplane.jpg" );
|
5
|
Mat dst = imread( "images/sky.jpg" );
|
6
|
|
7
|
8
|
// Create a rough mask around the airplane.
|
9
|
Mat src_mask = Mat::zeros(src.rows, src.cols, src.depth());
|
10
|
|
11
|
// Define the mask as a closed polygon
|
12
|
Point poly[1][7];
|
13
|
poly[0][0] = Point(4, 80);
|
14
|
poly[0][1] = Point(30, 54);
|
15
|
poly[0][2] = Point(151,63);
|
16
|
poly[0][3] = Point(254,37);
|
17
|
poly[0][4] = Point(298,90);
|
18
|
poly[0][5] = Point(272,134);
|
19
|
poly[0][6] = Point(43,122);
|
20
|
|
21
|
const Point* polygons[1] = { poly[0] };
|
22
|
int num_points[] = { 7 };
|
23
|
|
24
|
// Create mask by filling the polygon
|
25
|
26
|
fillPoly(src_mask, polygons, num_points, 1, Scalar(255,255,255));
|
27
|
|
28
|
// The location of the center of the src in the dst
|
29
|
Point center(800,100);
|
30
|
|
31
|
// Seamlessly clone src into dst and put the results in output
|
32
|
Mat output;
|
33
|
seamlessClone(src, dst, src_mask, center, output, NORMAL_CLONE);
|
34
|
|
35
|
// Save result
|
36
|
imwrite( "images/opencv-seamless-cloning-example.jpg" , output);
|
在上面的示例中,我使用的克隆类型(标志)为NORMAL_CLONE。还有另一种MIXED_CLONE,与NORMAL_CLONE稍有不同。让我们看看这两种类型在细节上有何不同。
普通克隆(NORMAL_CLONE)与混合克隆(MIXED_CLONE)
我有一个5岁的儿子,如果我对他好,他会给我“我爱你”门票。曾经有一段时间,孩子们渴望得到父母的批准,但如今,父母们必须竭尽全力获得“我爱你”的门票。无论如何,回到克隆。我将在Computer Vision服务中使用这些“我爱你的票”之一(请参见图4)。
图4:“我爱你”门票。
让我们尝试将该图像克隆到图5所示的木质纹理上。我们会很懒,使用全白色的源蒙版,然后将源图像克隆在木质纹理图像的中心。
图5:木材纹理
Python范例
1
|
import cv2
|
2
|
import numpy as np
|
3
|
4
|
# Read images : src image will be cloned into dst
|
5
|
im = cv2.imread( "images/wood-texture.jpg" )
|
6
|
obj = cv2.imread( "images/iloveyouticket.jpg" )
|
7
|
8
|
# Create an all white mask
|
9
|
mask = 255 * np.ones(obj.shape, obj.dtype)
|
10
|
11
|
# The location of the center of the src in the dst
|
12
|
width, height, channels = im.shape
|
13
|
center = (height / 2 , width / 2 )
|
14
|
15
|
# Seamlessly clone src into dst and put the results in output
|
16
|
normal_clone = cv2.seamlessClone(obj, im, mask, center, cv2.NORMAL_CLONE)
|
17
|
mixed_clone = cv2.seamlessClone(obj, im, mask, center, cv2.MIXED_CLONE)
|
18
|
19
|
# Write results
|
20
|
cv2.imwrite( "images/opencv-normal-clone-example.jpg" , normal_clone)
|
21
|
cv2.imwrite( "images/opencv-mixed-clone-example.jpg" , mixed_clone)
|
C ++示例
1
|
using namespace cv;
|
2
|
Mat src = imread( "images/iloveyouticket.jpg" );
|
3
|
Mat dst = imread( "images/wood-texture.jpg" );
|
4
|
|
5
|
// Create an all white mask
|
6
|
Mat src_mask = 255 * Mat::ones(src.rows, src.cols, src.depth());
|
7
|
|
8
|
// The location of the center of the src in the dst
|
9
|
Point center(dst.cols/2,dst.rows/2);
|
10
|
|
11
|
// Seamlessly clone src into dst and put the results in output
|
12
|
Mat normal_clone;
|
13
|
Mat mixed_clone;
|
14
|
|
15
|
seamlessClone(src, dst, src_mask, center, normal_clone, NORMAL_CLONE);
|
16
|
seamlessClone(src, dst, src_mask, center, mixed_clone, MIXED_CLONE);
|
17
|
|
18
|
// Save results
|
19
|
imwrite( "images/opencv-normal-clone-example.jpg" , normal_clone);
|
20
|
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秒。
下载无缝克隆代码和示例图像
向下滚动到下载部分(此文章底部)以立即访问此文章中的C ++和Python代码以及图像。
泊松图像编辑
在OpenCV的无缝克隆一个标题为一个有影响力的SIGGRAPH 2003纸的实现“泊松图像编辑”,由帕特里克·佩雷斯,米歇尔Gangnet和安德鲁·布雷克。
现在我们知道,如果使用精心创建的遮罩将源图像(飞机)的强度(RGB值)与目标图像(天空)混合,我们将获得如图3所示的结果。使用图像梯度而不是图像强度可以产生更真实的结果。无缝克隆后,蒙版区域中结果图像的强度与蒙版区域中源区域的强度不同。相反,结果图像在遮罩区域中的梯度与源区域在遮罩区域中的梯度大约相同。另外,在遮蔽区域的边界处的结果图像的强度与目的地图像(天空)的强度相同。
作者表明,这是通过求解泊松方程来完成的,因此可以解决论文的标题-泊松图像编辑。该论文的理论和实现细节实际上很酷,但超出了本文的范围。但是,如果您阅读本文并有疑问,请随时在评论部分提问。
使用OpenCV(Python,C ++)无缝克隆相关推荐
- opencv(python)------图像无缝克隆、对比度脱色、修复、HDR成像、非真实感渲染(三)
1. 基于opencv的无缝克隆 #python output = cv2.seamlessClone(src, dst, mask, center, flags) #c++ seamlessClon ...
- openCV【实践系列】3——使用OpenCV进行无缝克隆
使用OpenCV进行无缝克隆 图1:无缝克隆示例:一架飞机克隆到傍晚天空的照片中 OpenCV 3中引入的令人兴奋的新功能之一称为无缝克隆.使用此新功能,你可以从一个图像复制对象,并将其粘贴到另一个图 ...
- OpenCV项目开发实战--对图像种的对象进行无缝克隆-附Python、C++的代码实现
文末附基于Python和C++两种方式实现的测试代码下载链接 图 1:无缝克隆示例:一架飞机被克隆到傍晚天空的图片中. OpenCV 3 中引入的令人兴奋的新功能之一称为无缝克隆.有了这个新功能,您可 ...
- OpenCV:使用OpenCV无缝克隆模块的实例(附完整代码)
使用OpenCV无缝克隆模块的实例 使用OpenCV无缝克隆模块的实例 使用OpenCV无缝克隆模块的实例 #include <signal.h> #include "openc ...
- OpenCV:没有GUI的情况下使用OpenCV无缝克隆模块(附完整代码)
没有GUI的情况下使用OpenCV无缝克隆模块 没有GUI的情况下使用OpenCV无缝克隆模块 没有GUI的情况下使用OpenCV无缝克隆模块 #include "opencv2/photo ...
- OpenCV无缝克隆带GUI的模块的实例(附完整代码)
OpenCV无缝克隆带GUI的模块的实例 OpenCV无缝克隆带GUI的模块的实例 OpenCV无缝克隆带GUI的模块的实例 #include "opencv2/photo.hpp" ...
- OpenCV无缝克隆不带GUI的模块的实例(附完整代码)
OpenCV无缝克隆不带GUI的模块的实例 OpenCV无缝克隆不带GUI的模块的实例 OpenCV无缝克隆不带GUI的模块的实例 #include "opencv2/photo.hpp&q ...
- OpenCV每日函数 计算摄影模块(5) 无缝克隆算法
一.概述 借助无缝克隆算法,您可以从一张图像中复制一个对象,然后将其粘贴到另一张图像中,从而形成一个看起来无缝且自然的构图. 二.函数原型 给定一个原始彩色图像,可以无缝混合该图像的两个不同颜色版本. ...
- opencv 无缝克隆
一:API函数介绍 OpenCV3.x的图像计算模块多了新算法API-无缝克隆(Seamless Cloning),主要是针对图像编辑,局部修改等应用场景实现迁移对象与原图像场景的无缝克隆.相关函数与 ...
最新文章
- [NC19798]区间权值
- mysql表情符号变为_mysql Emoji表情字符集转换
- 表格排序tablesort小案列
- Sql 某一字段统计
- phpcms v9 内容页显示会员的详细信息(包括自定义字段)
- 如何组织公司的线下活动
- Flink 1.7.2 dataset transformation 示例
- 【深度】从朴素贝叶斯到维特比算法:详解隐马尔科夫模型
- Visual Studio的语法着色终于调得赏心悦目
- C++_引用_引用的基本语法_注意事项_引用做函数参数---C++语言工作笔记031
- 算法笔记_072:N皇后问题(Java)
- 【Linux】Shell 时间运算以及时间差计算方法!
- javaScript编码
- java applet init_java Applet中init方法
- 魏武帝 太祖知不可匡正,遂不复献言
- python 入门区块链
- PCB多层板每层厚度及材质
- jQuery 效果 - 淡入淡出,fadeIn,fadeOut,fadeToggle的使用
- 大学英语精读第三版(第六册)学习笔记(原文及全文翻译)——6B - John Thomas’s Cube(约翰·托马斯的立方体)
- D38 Java智能电话项目本————创建实体类
热门文章
- java round half down_Java8中的RoundingMode.HALF_DOWN问题
- php能实现文本复制吗,php 简单复制文件的方法
- java+script+当前日期_javascript获取当前时间
- Shiro中的Remember me设置
- 15.4 xshell使用xftp传输文件;15.5 使用pure-ftpd搭建ftp服务
- SpringBoot下文件上传与下载的实现
- 如何快速部署国人开源的 Java 博客系统 Tale
- MySql按周,按月,按日分组统计数据
- iOS开发小技巧--计算label的Size的方法总结
- Linux内核编译过程分析