welsh颜色迁移算法实现过程
2016-08-01 15:48
232 查看
最近研究了一下color transfer的相关内容,自从实现了Reinhard经典颜色迁移算法后,便思考着能编写代码实现第二个经典算法:welsh算法,本人在编写调试大概一周才终于实现了出来。
welsh算法基本思想:
1.将目标图像和样本图像转换到Lab空间;
2.对目标图像和样本图像进行亮度重映射,保证后续的像素匹配正确进行;
3.从参考图片中选择一部分样本点,将这些样本点的像素亮度值L和领域亮度值σ得方差保存起来,作为权值W,W = L/2 + σ/2;
4.对目标图像进行逐像素扫描,对每个像素,计算其权值W,即为亮度值L和领域亮度值σ之和然后除以2,然后在第三步得到的样本点钟找到与其权值最接近的参考点,并将改点的a通道和b通道的值赋给目标图像的像素。
5.将图像从Lab空间转化到RGB空间。
下面来看代码:
在这个文件中,用到一些数值我直接定义出来了:
关于亮度重映射和色彩空间的转换我就不贴代码了,这块比较简单。
这部分代码的作用是进行匹配和色彩迁移,geindex函数为匹配过程,即在参考点中找出最佳匹配点,然后就可以对其a通道和b通道赋值。
在实现像素匹配的时候,因为参考点需要不断进行搜索匹配,因此笔者将参考点按权值进行排序,这样速度可以提高很多(搜索速度由N减少到logN)。
处理结果:
整个代码的资源:http://download.csdn.net/detail/zsy162534/9591962
welsh算法基本思想:
1.将目标图像和样本图像转换到Lab空间;
2.对目标图像和样本图像进行亮度重映射,保证后续的像素匹配正确进行;
3.从参考图片中选择一部分样本点,将这些样本点的像素亮度值L和领域亮度值σ得方差保存起来,作为权值W,W = L/2 + σ/2;
4.对目标图像进行逐像素扫描,对每个像素,计算其权值W,即为亮度值L和领域亮度值σ之和然后除以2,然后在第三步得到的样本点钟找到与其权值最接近的参考点,并将改点的a通道和b通道的值赋给目标图像的像素。
5.将图像从Lab空间转化到RGB空间。
下面来看代码:
class Reference { public: float weight; int a; int b; Reference(float weight,int a,int b) { this->weight = weight; this->a = a; this->b = b; } };将类命名为Reference,一共有三个变量,weight表示权值,a和b表示Lab通道中的a通道和bg通道的值,这里我并没有保存像素的坐标信息,因为坐标信息对后续的算法没什么帮助。
在这个文件中,用到一些数值我直接定义出来了:
const int Number = -1; const int Domain = 7; const double Alpha = 0.5;Number表示取参考点的个数,例如Number=20,则表示在图像上要取400个点,即在图像行和列方向分别画20条直线,线的交点即为参考点的位置,当然也可设置为随机取参考点,当Number=-1时表示将参考图像所有点都作为参考点。
double getstatis(int x,int y,IplImage* image) { int number = 0; vector<int> vec; for(int i=x - Domain/2;i<=x + Domain/2;i++) { uchar *ptr = (uchar*)(image->imageData+i*image->widthStep); for(int j=y-Domain/2;j<=y+Domain/2;j++) { if(i<0||i>=image->height||j<0||j>=image->width) { continue; } int light = ptr[3*j]; vec.push_back(light); } } uchar *ptr = (uchar*)(image->imageData+x*image->widthStep); int light = ptr[3*y]; return (light*Alpha+(1-Alpha)*(getstd(vec))); }其中getstd函数为获取vec的方差,这整个函数的作用是获取位于图像image上(x,y)位置的像素的权值,Alpha的值决定了亮度和方差的比重,在上述步骤中Alpha为0.5.
关于亮度重映射和色彩空间的转换我就不贴代码了,这块比较简单。
for(int i = 0,information = 1,coutinf = 0;i<secondLabClone->height;i++,coutinf++) { uchar* ptr = (uchar*)(secondLab->imageData+i*secondLab->widthStep); if(coutinf == secondLabClone->height/10) { coutinf = 0; cout<<"proceeding----"<<information<<"/10"<<"---"<<endl; information++; } for(int j=0;j<secondLabClone->width;j++) { float weight = getstatis(i,j,secondLabClone); int index = getindex(references,weight); ptr[3*j+1] = references[index].a; ptr[3*j+2] = references[index].b; } }
这部分代码的作用是进行匹配和色彩迁移,geindex函数为匹配过程,即在参考点中找出最佳匹配点,然后就可以对其a通道和b通道赋值。
在实现像素匹配的时候,因为参考点需要不断进行搜索匹配,因此笔者将参考点按权值进行排序,这样速度可以提高很多(搜索速度由N减少到logN)。
处理结果:
整个代码的资源:http://download.csdn.net/detail/zsy162534/9591962
相关文章推荐
- python opencv 实现Reinhard颜色迁移算法
- 颜色迁移之三——Welsh经典算法
- 数字图像处理——直方图均衡化与颜色迁移算法的c++实现
- Dijkstra算法-(迪杰斯特拉)算法的迭代实现与优先队列实现 图解算法过程
- 12-2 今天论文进展 1. 算法传递的过程考虑解决了 用c浅lone 2.手机上实现了 和 几个点的检测算法
- 多级树集合分裂(SPIHT)算法的过程详解与Matlab实现(6)解码过程——主程序
- 多级树集合分裂(SPIHT)算法的过程详解与Matlab实现(7)解码过程——扫描解码
- 多级树集合分裂(SPIHT)算法的过程详解和Matlab实现(2)数学表述
- OpenCV中图像旋转(warpAffine)算法的实现过程
- OpenCV中图像旋转(warpAffine)算法的实现过程
- 从算法入手讲解SQL Server典例实现过程
- 算法实现过程
- 实现RGB,CMY(K),YUV,YIQ,YCbCr颜色的转换算法
- 【后缀表达式的计算思想、过程以及算法实现】
- 【栈】十进制转换成二进制的过程及算法实现
- 图片拼接镶嵌算法(image spline and mosaics经典算法)实现过程和效果展示
- 多级树集合分裂(SPIHT)算法的过程详解与Matlab实现(1)算法概述
- C#实现WORD颜色下拉框控件全过程
- [arcengine+geoProcessor]相交多边形的算法分析过程与实现
- 【中缀转换成后缀或者前缀的思想、过程以及算法实现】