• Color Transfer between Images code实现


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

    基本思路是:

    1.给定srcImg和targetImg

    2.将RGB空间转为Lab空间

    3.根据论文中公式:

    计算每一个像素点

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

    效果图:

      

      

    见代码:

      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 }
  • 相关阅读:
    要坚持的好习惯
    Attribute与Property关系
    浅谈ES6中super关键字
    JS权威指南读书笔记(七)
    JS权威指南读书笔记(六)
    JS权威指南读书笔记(五)
    JS权威指南读书笔记(四)
    函数
    对象
    数值
  • 原文地址:https://www.cnblogs.com/xlturing/p/3463813.html
Copyright © 2020-2023  润新知