Color Transfer Between Image

Color Transfer Between Image

      Color Transfer Between Images算法中,给定两张图片source_img和target_img。该算法可以把source_img中的颜色迁移到target_img中。

算法主要思路为:

  1. 给定输入图像source_img和target_img
  2. 把source_img和target_img转换到Lab颜色空间,转换后图像为source_lab和target_lab
  3. 分别计算source_Lab和target_lab三个通道的均值和标准差
  4. 根据论文中的公式,分别计算三通道的变换值:

       

         5. 把Lab空间的结果图像再转换到RGB空间,并显示

        Lab转RGB空间和RGB转LAB空间,可以参考之前写的博文:RGB与Lab颜色空间互相转换


算法关键代码实现:

	RGB2Lab(source_img,source_lab);
	RGB2Lab(target_img,target_lab);

	
	source_Mean = ConputerMean(source_lab,source_height,source_width,source_line_byte);
	target_Mean = ConputerMean(target_lab,target_height,target_width,target_line_byte);

	source_Labvar = ConputerVar(source_height,source_width,source_Mean);
	target_Labvar = ConputerVar(target_height,target_width,target_Mean);

	Color_Transform_Func(target_lab,source_Labvar,target_Labvar,source_Mean,target_Mean,target_height,target_width,target_line_byte);

	bmp =  Lab2RGB(target_img,target_lab);

	fwrite(bmp, target_line_byte*target_height, 1, Color_Transform_BMP_fp);
        fclose(Color_Transform_BMP_fp);  
        free(Color_Transform_BMP);
	free(bmp);

    return 0;


计算均值和方差关键代码:


LABMEAN ConputerMean(float *lab_img,DWORD height,DWORD width,T_U32 line_byte)
{
	double LMean,aMean,bMean,SumL,SumA,SumB,SumL2,SumA2,SumB2,TmpL,TmpA,TmpB,size,l,a,b;
	DWORD i,j,index;
	LABMEAN labMean = {0};


	LMean = 0.0;
	aMean =0;
	bMean=0.0;
	SumL = 0;
	SumA = 0;
	SumB = 0;
	SumL2 = 0.0;
	SumA2 = 0.0;
	SumB2 = 0.0;
	TmpL = 0;
	TmpA = 0.0;
	TmpB = 0;
	size = width*height;


	for(i = 0; i < height;i++)
	{
		for(j = 0;j < width;j++)
		{
			index = i*line_byte+3*j;

			TmpL = lab_img[index+0];
			SumL  += TmpL;
			SumL2 += TmpL*TmpL;


			TmpA = lab_img[index+1];
			SumA  += TmpA;
			SumA2 += TmpA*TmpA;

			TmpB = lab_img[index+2];
			SumB  += TmpB;
			SumB2 += TmpB*TmpB;
		}
	}

	LMean = SumL/(size);
	aMean = SumA/(size);
	bMean = SumB/(size);

	labMean.MeanL = LMean;
	labMean.MeanA = aMean;
	labMean.MeanB = bMean;

	labMean.SumL = SumL;
	labMean.SumA = SumA;
	labMean.SumB = SumB;

	labMean.SumL2 = SumL2;
	labMean.SumA2 = SumA2;
	labMean.SumB2 = SumB2;
	
	return labMean;
}

LABVAR ConputerVar(DWORD height,DWORD width,LABMEAN labMean)
{
	double LVar,aVar,bVar,size;
	LABVAR labvar = {0};

    LVar = 0.0;
	aVar = 0.;
	bVar = 0.0;
	size = width*height;

	LVar = (labMean.SumL2-(labMean.SumL*labMean.SumL)/size)/size;
	aVar = (labMean.SumA2-(labMean.SumA*labMean.SumA)/size)/size;
	bVar = (labMean.SumB2-(labMean.SumB*labMean.SumB)/size)/size;

	LVar = sqrt(LVar);
	aVar = sqrt(aVar);
	bVar = sqrt(bVar);

	labvar.VarL = LVar;
	labvar.VarA = aVar;
	labvar.VarB = bVar;

	return labvar;
}




颜色转换关键代码实现:

void Color_Transform_Func(float *lab_img,LABVAR source_var,LABVAR target_var,LABMEAN source_mean,LABMEAN target_mean,DWORD height,DWORD width,T_U32 line_byte)
{
	int i,j,index;

	for(i = 0; i < height;i++)
	{
		for(j = 0;j < width;j++)
		{
			 index = i*line_byte+3*j;
			 lab_img[index+0] -= target_mean.MeanL;
			 lab_img[index+1] -= target_mean.MeanA;
			 lab_img[index+2] -= target_mean.MeanB;


			 lab_img[index+0] = (target_var.VarL/source_var.VarL)*lab_img[index+0];
			 lab_img[index+1] = (target_var.VarA/source_var.VarA)*lab_img[index+1];
			 lab_img[index+2] = (target_var.VarB/source_var.VarB)*lab_img[index+2];


			 lab_img[index+0] += source_mean.MeanL;
			 lab_img[index+1] += source_mean.MeanA;
			 lab_img[index+2] += source_mean.MeanB;

		}
	}

}



图像结果:


     左图为source_img,又图为target_img


结果图像




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值