上计算机视觉课老师布置的作业实现论文: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实现的更多相关文章

  1. 快速 图片颜色转换迁移 Color Transfer Opencv + Python

      Super fast color transfer between images About a month ago, I spent a morning down at the beach, w ...

  2. 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 ...

  3. 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 ...

  4. 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" ...

  5. Visual Studio Code 如何编写运行 C、C++ 程序?

    0. 前言 VS Code 是微软发布一款跨平台的源代码编辑器,其拥有强大的功能和丰富的扩展,使之能适合编写许多语言. 本文面向初学者(但不是纯小白),分享一点我配置C/C++的经验. 本文所有内容均 ...

  6. maven报错:Return code is: 501 , ReasonPhrase:HTTPS Required

    今天把一个去年没做完的项目翻出来做时,发现maven无法正常导入依赖.检查了一遍项目配置,没发现有什么问题.而且依赖在本地仓库存在. 随后发现报错:Failed to transfer file:** ...

  7. RGB Color Codes Chart

    RGB Color Codes Chart RGB颜色空间 RGB颜色空间或RGB颜色系统,从红色.绿色和蓝色的组合中构造所有颜色. 红色.绿色和蓝色各使用8位,它们的整数值从0到255.这使得256 ...

  8. {ICIP2014}{收录论文列表}

    This article come from HEREARS-L1: Learning Tuesday 10:30–12:30; Oral Session; Room: Leonard de Vinc ...

  9. C#读取图片Exif信息

    Exif是可交换图像文件的缩写,是专门为数码相机的照片设定的,可以记录数码照片的属性和拍摄数据 ////调用 //string strFile="fffff.jpg";//文件名 ...

随机推荐

  1. spring注解配置实例

    在spring中使用注解配置前需要先在配置文件指定需要扫描的包. 通过注解的方式依赖注入,可以不用创建set方法,也不用在xml文件中申明注入关系. 实例结构如下: 整个流程是: 先创建好数据库的表对 ...

  2. 【转】【10g SQL新特性】q-quote使用

    转自:http://blog.chinaunix.net/uid-7655508-id-3684042.html 转发只为留存学习 在Oracle中,字符串的字面量如果含有单引号,那么必须转义,而且转 ...

  3. 安卓中的Model-View-Presenter模式介绍

    转载自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0425/2782.html 英文原文:Introduction to M ...

  4. JS 判断字串字节数,并截取长度

    var matchWords;         function notifyTextLength() {             var inputNum = document.getElement ...

  5. .NET C#-- 利用BeginInvoke与EndInvoke完成异步委托方法并获取方法执行返回值示例

    //定义委托 delegate string MyDelegate(string name); //定义委托调用函数 public string Hello(string name) { Thread ...

  6. 20145337 GDB调试汇编堆栈过程分析

    20145337 GDB调试汇编堆栈过程分析 测试代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const ...

  7. TreeView 使用方法:(在View.Details模式下)

    1.建立TreeView的標題         2.建立TreeView的Item         3.在TreeView的Item中的建立SubItem                  如果將各部 ...

  8. .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

  9. 顶级的JavaScript框架、库、工具及其使用

    几乎每隔一个星期,就有一个新的 JavaScript 库席卷网络社区!Web 社区日益活跃.多样,并在多个领域快速成长.想要研究每一个重要的 JavaScript 框架和库,是个不可能完成的任务.接下 ...

  10. How.To.Process.Image.Infomation.Of.Rotate.And.Flip.From.Server

    需求说明 客户端接收到服务器传送过来的图像数据,客户端通过对图像进行旋转和反转操作. 然后把这个旋转和反转的数据上传到服务器. 客户端在接收图像的时候, 也会下载以前的旋转和反转参数, 然后客户端根据 ...