学习OpenCV:Color Transfer Between Images算法的实现

CV课程的第一次作业就是Color Transfer Between Images算法的实现。

这个算法的用处是,给出两张图片,给第一张图染上第二张图的颜色。输出效果图。

算法流程:

1.首先得到输入图片和参考图片的RGB空间值。

2.把输入图片和参考图片的RGB值转换为lab空间值。

3.得到输入图片和参考图片lab空间下的三通道的标准差和均值。

4.用输入图片减去自身均值再乘上标准差比最后加上参考图片均值的公式得到输入图片最后的lab值

5.从lab空间转换到RGB空间。

#include<highgui.h>
#include<cv.h>
#include<iostream>
#include<cmath>

using namespace std;

int main()
{
	IplImage *srcimg1=cvLoadImage("input.jpg");
	IplImage *srcimg2=cvCreateImage(cvGetSize(srcimg1),srcimg1->depth,srcimg1->nChannels);
	cvCvtColor(srcimg1,srcimg2,CV_BGR2Lab);
	CvMat *out=cvCreateMat(srcimg2->height,srcimg2->width,CV_8UC3);

	IplImage *dstimg1=cvLoadImage("refer.jpg");
	IplImage *dstimg2=cvCreateImage(cvGetSize(dstimg1),dstimg1->depth,dstimg1->nChannels);
	cvCvtColor(dstimg1,dstimg2,CV_BGR2Lab);

	int i,j;
	double mean1[3],mean2[3];
	double var1[3],var2[3];

	for(i=0;i<3;i++)
	{
		mean1[i]=0;
		mean2[i]=0;
		var1[i]=0;
		var2[i]=0;
	}

	CvScalar s;

	for(i=0;i<srcimg2->height;i++)
	{
		for(j=0;j<srcimg2->width;j++)
		{
			s=cvGet2D(srcimg2,i,j);
			mean1[0]=mean1[0]+s.val[0];
			mean1[1]=mean1[1]+s.val[1];
			mean1[2]=mean1[2]+s.val[2];
		}
	}

	for(i=0;i<3;i++)
	{
		mean1[i]=mean1[i]/((srcimg2->height)*(srcimg2->width));
	}

	for(i=0;i<dstimg2->height;i++)
	{
		for(j=0;j<dstimg2->width;j++)
		{
			s=cvGet2D(dstimg2,i,j);
			mean2[0]=mean2[0]+s.val[0];
			mean2[1]=mean2[1]+s.val[1];
			mean2[2]=mean2[2]+s.val[2];
		}
	}

	for(i=0;i<3;i++)
	{
		mean2[i]=mean2[i]/((dstimg2->height)*(dstimg2->width));
	}

	for(i=0;i<srcimg2->height;i++)
	{
		for(j=0;j<srcimg2->width;j++)
		{
			s=cvGet2D(srcimg2,i,j);
			var1[0]=var1[0]+(s.val[0]-mean1[0])*(s.val[0]-mean1[0]);
			var1[1]=var1[1]+(s.val[1]-mean1[1])*(s.val[1]-mean1[1]);
			var1[2]=var1[2]+(s.val[2]-mean1[2])*(s.val[2]-mean1[2]);
		}
	}

	for(i=0;i<3;i++)
	{
		var1[i]=sqrt(var1[i]/((srcimg2->width)*(srcimg2->height)));
		//cout<<var1[i]<<endl;
	}

	for(i=0;i<dstimg2->height;i++)
	{
		for(j=0;j<dstimg2->width;j++)
		{
			s=cvGet2D(dstimg2,i,j);
			var2[0]=var2[0]+(s.val[0]-mean2[0])*(s.val[0]-mean2[0]);
			var2[1]=var2[1]+(s.val[1]-mean2[1])*(s.val[1]-mean2[1]);
			var2[2]=var2[2]+(s.val[2]-mean2[2])*(s.val[2]-mean2[2]);
		}
	}

	for(i=0;i<3;i++)
	{
		var2[i]=sqrt(var2[i]/((dstimg2->width)*(dstimg2->height)));
		//cout<<var2[i]<<endl;
	}

	for(i=0;i<srcimg2->height;i++)
	{
		for(j=0;j<srcimg2->width;j++)
		{
			s=cvGet2D(srcimg2,i,j);
			s.val[0]=(s.val[0]-mean1[0])*(var2[0]/var1[0])+mean2[0];
			s.val[1]=(s.val[1]-mean1[1])*(var2[1]/var1[1])+mean2[1];
			s.val[2]=(s.val[2]-mean1[2])*(var2[2]/var1[2])+mean2[2];
			cvSet2D(srcimg2,i,j,s);
		}
	}

	IplImage *srcimg3=cvCreateImage(cvGetSize(srcimg1),srcimg1->depth,srcimg1->nChannels);
	cvCvtColor(srcimg2,srcimg3,CV_Lab2BGR);
	cvNamedWindow("result",1);
	cvNamedWindow("input",1);
	cvNamedWindow("refer",1);
	cvShowImage("input",srcimg1);
	cvShowImage("refer",dstimg1);
	cvShowImage("result",srcimg3);
	cvWaitKey(0);
	cvReleaseImage(&srcimg1);
	cvReleaseImage(&srcimg3);
	cvReleaseImage(&dstimg1);
	cvDestroyWindow("input");
	cvDestroyWindow("refer");
	cvDestroyWindow("result");

	return 0;
}
输入图片:



参考图片:


效果图片:


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值