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";//文件名 ...
随机推荐
- CF2.C(二分贪心)
C. Road to Cinema time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- dialog
function showDialog(){ var $by = $(window), obj = $('.dialog'), brsW = $by.width(), brsH = $by.heigh ...
- 18个演讲PPT技巧,让你成为真正的演讲高手
如何成为一个演讲高手呢?在现在这个年代,PPT是必不可少的,乔布斯的经典演讲就是使用大屏幕幻灯片.下面的18个技巧或许可以帮助你提高PPT演讲技巧. (1)10-20-30原则 这是Guy Kawas ...
- 利用history实现无刷新跳转界面
看标题是不是感觉很拽的样子,其实没什么啦,也就是时下常说的单页面应用.这种web形式在如今的移动端十分流行,毕竟在移动端频繁得去刷新界面不是很友好,而且还费流量.今天我们要做一个小的app(移动端), ...
- ENode框架Conference案例分析系列之 - 上下文划分和领域建模
前面一片文章,我介绍了Conference案例的核心业务,为了方便后面的分析,我这里再列一下: 业务描述 Conference是这样一个系统,它提供了一个在线创建会议以及预订会议座位的平台.这个系统的 ...
- 让Chrome 接管邮件连接,收发邮件更方便了
页面中除了传统的超链接外,还可以将邮箱地址写入<a>标签,意思不表自明,当然是用户点击后就会打开相应的邮件客户端向这个连接指向的邮件地址发邮件. <a href="mail ...
- spring快速入门(四)
一.在spring快速入门(三)的基础上,我们来了解BeanFactory及配置. Client package com.murong.client; import org.springframewo ...
- Atitit xml命名空间机制
Atitit xml命名空间机制 命名冲突1 使用前缀来避免命名冲突2 使用命名空间(Namespaces)2 XML Namespace (xmlns) 属性2 默认的命名空间(Default Na ...
- Oracle 多行转多列,列值转为列名
前段时间做调查问卷,客户创建自定义问卷内容,包括题目和选项内容; 之后需要导出问卷明细,,,,麻烦来咯 于是到网上到处搜索,没有直接结果;于是又找各种相似的,,终于功夫不负有心人 然后最终自己写出来了 ...
- iOS-多线程基础
进程与线程: 1> 一个应用程序对应一个进程,一个进程帮助程序占据一块存储空间 2> 要想在进程中执行任务,就必须开启线程,一条线程就代表一个任务 3> 一个进程中允许开 ...