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;
}
输入图片:
参考图片:
效果图片: