您的位置:首页 > 其它

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空间。

下面来看代码:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息