这是一个比较有意思的demo,用到了播送融合,具体效果见下图:

文件结构如图所示

主程序代码

#include"stdafx.h"
#include<opencv2/photo.hpp>
#include"HSL.hpp" using namespace std;
using namespace cv; const string window_name = "photo";
static Mat src; static HSL hsl;
static int color = 0;
static int hue = 180;
static int saturation = 100;
static int brightness = 100; #define VP vector<Point> //寻找最大的轮廓
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];
} //提高饱和度
Mat EnhanceSaturation(Mat temp)
{
Mat matDst;
Mat Img_out(temp.size(), CV_32FC3);
temp.convertTo(Img_out, CV_32FC3);
Mat Img_in(temp.size(), CV_32FC3);
temp.convertTo(Img_in, CV_32FC3);
// define the iterator of the input image
MatIterator_<Vec3f> inp_begin, inp_end;
inp_begin = Img_in.begin<Vec3f>();
inp_end = Img_in.end<Vec3f>();
// define the iterator of the output image
MatIterator_<Vec3f> out_begin, out_end;
out_begin = Img_out.begin<Vec3f>();
out_end = Img_out.end<Vec3f>();
// increment (-100.0, 100.0)
float Increment = 50.0 / 100.0; //饱和度参数调整
float delta = 0;
float minVal, maxVal;
float t1, t2, t3;
float L, S;
float alpha; for (; inp_begin != inp_end; inp_begin++, out_begin++)
{
t1 = (*inp_begin)[0];
t2 = (*inp_begin)[1];
t3 = (*inp_begin)[2]; minVal = std::min(std::min(t1, t2), t3);
maxVal = std::max(std::max(t1, t2), t3);
delta = (maxVal - minVal) / 255.0;
L = 0.5*(maxVal + minVal) / 255.0;
S = std::max(0.5*delta / L, 0.5*delta / (1 - L)); if (Increment > 0)
{
alpha = max(S, 1 - Increment);
alpha = 1.0 / alpha - 1;
(*out_begin)[0] = (*inp_begin)[0] + ((*inp_begin)[0] - L * 255.0)*alpha;
(*out_begin)[1] = (*inp_begin)[1] + ((*inp_begin)[1] - L * 255.0)*alpha;
(*out_begin)[2] = (*inp_begin)[2] + ((*inp_begin)[2] - L * 255.0)*alpha;
}
else
{
alpha = Increment;
(*out_begin)[0] = L * 255.0 + ((*inp_begin)[0] - L * 255.0)*(1 + alpha);
(*out_begin)[1] = L * 255.0 + ((*inp_begin)[1] - L * 255.0)*(1 + alpha);
(*out_begin)[2] = L * 255.0 + ((*inp_begin)[2] - L * 255.0)*(1 + alpha); }
}
Img_out /= 255;
Img_out.convertTo(matDst, CV_8UC3, 255); return matDst;
} int _tmain(int argc, _TCHAR* argv[])
{
Mat matSrc = imread("../src3.jpg");
Mat matCloud = imread("../cloud2.jpg");
Mat temp; Mat matDst; Mat mask;
vector<Mat> planes;
/************************************************************************/
/* 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());
mask = temp.clone();//将结果存入mask
/************************************************************************/
/* 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);
/************************************************************************/
/* 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("原始图", matSrc);
imshow("结果图", matDst);
cv::waitKey();
getchar();
return 0;
}

其他包含的库文件放到我的链接:https://i-beta.cnblogs.com/files

OpenCV实现"你的名字"滤镜的更多相关文章

  1. [转] Matlab与C++混合编程,添加OpenCV库

    原文地址 峰回璐转 最近在做运动医学软件优化工作,此款软件框架及算法语言全由matlab实现,虽然matlab矩阵运算.数值计算能力强大,但速度让人难以忍 受.软件立刻移植到C++上又不太实际,故采用 ...

  2. Matlab与C++混合编程,添加OpenCV库

    最近在做运动医学软件优化工作,此款软件框架及算法语言全由matlab实现,虽然matlab矩阵运算.数值计算能力强大,但速度让人难以忍受.软件立刻移植到C++上又不太实际,故采用联合编程的方式,速度难 ...

  3. Ubuntu系统---编译opencv程序的几种方式g++、Makefile、Cmake

    Ubuntu系统---编译opencv程序的几种方式g++.Makefile.Cmake 先建立一个工程(一个文件夹),写好xxx.cpp文件,可以是多个: //----------opencv.cp ...

  4. Poisson Blending(Seamless clone)研究和实现

    Poisson Blending 实现了非常棒的效果,可以看 <自己动手,实现“你的名字”滤镜> http://www.cnblogs.com/jsxyhelu/p/7216795.htm ...

  5. studio 配置 opencv3.1

    环境 win10 android studio2.0 OpenCV-3.1.0-android-sdk android-ndk-r10e-windows-x86_64 jdk-8u102-window ...

  6. vs2017 dlib19.3 opencv3.41 C++ 环境配置 人脸特征点识别

    身为一个.net程序员经过两天的采坑终于把人脸特征检测的项目跑通了,然后本文将以dlib项目中人脸特征检测工程为例,讲解dlib与opencv 在vs2017 C++ 项目中的编译与运行路径配置. 1 ...

  7. 高反差保留滤镜学习OpenCV:滤镜系列(11)——高反差保留

    这几周笔者几篇文章介绍了改高反差保留滤镜的文章. 关联文章的地址 高反差保留就是高通滤波 r=(pix[x,y]-avg(R))/128 pix[x,y]*r+128*(1-r) #include & ...

  8. opencv滤镜-使用opencv实现各种图像滤镜特效

    图像处理-滤镜 链接:https://mangoroom.cn/opencv/image-processing-filter.html opencv滤镜-实现晕影vignetting效果 链接:htt ...

  9. 学习OpenCV:滤镜系列(15)——羽化(模糊边缘)

    ============================================== 版权所有:小熊不去实验室CSDN博客 ================================== ...

随机推荐

  1. 2019 C/C++《阿里》面试题总结

    一.C和C++的区别是什么? C是面向过程的语言,C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛. C中函数不能进行重载,C++函数可以重载 C++在C的基础上增添类,C是一个结构化语言 ...

  2. day61——多表操作(增、删除、改、基于对象的跨表查询)

    day61 增删改查 增加 # 增加 # 一对一 # au_obj = models.AuthorDetail.objects.get(id=4) models.Author.objects.crea ...

  3. 『Andrew and Chemistry 树同构』

    Andrew and Chemistry Description During the chemistry lesson Andrew learned that the saturated hydro ...

  4. 部署CentOS虚拟机集群

    1.在虚拟机中安装CentOS (1)使用CentOS-6.5-i386-minimal.iso.(2)创建虚拟机:打开Virtual Box,点击“新建”按钮,点击“下一步”,输入虚拟机名称为esh ...

  5. linux或者shell进入vi命令

    vi的基本操作 a) 进入vi     在系统提示符号输入vi及文件名称后,就进入vi全屏幕编辑画面: $ vi file  不过有一点要特别注意,就是您进入vi之后,是处于「命令行模式(comman ...

  6. Django--模型层进阶

    目录 QuerySet对象 可切片 可迭代 惰性查询 缓存机制 何时查询集不会被缓存? exists()与iterator()方法 exists() iterator() 中介模型 查询优化 表数据 ...

  7. 《SAP微顾问和大数据 》公众号管理课程清单

    互联网商业模式创新 电子商务与传统企业转型 “一带一路”信息化:格局与对策 “一带一路”沿线国家主权信用及风险防范 大数据下的资源整合和知识共享 地产数字化改革的痛点与处方 携手共建“一带一路” 数字 ...

  8. vector中的push_back函数的意思是什么

    push_back   就是在vector的末尾插入一个元素, vector 中的erase()函数,从指定容器删除指定位置的元素或者某段范围内的元素,删除之后,返回值也是一个迭代器,指向最后一个删除 ...

  9. shell:echo -e "\033字体颜色"

    格式: echo -e "\033[字背景颜色;字体颜色m字符串\033[0m" 例如: echo -e "\033[41;36m 你好 \033[0m" 其中 ...

  10. Redis特点分析及性能优化

    一.Key >Redis key值是二进制安全的,这意味着可以可以使用任何二进制序列作为key值.空字符串也是有效的key值. >key取值原则 1.键值不需要太长,消耗内存,且在数据中查 ...