上计算机视觉课老师布置的作业实现论文:Color Transfer between Images

基本思路是:

1.给定srcImg和targetImg

2.将RGB空间转为Lab空间

3.根据论文中公式:

Color Transfer between Images code实现

计算每一个像素点

4.将resultImg转回到RGB空间显示

 

效果图:

Color Transfer between Images code实现 Color Transfer between Images code实现 Color Transfer between Images code实现

Color Transfer between Images code实现 Color Transfer between Images code实现 Color Transfer between Images code实现

见代码:

  1 #include <opencv2/opencv.hpp>  
  2 #include <opencv2/core/core.hpp>  
  3 #include <opencv2/imgproc/imgproc.hpp>
  4 #include <math.h>
  5 using namespace std;
  6 using namespace cv;
  7 
  8 class ColorTransfer
  9 {
 10 public:
 11     Mat resultImg;
 12 
 13     ColorTransfer(Mat src, Mat target)
 14     {
 15         src.convertTo(srcImg_32F, CV_32FC3,1.0f/255.f);//这里切记要类型转换下
 16         target.convertTo(targetImg_32F, CV_32FC3, 1.0f/255.0f);
 17         resultImg = srcImg_32F;  //将结果先初始化为源图像
 18         
 19         srcImg_Lab = RGBToLab(srcImg_32F);
 20         targetImg_Lab = RGBToLab(targetImg_32F);
 21         srcMeans = computeMeans(srcImg_Lab);
 22         targetMeans = computeMeans(targetImg_Lab);
 23         srcVariances = computeVariances(srcImg_Lab, srcMeans);
 24         targetVariances = computeVariances(targetImg_Lab, targetMeans);
 25         computeResult();
 26     }
 27 
 28 private:
 29     //读入的RGB图像
 30     Mat srcImg_32F;
 31     Mat targetImg_32F;
 32     //转换后的Lab空间图像
 33     Mat srcImg_Lab;
 34     Mat targetImg_Lab;
 35     //计算得到的均值和方差
 36     Vector<double> srcMeans;
 37     Vector<double> targetMeans;
 38     Vector<double> srcVariances;
 39     Vector<double> targetVariances;
 40 
 41     //RGB转换到Lab空间
 42     Mat RGBToLab(Mat m)
 43     {
 44         Mat_<Vec3f> I = m;
 45         for(int i=0;i<I.rows;++i)
 46         {
 47             for(int j=0;j<I.cols;++j)
 48             {
 49                 double L = 0.3811*I(i,j)[0] + 0.5783*I(i,j)[1] + 0.0402*I(i,j)[2];
 50                 double M = 0.1967*I(i,j)[0] + 0.7244*I(i,j)[1] + 0.0782*I(i,j)[2];
 51                 double S = 0.0241*I(i,j)[0] + 0.1288*I(i,j)[1] + 0.8444*I(i,j)[2];
 52                 if(L == 0) L = 1;
 53                 if(M == 0) M = 1;
 54                 if(S == 0) S = 1;
 55                 L = log(L);
 56                 M = log(M);
 57                 S = log(S);
 58             
 59                 I(i,j)[0] = (L+M+S) / sqrt(3.0);
 60                 I(i,j)[1] = (L+M-2*S) / sqrt(6.0);
 61                 I(i,j)[2] = (L-M) / sqrt(2.0);
 62             }
 63         }
 64 
 65         return I;
 66     }
 67 
 68     //Lab转换到RGB空间
 69     Mat LabToRGB(Mat m)
 70     {
 71         Mat_<Vec3f> I = m;
 72         for(int i=0;i<I.rows;++i)
 73         for(int j=0;j<I.cols;++j)
 74         {
 75             double L = I(i,j)[0]/sqrt(3.0) + I(i,j)[1]/sqrt(6.0) + I(i,j)[2]/sqrt(2.0);
 76             double M = I(i,j)[0]/sqrt(3.0) + I(i,j)[1]/sqrt(6.0) - I(i,j)[2]/sqrt(2.0);
 77             double S = I(i,j)[0]/sqrt(3.0) - 2*I(i,j)[1]/sqrt(6.0);
 78 
 79             L = exp(L);
 80             M = exp(M);
 81             S = exp(S);
 82             
 83             I(i,j)[0] = 4.4679*L - 3.5873*M + 0.1193*S;
 84             I(i,j)[1] = -1.2186*L + 2.3809*M - 0.1624*S;
 85             I(i,j)[2] = 0.0497*L - 0.2439*M + 1.2045*S;
 86         }
 87 
 88         return I;
 89     }
 90 
 91     Vector<double> computeMeans(Mat m)
 92     {
 93         double sum[3] = { 0 };
 94         int pixes = m.cols * m.rows;
 95         Vector<double> means;
 96         means.resize(3);
 97         Mat_<Vec3f> I = m;
 98         
 99         for(int i=0;i<I.rows;++i)
100         for(int j=0;j<I.cols;++j)
101         {
102             for(int k = 0;k < 3;k++)
103             {
104                 sum[k] += I(i,j)[k];
105             }
106         }
107 
108         for(int i = 0;i < 3;i++)
109         {
110             means[i] = sum[i] / pixes;
111         }
112 
113         return means;
114     }
115 
116     Vector<double> computeVariances(Mat m, Vector<double> means)
117     {
118         double sum[3] = { 0 };
119         int pixes = m.cols * m.rows;
120         Mat_<Vec3f> I = m;
121         Vector<double> variances;
122         variances.resize(3);
123 
124         for(int i=0;i<I.rows;++i)
125         for(int j=0;j<I.cols;++j)
126         {
127             for(int chanel = 0;chanel < 3;chanel++)
128             {
129                 sum[chanel] += abs(I(i,j)[chanel] - means[chanel]);
130             }
131         }
132 
133         for(int i = 0;i < 3;i++)
134         {
135             variances[i] = sqrt(sum[i] / pixes);
136         }
137 
138         return variances;
139     }
140 
141     void computeResult()
142     {
143         Mat_<Vec3f> I = resultImg;
144         double dataTemp[3] = { 0 };
145         
146         for(int chanel =0;chanel < 3;chanel++)
147         {
148             dataTemp[chanel] = targetVariances[chanel] / srcVariances[chanel];
149         }
150         
151         for(int i=0;i<I.rows;++i)
152         for(int j=0;j<I.cols;++j)
153         {
154             for(int chanel = 0;chanel < 3;chanel++)
155             {
156                 I(i,j)[chanel] = dataTemp[chanel] * (I(i,j)[chanel]-srcMeans[chanel]) + targetMeans[chanel];
157             }
158         }
159         resultImg = LabToRGB(resultImg);
160     }
161 };
162 
163 int main()
164 {
165     Mat src = imread("11.jpg");
166     namedWindow("src");  
167     imshow("src", src); 
168     Mat target = imread("12.jpg");
169     namedWindow("target");
170     imshow("target", target);
171     ColorTransfer clt(src,target);
172     namedWindow("result");
173     imshow("result", clt.resultImg);
174     Mat saveImg;
175     clt.resultImg.convertTo(saveImg,CV_8U, 255.0, 1/255.0);//imwrite函数只支持8bit和16bit,前面将图像转为了float,保存前要转换
176     imwrite("result.jpg",saveImg);
177 
178     waitKey(0);
179     return 0;
180 }

 

相关文章:

  • 2021-09-21
  • 2022-02-06
  • 2022-02-10
  • 2021-08-27
  • 2021-09-02
  • 2021-10-06
猜你喜欢
  • 2022-01-04
  • 2021-04-15
  • 2022-12-23
  • 2022-01-11
  • 2022-12-23
  • 2021-09-24
  • 2022-12-23
相关资源
相似解决方案