Opencv学习:使用Opencv对图象进行抠图和滤镜处理,实现“你的名字”动漫图片效果
最近接到了一个坑爹题目,是这么要求的:
仿照 《你的名字》,对天坛图像。src.jpg进行处理。要求
(一)背景(天空)分割,替换后再融合
在自然界的图片中,很难出现动漫中大多大多的云彩。首先需要将背景(天空)分割出来,替换成动漫的天空,并且在很好地融合回去。
需要实现的技术:1.背景(天空)分割; 2.再融合。
(二)前景色调转换
为了实现漫画中具有卡通意味的前景色调,需要对前面切割下来的前景图片进行色调转换。需要实现的技术:3.LUT和色块制作
幸好网上的例子比较多,老师也给了个例程,现在就一步步来执行
给了两张图片,是这个样子的:


现在需要做得事情就是把云编程动漫里面那种云,然后把天坛抠出来换成那样的云。
首先要对天坛进行抠图处理。
给出代码如下:

/************************************************************************/
/* 1.背景(天空)分割 */
/************************************************************************/
cvtColor(matSrc, temp, COLOR_BGR2HSV);
split(temp, planes);
equalizeHist(planes[2], planes[2]);//对v通道进行equalizeHist
merge(planes, temp);
inRange(temp, Scalar(100, 43, 46), Scalar(124, 255, 255), temp);
erode(temp, temp, Mat());//形态学变换,填补内部空洞
dilate(temp, temp, Mat());
imshow("kou",temp);
原理是对图片进行了直方图均衡化:equalizeHist(),然后根据阙值二元化,白色和黑色。接着进行形态学变换,把天坛的大致轮廓抠图出来了。
接下来就是把我们的云彩图片和这个天坛融合起来了.......
记得要先进行resize,也就是尺寸控制。
/************************************************************************/
/* 2.再融合,以1的结果mask,直接将云图拷贝过来(之前需要先做尺度变换) */
/************************************************************************/
//寻找白色区域最大外接矩形的代码
VP maxCountour = FindBigestContour(mask);
Rect maxRect = boundingRect(maxCountour);
if (maxRect.height == 0 || maxRect.width == 0)
maxRect = Rect(0, 0, mask.cols, mask.rows);//特殊情况
matDst = matSrc.clone();
//注意这里的mask 需要和matCloud同样尺寸
mask = mask(maxRect);
resize(matCloud, matCloud, maxRect.size());
//seamless clone
//中间位置为蓝天的背景位置
Point center = Point((maxRect.x + maxRect.width) / 2, (maxRect.y + maxRect.height) / 2);
Mat normal_clone;
Mat mixed_clone;
Mat monochrome_clone;
seamlessClone(matCloud, matSrc, mask, center, normal_clone, NORMAL_CLONE);
seamlessClone(matCloud, matSrc, mask, center, mixed_clone, MIXED_CLONE);
seamlessClone(matCloud, matSrc, mask, center, monochrome_clone, MONOCHROME_TRANSFER);
这里有几个问题,第一个是FindBigestContour函数,实在是不太清楚作用
VP FindBigestContour(Mat src) {
int imax = 0; //代表最大轮廓的序号
int imaxcontour = -1; //代表最大轮廓的大小
std::vector<std::vector<Point>>contours;
findContours(src, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size(); i++) {
int itmp = contourArea(contours[i]);//这里采用的是轮廓大小
if (imaxcontour < itmp) {
imax = i;
imaxcontour = itmp;
}
}
return contours[imax];
}
seamlessclone是一种叫做泊松融合的函数,这里用了3种融合方法。
函数原型(C++):
void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)
官方文档中的解释:Checks if array elements lie between the elements of two other arrays.即检查数组元素是否在另外两个数组元素值之间。这里的数组通常也就是矩阵Mat或向量。请注意:该函数输出的dst是一幅二值化之后的图像。
seamlessClone(matCloud, matSrc, mask, center, normal_clone, NORMAL_CLONE);
seamlessClone(matCloud, matSrc, mask, center, mixed_clone, MIXED_CLONE);
seamlessClone(matCloud, matSrc, mask, center, monochrome_clone, MONOCHROME_TRANSFER);
实验结果如下:

有几个问题,这三个函数显示出来的图象其实效果差不多。是因为什么呢?这就不太清楚了,由于之前的边缘分析算法设计比较精良的缘故嘛?
接下来进行卡通处理。
代码如下:
/************************************************************************/
/* 3.卡通画处理 */
/************************************************************************/
//双边滤波
bilateralFilter(normal_clone, temp, 5, 10.0, 2.0);
//彩色直方图均衡,将RGB图像转到YCbCr分量,然后对Y分量上的图像进行直方图均衡化
cvtColor(temp, temp, COLOR_BGR2YCrCb);
split(temp, planes);
equalizeHist(planes[0], planes[0]);
merge(planes, temp);
cvtColor(temp, temp, COLOR_YCrCb2BGR);
//提高图像饱和度
matDst = EnhanceSaturation(temp);
imshow("结果图", matDst);
这里有个秘制小函数叫EnhanceSaturation(),目的是提高图像的饱和度,这里就不放出来了。
大致的原理是双边滤波+彩色直方图均衡。
最终的结果是这样

