color transfer between images论文实现
2016-01-28 20:28
387 查看
今天闲来无事把经典的颜色迁移文章来拿看看,突然发现自己还没动手实现过color transfer between images这篇文章,想当初自己的毕业设计就是做的这个,真是有点惭愧。
关于这篇文章的代码网上有很多,但是我找了很久,发现现在网上的代码有一个通病,一个是很乱,另一个是很多都是转载的,作者自己肯定都不太清楚是什么代码就转过来了,结果误导了很多想学习的好同志,所以决定以后养成好习惯,遇到好的代码要自己记下来,或者发到博客上一遍保存和以后自己拿出来翻看。
有一篇比较好的文章是在rachel-zhang(我的女神)的博客上看到的,代码写的非常清晰,模块也分得很好,几分钟就看明白了,不过她的代码都是在RGB空间直接进行颜色迁移的,代码如下:
其中输入图片为
![](http://img.blog.csdn.net/20160128210318589?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
样本图片为:
![](http://img.blog.csdn.net/20160128210335972?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
使用上诉代码的运行结果为:(忽略图片大小问题,为了便于排版所有图片均为截图)
![](http://img.blog.csdn.net/20160128210400590?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
但是color transfer between images论文提到的方法需要把图片转换到LAB空间,所以我就想大概转换到LAB空间之后处理的效果会不一样,所以对代码稍作修改,改为下面的:
还是用上面的图片,不过结果稍有不同:
![](http://img.blog.csdn.net/20160128210421972?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
可以看到结果差别还是有的,迁移之后的图像效果更好。
关于这篇文章的代码网上有很多,但是我找了很久,发现现在网上的代码有一个通病,一个是很乱,另一个是很多都是转载的,作者自己肯定都不太清楚是什么代码就转过来了,结果误导了很多想学习的好同志,所以决定以后养成好习惯,遇到好的代码要自己记下来,或者发到博客上一遍保存和以后自己拿出来翻看。
有一篇比较好的文章是在rachel-zhang(我的女神)的博客上看到的,代码写的非常清晰,模块也分得很好,几分钟就看明白了,不过她的代码都是在RGB空间直接进行颜色迁移的,代码如下:
#include "iostream" #include <opencv2\opencv.hpp> #include <highgui.h> using namespace std; IplImage* Transform(IplImage* A,CvScalar avg_src, CvScalar avg_dst,CvScalar std_src, CvScalar std_dst) { for(int i=0;i<3;i++) { for(int x=0;x<A->height;x++) { uchar *ptr=(uchar*)(A->imageData+x*A->widthStep); for(int y=0;y<A->width;y++) { double tmp=ptr[3*y+i]; int t=(int)((tmp-avg_dst.val[i])*(std_src.val[i]/std_dst.val[i])+avg_src.val[i]); t = t<0?0:t; t = t>255?255:t; ptr[3*y+i]=t; } } } return A; } int main() { //load IplImage* source = cvLoadImage("..\\Images\\snow.jpeg",CV_LOAD_IMAGE_COLOR); IplImage* dst = cvLoadImage("..\\Images\\grass.jpg",CV_LOAD_IMAGE_COLOR); IplImage* dstlab = cvCreateImage(cvGetSize(dst),dst->depth,dst->nChannels); IplImage* res = cvCreateImage(cvGetSize(dst),dst->depth,dst->nChannels); dstlab = cvCloneImage(dst); //calculate average and standard derivation CvScalar avg_src,avg_dst,std_src, std_dst; cvAvgSdv(source,&avg_src,&std_src); cvAvgSdv(dstlab, &avg_dst, &std_dst); //transform dstlab = Transform(dstlab,avg_src,avg_dst,std_src, std_dst); res = cvCloneImage(dstlab); cvSaveImage("..\\Images\\out.jpg",res); cvWaitKey(); cvReleaseImage(&source); cvReleaseImage(&dst); cvReleaseImage(&dstlab); cvReleaseImage(&res); getchar(); }代码很简单,就一个函数调用,直接对每个像素进行均值和方差的运算,最后得到输出图像
其中输入图片为
样本图片为:
使用上诉代码的运行结果为:(忽略图片大小问题,为了便于排版所有图片均为截图)
但是color transfer between images论文提到的方法需要把图片转换到LAB空间,所以我就想大概转换到LAB空间之后处理的效果会不一样,所以对代码稍作修改,改为下面的:
#include <highgui.h> #include <cv.h> #include <iostream> using namespace std; IplImage* Transform(IplImage* A,CvScalar avg_dst,CvScalar avg_src, CvScalar std_dst,CvScalar std_src) { for(int i=0;i<3;i++) { for(int x=0;x<A->height;x++) { uchar *ptr=(uchar*)(A->imageData+x*A->widthStep); for(int y=0;y<A->width;y++) { double tmp=ptr[3*y+i]; int t=(int)((tmp-avg_dst.val[i])*(std_src.val[i]/std_dst.val[i])+avg_src.val[i]); t = t<0?0:t; t = t>255?255:t; ptr[3*y+i]=t; } } } return A; } int main() { IplImage *src = cvLoadImage("grass.jpg",CV_LOAD_IMAGE_COLOR); IplImage *dst = cvLoadImage("snow.jpeg",CV_LOAD_IMAGE_COLOR); IplImage *out = cvCreateImage(cvGetSize(src),src->depth,src->nChannels); cvNamedWindow("first",CV_WINDOW_AUTOSIZE); cvNamedWindow("good",CV_WINDOW_AUTOSIZE); cvShowImage("first",src); cvShowImage("good",dst); IplImage *srclab = cvCreateImage(cvGetSize(src),src->depth,src->nChannels); IplImage *dstlab = cvCreateImage(cvGetSize(dst),dst->depth,dst->nChannels); cvCvtColor(src,srclab,CV_BGR2Lab); cvCvtColor(dst,dstlab,CV_BGR2Lab); CvScalar avg_src,avg_dst,std_src, std_dst; cvAvgSdv(srclab,&avg_src, &std_src); cvAvgSdv(dstlab,&avg_dst, &std_dst); cout<<"hello"<<endl; out = Transform(srclab,avg_src,avg_dst,std_src,std_dst); IplImage* outimage = cvCreateImage(cvGetSize(src),src->depth,src->nChannels); cvCvtColor(out,outimage,CV_Lab2BGR); cvNamedWindow("second",CV_WINDOW_AUTOSIZE); cvShowImage("second",outimage); cvWaitKey(0); cvReleaseImage(&src); cvReleaseImage(&dst); cvReleaseImage(&srclab); cvReleaseImage(&dstlab); cvWaitKey(0); }
还是用上面的图片,不过结果稍有不同:
可以看到结果差别还是有的,迁移之后的图像效果更好。
相关文章推荐
- HTML简介
- 【JSOI2015】字符串树
- html image -- data:image/png;base64
- JsViews Error:Unknown template:“#projectData”
- Rhino -- 基于java的javascript实现
- 【树】Populating Next Right Pointers in Each Node
- 多说使用ua-parser-js显示浏览器和系统信息
- jquery中对CheckBox的操作
- 封装jQuery Validate扩展验证方法
- jQuery Validate验证框架详解
- Javascript 如何访问 和 修改CSS样式(网页样式)
- 浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
- ReactNative使用require引用模块的技巧
- 通过设置Referer反"反盗链"
- 通过设置Referer反"反盗链"
- 前端基本功之选择题
- Referer反反盗链
- IE, FireFox, Opera 浏览器支持CSS实现Alpha透明的方法 兼容问题
- Referer反反盗链
- 11、BaseJsonRes