welsh颜色迁移算法实现过程

最近研究了一下color transfer的相关内容,自从实现了Reinhard经典颜色迁移算法后,便思考着能编写代码实现第二个经典算法:welsh算法,本人在编写调试大概一周才终于实现了出来。


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




  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值