图像的简单copyPaste实现
简介
本篇是对实现复制粘贴的笔记记录。 注:本篇使用的所有图像皆来源自网络,如有侵权,请联系本人删除。
基本原理
这里分为两步:1、从第一张图像中抠出感兴趣区域。 2、将感兴趣区域粘贴到第二张图片中。分别可以参考前面文档:1、opencv实现图像分割,分离前景和背景(2)2、残差金字塔实现
抠图部分
参考前面的提到的文档:《opencv实现图像分割,分离前景和背景(2)》,最后将扣出来的感兴趣图像复制到resCopy,并将对应图像掩码保存到 binMask中。对应结果显示如下:
手动抠图操作 扣去图像的掩码 抠出的图像
掩码处理
在直接根据掩码进行图像粘贴融合之前,需要先对掩码进行处理,否则会导致融合图像的边缘很模糊。 具体的操作,可以参考前面提到的文档:《残差金字塔实现》
大致代码如下:
GaussianBlur(pySrc[0], pyDst[0], Size(g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1), 0, 0);
pyWidth[1] = pyWidth[0] / 2;
pyHeight[1] = pyHeight[0] / 2;
resize(pyDst[0], pySrc[1], Size(pyHeight[1], pyWidth[1]));GaussianBlur(pySrc[1], pyDst[1], Size(g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1), 0, 0);
pyWidth[2] = pyWidth[1] / 2;
pyHeight[2] = pyHeight[1] / 2;
resize(pyDst[1], pySrc[2], Size(pyHeight[2], pyWidth[2]));GaussianBlur(pySrc[2], pyDst[2], Size(g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1), 0, 0);
pyWidth[3] = pyWidth[2] / 2;
pyHeight[3] = pyHeight[2] / 2;
resize(pyDst[2], pySrc[3], Size(pyHeight[3], pyWidth[3]));resize(pySrc[3], tmp, Size(pyHeight[2], pyWidth[2]));
pyDst[2] = tmp;resize(pyDst[2], tmp, Size(pyHeight[1], pyWidth[1]));
pyDst[1] = tmp;resize(pyDst[1], tmp, Size(pyHeight[0], pyWidth[0]));
pyDst[0] = tmp;imshow("mask22", pyDst[0]);
binMask = pyDst[0];
最开始的pySrc[0]就是之前的掩码图像binMask,先建立该图像的高斯金字塔,接着对图像进行恢复。注意这里并没有使用残差金字塔,所以恢复后的 图像将会是原图像的边缘模糊处理后图像。对应的效果显示如下:
原始掩码图像 处理后掩码图像
图像粘贴
获得了处理之后的掩码,接着就是进行最后的图像粘贴融合操作。
1、计算出掩码对应感兴趣区域,在原图中的坐标位置,保存到rectResCopy中。
void getResCopyAddr(Mat src){int i, j;IplImage ipI = src;int width = src.rows;int height = src.cols;int minWidth,maxWidth, minHeight, maxHeight;CvScalar s1;for(i=0; i<width; i++){for(j=0; j<height; j++){s1 = cvGet2D(&ipI, i, j);if(s1.val[0] > 0){if(maxWidth == 0){minWidth = i; maxWidth = i; minHeight = j; maxHeight = j; }if(minWidth > i)minWidth = i;if(maxWidth < i)maxWidth = i;if(minHeight > j)minHeight = j;if(maxHeight < j)maxHeight = j;}}}rectResCopy.x = minWidth;rectResCopy.y = minHeight;rectResCopy.width = maxWidth - minWidth;rectResCopy.height = maxHeight - minHeight;
}
2、根据掩码图像像素值,进行融合图像权重计算计算:如果掩码值为0,则新像素值全部为被粘贴图像;如果掩码值为[1, 254],则新 像素值为:(被粘贴图像 * (1 - (掩码值 / 255))) + (感兴趣区域 * (掩码值 / 255));如果掩码值为255,则新像素值为感兴趣区域。
void getPaste(Mat src1, Mat src2, Rect rectAddr){int i, j;IplImage ip1 = src1;IplImage ip2 = src2;IplImage ip3 = binMask;CvScalar s1, s2, s3;int dstWidth = src1.rows;int dstHeight = src1.cols;int addrX = 70, addrY = 70;double scale;if(addrX + rectAddr.width > dstWidth){printf("pic Size is too big in Width!\n");return; }if(addrY + rectAddr.height > dstHeight){printf("pic Size is too big in Height!\n");return; }for(i=rectAddr.x; i<rectAddr.x + rectAddr.width; i++){for(j=rectAddr.y; j<rectAddr.y + rectAddr.height; j++){s1 = cvGet2D(&ip1, addrX + i - rectAddr.x, addrY + j -rectAddr.y);s2 = cvGet2D(&ip2, i, j);s3 = cvGet2D(&ip3, i, j);if(s3.val[0] > 0){scale = s3.val[0] / 255;s1.val[0] = (s1.val[0] * (1 - scale)) + (s2.val[0] * scale);s1.val[1] = (s1.val[1] * (1 - scale)) + (s2.val[1] * scale);s1.val[2] = (s1.val[2] * (1 - scale)) + (s2.val[2] * scale);cvSet2D(&ip1, addrX + i - rectAddr.x, addrY + j -rectAddr.y, s1);} }}
}
结果显示
显示的结果如下:
直接融合 处理掩码后融合
代码下载:http://download.csdn.net/detail/u011630458/9424343
图像的简单copyPaste实现相关推荐
- java 验证码图片识别_JavaSE图像验证码简单识别程序详解
本文为大家分享了JavaSE图像验证码简单识别程序,供大家参考,具体内容如下 首先你应该对图片进行样本采集,然后将样本进行灰度处理,也就是变成黑白两色. 然后你就可以使用该类,对目标文件进行分析.具体 ...
- C++下opencv学习笔记(一)(图像的简单读取丶显示与存储)
C++下opencv学习笔记(一)(图像的简单读取丶显示与存储) 前言 学习C++ OpenCV,第一需要具备面向对象语言的基础,第二要对图像处理机器学习有基础了解,容易入门.觉得自己基础已经有了可以 ...
- 玩转Pillow(PIL)-Python将图像变为简笔画风格进行图像的简单操作
目录 一.前言 (一)Pillow与PIL简介 (二)Pillow安装 二.实战 (一)将图像变为简笔画风格 (二)进行图像的简单操作 一.前言 (一)Pillow与PIL简介 1.PIL:PIL(P ...
- CSS背景图像的简单响应
本文设有很多,最理想的解决方案,响应图像只是其中之一.我们建议您查看不同的方法,然后再选择一个特定的响应图像解决方案,包括这两个:如何避免重复下载响应图像中选择响应图像解决方案. 大家都在谈论的的sr ...
- 什么是.dat? python读取.dat文件并转换为png图像——超简单实现
相信大家和我一样,对于.dat文件是感到十分陌生的.因此在刚接触到这个小任务的时候我实在花了一些时间来了解到底什么是.dat文件.这里我将我自己的认识分享给大家: 总体而言,对于.dat文件的定义,我 ...
- 【CCD图像检测】4:图像的简单校正
CCD图像检测<四> 作者:一点一滴的Beer 指导教师:Chen Zheng 单位:WHU 五. 图像的校正. 5.1.纵向校正 5.1.1纵向理论校正. 图28:纵向理论校正 ...
- 去除pdf水印图像的简单方法
在由超星转换而来的pdf文件中,往往带有一个篆刻水印"好学近乎知",这样的文档由打印机打印出来后,会变成全黑的一块.下面是个简单的方法来去除篆刻水印图像.需要注意的是,这个是水印图 ...
- opencv(三)对图像进行简单算术运算(加减乘除)
opencv可以将图像以不同的方式组合,图像其实就是一般的矩阵,所以它们可以做加减乘除.opencv提供了各种图像算术操作符. 1[首先我们对两幅图像进行操作] 当我们需要一些图像特效或者在图像上叠加 ...
- JavaSE图像验证码简单识别程序
首先你应该对图片进行样本采集,然后将样本进行灰度处理,也就是变成黑白两色. 然后你就可以使用该类,对目标文件进行分析.具体怎么实现我觉得这个类非常清楚,就是将样本从左都有这么横向移动,匹配出一个合适的 ...
- Opencv学习笔记 图像特效 简单铅笔/卡通/马赛克/毛玻璃/Lomography/简单磨皮等效果
一.铅笔画滤镜 铅笔画滤镜主要是提取出图片中梯度比较高的部分,也就是边缘检测 二.卡通画特效 卡通画特效主要由三部分组成 1.提取图像中轮廓 => edges 2.使用bilateral 滤波在 ...
最新文章
- Json对象和Json字符串
- IE 市场份额暴跌,Edge 能否守住微软的辉煌
- rostcm6情感分析案例分析_卷积情感分析
- Extracting Text From Image
- php memcached 队列,redis获取所有队列_memcached
- Android P (4)一种绕过Android P上非SDK接口限制的简单方法
- 29岁学java_今年29岁小学文化,想学java请各位指点怎么入手?
- 将小写金额转换成大写金额[存储过程版]
- python画出roc曲线 auc计算逻辑_从scikitlearn(sklearn)的多类数据计算AUC和ROC曲线?...
- Tricks(三十二)—— 遍历全部的子串(子数组)
- 【车间调度】基于matlab模拟退火算法求解车间调度(jobshop-3)问题【含Matlab源码 1082期】
- 移远4G模组EC600N进行TCP/IP连接和服务器测试
- 【源码】C++坦克大战
- linux 下不错的html编辑器bluefish
- 联想服务器安装系统鼠标失灵,ThinkPad自行安装操作系统后键盘鼠标失灵怎么办...
- 宋体能力从业的一些感悟
- poj 1830 开关问题
- laravel 5.6 请教邮件中的cc,bcc是什么意思,有什么用?
- 跟着iMeta学做图|ComplexHeatmap包绘制热图展示不同样本物种相对丰度
- 五分钟学会如何用java解析json字符串!