Opencv学习:使用Opencv对图象进行抠图和滤镜处理,实现“你的名字”动漫图片效果的更多相关文章
- OpenCV学习(22) opencv中使用kmeans算法
kmeans算法的原理参考:http://www.cnblogs.com/mikewolf2002/p/3368118.html 下面学习一下opencv中kmeans函数的使用. 首先我们 ...
- OpenCV学习笔记——OpenCV安装
关于OpenCV安装 1.下载和安装OpenCV SDK 在官网:http://opencv.org/上找到OpenCV windows版下载 . 后得到一个 opencv-2.X.X.exe的文件, ...
- OpenCV学习(39) OpenCV中的LBP图像
本章我们学习LBP图像的原理和使用,因为接下来教程我们要使用LBP图像的直方图来进行脸部识别. 参考资料: http://docs.opencv.org/modules/contrib/doc/fac ...
- OpenCV学习(35) OpenCV中的PCA算法
PCA算法的基本原理可以参考:http://www.cnblogs.com/mikewolf2002/p/3429711.html 对一副宽p.高q的二维灰度图,要完整表示该图像,需要m = ...
- OpenCV学习:OpenCV文件一览
了解一些OpenCV代码整体的模块结构后,再重点学习自己感兴趣的部分,会有一种一览众山小的感觉~ Come on! C:\OpenCV\opencv\build\include文件夹下包含两个文件夹: ...
- OpenCV学习(1) OpenCV的安装
前沿 准备了好几天,终于开始了,不管怎样,接下来的这个月一定把这本书很好的啃下来.当然OpenCV可以在很多的IDE下安装与配置,我这里就只在VS2010和VC6.0下安装配置了,当然这篇博文主要讲在 ...
- OpenCV学习:OpenCV源码编译(vc9)
安装后的OpenCV程序下的build文件夹中,只找到了vc10.vc11和vc12三种编译版本的dll和lib文件,需要VS2010及以上的IDE版本,而没有我们常用的VS2008版本. 于是,需要 ...
- OpenCV学习:OpenCV介绍
OpenCV全称是:Open Source Computer Vision Library(开源计算机视觉库). 于1999年由Intel建立,如今由Willow Garage提供支持. 跨平台,可以 ...
- OpenCV学习(3) OpenCV框架
OpenCV是一个开源的视觉库,其中包括很多计算机视觉的算法实现.在版本2.2以后,OpenCV采用C++特征的API,在1.x版本中,OpenCV函数都是传统的C语言形式. ...
- OpenCV学习(2) OpenCV的配置
下面我们在VS2010中编写一个简单的OpenCV程序,来看看如何在程序中使用OpenCV. 创建一个新的Win32 控制台程序,附加选项为空工程(empty project),并添加一个 ...
随机推荐
- PIO----创建Excel表格复杂使用
导出 @RequestMapping( name = "下载模板附件实现Model", value = {"/uploadFileModel"}, method ...
- 官方的 MCP C# SDK:csharp-sdk
csharp-sdk 这是 Model Context Protocol(MCP)官方提供的 C# SDK,为 MCP 服务器和客户端提供简单易用的接口, 主要由微软维护.MCP 是由 Claude( ...
- ANSYS 命令流导航
常见书籍 ANSYS 命令流导航 GitHub 项目:ANSYS_Code Gitee 镜像:ANSYS_Code 欢迎补充~ 文件说明 doc 中包括 ANSYS, ABAQUS, LS-DYNA ...
- DTMF从2833到inband的方案
概述 freeswitch是一款简单好用的VOIP开源软交换平台. 之前的文章中介绍过通过dialplan拨号计划配置的方法,实现2833到inband的转换,但是实际生产环境中的场景会更复杂,无法预 ...
- ASP.NET 自定义DataTable数据
using System.Data; //DataTable try { DataTable dt = new DataTable(); dt.Columns.Add("Bu ...
- 【深度解析】SkyWalking 10.2.0版本安全优化与性能提升实战指南
前言 Apache SkyWalking 作为云原生可观测性领域的佼佼者,在微服务架构监控中扮演着至关重要的角色.然而,官方版本在安全性.镜像体积和功能扩展方面仍有优化空间.本文将分享一套完整的 Sk ...
- 快速定位MySQL 8.0中的慢查询语句详细步骤
步骤一.启用慢查询日志 慢查询日志是MySQL记录执行时间超过指定阈值的SQL语句 配置慢查询日志 在MySQL配置文件(如my.cnf或my.ini)中设置以下参数: slow_query_log: ...
- DelayQueue 底层原理
一.DelayQueue 底层原理 DelayQueue是一种本地延迟队列,比如希望我们的任务在5秒后执行,就可以使用DelayQueue实现.常见的使用场景有: 订单10分钟内未支付,就取消. 缓存 ...
- element ui select组件 实现鼠标悬浮 自动展开选项
利用鼠标悬浮事件: 同样的原理也可以设置鼠标移开自动关闭
- Nacos简介—3.Nacos的配置简介
大纲 1.Nacos生产集群Web端口与数据库配置 2.Nacos生产集群的Distro协议核心参数 3.Nacos打通CMDB实现跨机房的就近访问 4.Nacos基于SPI动态扩展机制来获取CMDB ...