Color Transfer between Images code实现
上计算机视觉课老师布置的作业实现论文:Color Transfer between Images
基本思路是:
1.给定srcImg和targetImg
2.将RGB空间转为Lab空间
3.根据论文中公式:
计算每一个像素点
4.将resultImg转回到RGB空间显示
效果图:


见代码:
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <math.h>
using namespace std;
using namespace cv; class ColorTransfer
{
public:
Mat resultImg; ColorTransfer(Mat src, Mat target)
{
src.convertTo(srcImg_32F, CV_32FC3,1.0f/.f);//这里切记要类型转换下
target.convertTo(targetImg_32F, CV_32FC3, 1.0f/255.0f);
resultImg = srcImg_32F; //将结果先初始化为源图像 srcImg_Lab = RGBToLab(srcImg_32F);
targetImg_Lab = RGBToLab(targetImg_32F);
srcMeans = computeMeans(srcImg_Lab);
targetMeans = computeMeans(targetImg_Lab);
srcVariances = computeVariances(srcImg_Lab, srcMeans);
targetVariances = computeVariances(targetImg_Lab, targetMeans);
computeResult();
} private:
//读入的RGB图像
Mat srcImg_32F;
Mat targetImg_32F;
//转换后的Lab空间图像
Mat srcImg_Lab;
Mat targetImg_Lab;
//计算得到的均值和方差
Vector<double> srcMeans;
Vector<double> targetMeans;
Vector<double> srcVariances;
Vector<double> targetVariances; //RGB转换到Lab空间
Mat RGBToLab(Mat m)
{
Mat_<Vec3f> I = m;
for(int i=;i<I.rows;++i)
{
for(int j=;j<I.cols;++j)
{
double L = 0.3811*I(i,j)[] + 0.5783*I(i,j)[] + 0.0402*I(i,j)[];
double M = 0.1967*I(i,j)[] + 0.7244*I(i,j)[] + 0.0782*I(i,j)[];
double S = 0.0241*I(i,j)[] + 0.1288*I(i,j)[] + 0.8444*I(i,j)[];
if(L == ) L = ;
if(M == ) M = ;
if(S == ) S = ;
L = log(L);
M = log(M);
S = log(S); I(i,j)[] = (L+M+S) / sqrt(3.0);
I(i,j)[] = (L+M-*S) / sqrt(6.0);
I(i,j)[] = (L-M) / sqrt(2.0);
}
} return I;
} //Lab转换到RGB空间
Mat LabToRGB(Mat m)
{
Mat_<Vec3f> I = m;
for(int i=;i<I.rows;++i)
for(int j=;j<I.cols;++j)
{
double L = I(i,j)[]/sqrt(3.0) + I(i,j)[]/sqrt(6.0) + I(i,j)[]/sqrt(2.0);
double M = I(i,j)[]/sqrt(3.0) + I(i,j)[]/sqrt(6.0) - I(i,j)[]/sqrt(2.0);
double S = I(i,j)[]/sqrt(3.0) - *I(i,j)[]/sqrt(6.0); L = exp(L);
M = exp(M);
S = exp(S); I(i,j)[] = 4.4679*L - 3.5873*M + 0.1193*S;
I(i,j)[] = -1.2186*L + 2.3809*M - 0.1624*S;
I(i,j)[] = 0.0497*L - 0.2439*M + 1.2045*S;
} return I;
} Vector<double> computeMeans(Mat m)
{
double sum[] = { };
int pixes = m.cols * m.rows;
Vector<double> means;
means.resize();
Mat_<Vec3f> I = m; for(int i=;i<I.rows;++i)
for(int j=;j<I.cols;++j)
{
for(int k = ;k < ;k++)
{
sum[k] += I(i,j)[k];
}
} for(int i = ;i < ;i++)
{
means[i] = sum[i] / pixes;
} return means;
} Vector<double> computeVariances(Mat m, Vector<double> means)
{
double sum[] = { };
int pixes = m.cols * m.rows;
Mat_<Vec3f> I = m;
Vector<double> variances;
variances.resize(); for(int i=;i<I.rows;++i)
for(int j=;j<I.cols;++j)
{
for(int chanel = ;chanel < ;chanel++)
{
sum[chanel] += abs(I(i,j)[chanel] - means[chanel]);
}
} for(int i = ;i < ;i++)
{
variances[i] = sqrt(sum[i] / pixes);
} return variances;
} void computeResult()
{
Mat_<Vec3f> I = resultImg;
double dataTemp[] = { }; for(int chanel =;chanel < ;chanel++)
{
dataTemp[chanel] = targetVariances[chanel] / srcVariances[chanel];
} for(int i=;i<I.rows;++i)
for(int j=;j<I.cols;++j)
{
for(int chanel = ;chanel < ;chanel++)
{
I(i,j)[chanel] = dataTemp[chanel] * (I(i,j)[chanel]-srcMeans[chanel]) + targetMeans[chanel];
}
}
resultImg = LabToRGB(resultImg);
}
}; int main()
{
Mat src = imread("11.jpg");
namedWindow("src");
imshow("src", src);
Mat target = imread("12.jpg");
namedWindow("target");
imshow("target", target);
ColorTransfer clt(src,target);
namedWindow("result");
imshow("result", clt.resultImg);
Mat saveImg;
clt.resultImg.convertTo(saveImg,CV_8U, 255.0, /255.0);//imwrite函数只支持8bit和16bit,前面将图像转为了float,保存前要转换
imwrite("result.jpg",saveImg); waitKey();
return ;
}
Color Transfer between Images code实现的更多相关文章
- 快速 图片颜色转换迁移 Color Transfer Opencv + Python
Super fast color transfer between images About a month ago, I spent a morning down at the beach, w ...
- Maven-008-Nexus 私服部署发布报错 Failed to deploy artifacts: Failed to transfer file: ... Return code is: 4XX, ReasonPhrase: ... 解决方案
我在部署构件至 maven nexus 私服时,有时会出现 Failed to deploy artifacts: Failed to transfer file: ... Return code i ...
- QA:Failed to deploy artifacts from/to snapshots XX Failed to transfer file Return code is: 405, ReasonPhrase:Method Not Allowed.
QA: Failed to deploy artifacts from/to snapshots XX Failed to transfer file Return code is: 405, Rea ...
- Machine code transfer into assembly code
#include <stdio.h> const char shell[]="\x0f\x01\xf8\xe8\5\0\0\0\x0f\x01\xf8\x48\xcf" ...
- Visual Studio Code 如何编写运行 C、C++ 程序?
0. 前言 VS Code 是微软发布一款跨平台的源代码编辑器,其拥有强大的功能和丰富的扩展,使之能适合编写许多语言. 本文面向初学者(但不是纯小白),分享一点我配置C/C++的经验. 本文所有内容均 ...
- maven报错:Return code is: 501 , ReasonPhrase:HTTPS Required
今天把一个去年没做完的项目翻出来做时,发现maven无法正常导入依赖.检查了一遍项目配置,没发现有什么问题.而且依赖在本地仓库存在. 随后发现报错:Failed to transfer file:** ...
- RGB Color Codes Chart
RGB Color Codes Chart RGB颜色空间 RGB颜色空间或RGB颜色系统,从红色.绿色和蓝色的组合中构造所有颜色. 红色.绿色和蓝色各使用8位,它们的整数值从0到255.这使得256 ...
- {ICIP2014}{收录论文列表}
This article come from HEREARS-L1: Learning Tuesday 10:30–12:30; Oral Session; Room: Leonard de Vinc ...
- C#读取图片Exif信息
Exif是可交换图像文件的缩写,是专门为数码相机的照片设定的,可以记录数码照片的属性和拍摄数据 ////调用 //string strFile="fffff.jpg";//文件名 ...
随机推荐
- OpenGL Insights 阅读有感 - Tile Based架构下的性能调校 翻译
Performance Tunning for Tile-Based Architecture Tile-Based架构下的性能调校 by Bruce Merry GameKnife译 译序 在大概1 ...
- DBUtils 笔记
一.DBUtils介绍 apache 什么是dbutils,它的作用 DBUtils是java编程中的数据库操作实用工具,小巧简单实用. DBUtils封装了对JDBC的操作,简化了JDBC操作.可 ...
- >hibernate初认识
一.什么是hibernate 1.hibernate是java领域的一款开源的ORM框架技术 2.hibernate对JDBC进行了非常轻量级的封装(使用了反射机制+配置或注解) 二.hibernat ...
- Daily Scrum02 12.14
大家已经被各种作业折磨得体无完肤了,但是大家还挤出时间完成每天的软件工作啊…… 坚持就是胜利! Member 任务进度 下一步工作 吴文会 调试QuerySetting类函数 调试QuerySetti ...
- final 评论ii
按照演讲顺序 1.约跑app 约跑app,从界面的单调,到最后的final发布,实现界面的友好性,有了很大的提高.约跑app,如果在约定地点可以显示出,所在位置,以及约定地址.就可以达 ...
- Ajax是如何运行的?
1.我们需要知道什么是Ajax: AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现 ...
- CSS 基础语法
注:CSS对大小写不敏感,但是如果涉及到与HTML文档一起工作的时候,class和id名称对大小写是敏感的 一.color color:#ff0000; color:#f00; //缩写 color: ...
- Hadoop学习笔记—8.Combiner与自定义Combiner
一.Combiner的出现背景 1.1 回顾Map阶段五大步骤 在第四篇博文<初识MapReduce>中,我们认识了MapReduce的八大步凑,其中在Map阶段总共五个步骤,如下图所示: ...
- ASP.Net请求处理机制初步探索之旅 - Part 1 前奏
开篇:ASP.Net是一项动态网页开发技术,在历史发展的长河中WebForm曾一时成为了ASP.Net的代名词,而ASP.Net MVC的出现让这项技术更加唤发朝气.但是,不管是ASP.Net Web ...
- .Net开发笔记(二十)创建一个需要授权的第三方组件
在使用需要授权的软件时,注册付费的目标是软件的使用者,我们开发人员平时用到的一些第三方组件也是需要授权付费的,也就是说,付费者是开发人员,并不是系统(使用了该第三方组件)的最终使用者. 以上两者的区别 ...