Demo entry 6785668

c

   

Submitted by zsf on Mar 18, 2019 at 08:43
Language: C++. Code size: 6.1 kB.

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <math.h>
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
using namespace cv;

class ColorTransfer
{
public:
    Mat resultImg;

    ColorTransfer(Mat src, Mat target)
    {
        src.convertTo(srcImg_32F, CV_32FC3,1.0f/255.f);//convertToRGB and normalization
        target.convertTo(targetImg_32F, CV_32FC3, 1.0f/255.0f);
        resultImg = srcImg_32F;  //将结果先初始化为源图像

        srcImg_Lab = RGBToLab(srcImg_32F);
        targetImg_Lab = RGBToLab(targetImg_32F);
        srcMeans = computeMeans(srcImg_Lab);
        targetMeans = computeMeans(targetImg_Lab);
        srcVariances = computeVariances(srcImg_Lab, srcMeans);
        targetVariances = computeVariances(targetImg_Lab, targetMeans);
        computeResult();
    }

private:
    //读入的RGB图像
    Mat srcImg_32F;
    Mat targetImg_32F;
    //转换后的Lab空间图像
    Mat srcImg_Lab;
    Mat targetImg_Lab;
    //计算得到的均值和方差
    Vector<double> srcMeans;
    Vector<double> targetMeans;
    Vector<double> srcVariances;
    Vector<double> targetVariances;

    //RGB转换到Lab空间
    Mat RGBToLab(Mat m)
    {
        Mat_<Vec3f> I = m;
        for(int i=0;i<I.rows;++i)
        {
            for(int j=0;j<I.cols;++j)
            {
                double L = 0.3811*I(i,j)[0] + 0.5783*I(i,j)[1] + 0.0402*I(i,j)[2];
                double M = 0.1967*I(i,j)[0] + 0.7244*I(i,j)[1] + 0.0782*I(i,j)[2];
                double S = 0.0241*I(i,j)[0] + 0.1288*I(i,j)[1] + 0.8444*I(i,j)[2];
                if(L == 0) L = 1;
                if(M == 0) M = 1;
                if(S == 0) S = 1;
                L = log(L);
                M = log(M);
                S = log(S);

                I(i,j)[0] = (L+M+S) / sqrt(3.0);
                I(i,j)[1] = (L+M-2*S) / sqrt(6.0);
                I(i,j)[2] = (L-M) / sqrt(2.0);
            }
        }

        return I;
    }

    //Lab转换到RGB空间
    Mat LabToRGB(Mat m)
    {
        Mat_<Vec3f> I = m;
        for(int i=0;i<I.rows;++i)
        for(int j=0;j<I.cols;++j)
        {
            double L = I(i,j)[0]/sqrt(3.0) + I(i,j)[1]/sqrt(6.0) + I(i,j)[2]/sqrt(2.0);
            double M = I(i,j)[0]/sqrt(3.0) + I(i,j)[1]/sqrt(6.0) - I(i,j)[2]/sqrt(2.0);
            double S = I(i,j)[0]/sqrt(3.0) - 2*I(i,j)[1]/sqrt(6.0);

            L = exp(L);
            M = exp(M);
            S = exp(S);

            I(i,j)[0] = 4.4679*L - 3.5873*M + 0.1193*S;
            I(i,j)[1] = -1.2186*L + 2.3809*M - 0.1624*S;
            I(i,j)[2] = 0.0497*L - 0.2439*M + 1.2045*S;
        }

        return I;
    }

    Vector<double> computeMeans(Mat m)
    {
        double sum[3] = { 0 };
        int pixes = m.cols * m.rows;
        Vector<double> means;
        means.resize(3);
        Mat_<Vec3f> I = m;

        for(int i=0;i<I.rows;++i)
        for(int j=0;j<I.cols;++j)
        {
            for(int k = 0;k < 3;k++)
            {
                sum[k] += I(i,j)[k];
            }
        }

        for(int i = 0;i < 3;i++)
        {
            means[i] = sum[i] / pixes;
        }

        return means;
    }

    Vector<double> computeVariances(Mat m, Vector<double> means)
    {
        double sum[3] = { 0 };
        int pixes = m.cols * m.rows;
        Mat_<Vec3f> I = m;
        Vector<double> variances;
        variances.resize(3);

        for(int i=0;i<I.rows;++i)
        for(int j=0;j<I.cols;++j)
        {
            for(int chanel = 0;chanel < 3;chanel++)
            {
               // sum[chanel] += pow(I(i,j)[chanel] - means[chanel], 2.0);
                sum[chanel] += abs(I(i,j)[chanel] - means[chanel]);
            }
        }

        for(int i = 0;i < 3;i++)
        {
            variances[i] = sqrt(sum[i] / pixes);
        }

        return variances;
    }

    void computeResult()
    {
        Mat_<Vec3f> I = resultImg;
        double dataTemp[3] = { 0 };

        for(int chanel =0;chanel < 3;chanel++)
        {
            dataTemp[chanel] = targetVariances[chanel] / srcVariances[chanel];
        }

        for(int i=0;i<I.rows;++i)
        for(int j=0;j<I.cols;++j)
        {
            for(int chanel = 0;chanel < 3;chanel++)
            {
                I(i,j)[chanel] = dataTemp[chanel] * (I(i,j)[chanel]-srcMeans[chanel]) + targetMeans[chanel];
            }
        }

        resultImg = LabToRGB(resultImg);
    }
};

int main()
{
    string src_path("/home/zsj/data/target_img/1171.jpg");
    Mat src = imread(src_path);
    imwrite("/home/zsj/result/src6.jpg",src);
    namedWindow("src");
    imshow("src", src);
    Mat target = imread("/home/zsj/data/mid_img/170.jpg");
    imwrite("/home/zsj/result/target6.jpg",target);
    namedWindow("target");
    imshow("target", target);
    ColorTransfer clt(src,target);
    namedWindow("result");
    imshow("result", clt.resultImg);

    Mat saveImg;
    clt.resultImg.convertTo(saveImg,CV_8U, 255.0, 1/255.0);//imwrite函数只支持8bit和16bit,前面将图像转为了float,保存前要转换

    imwrite("/home/zsj/result/result6.jpg",saveImg);

    waitKey(0);
    return 0;
}



//int main(int argc, char **argv)
//{

//    string sourceVideoPath = "/home/zsj/data/NLPR_MCT_Dataset/video/Dataset1/Cam2.avi";
//    string savePath = "/home/zsj/data/mid_img/";

//    VideoCapture cap(sourceVideoPath);
//    if (!cap.isOpened()) {
//        cout << "fail to open video!" << endl;
//        exit(-1);
//    }

//    cv::Mat frameImg;

//    int cnt = 0;

//    while(true) {
//        cap >> frameImg;
//        if (frameImg.empty()) {
//            break;
//        }

//        stringstream ss;
//        ss << cnt;
//        cnt++;

//        string img_path = savePath + ss.str() + ".jpg";

//        cout << "path: " << img_path << endl;

//        cv::imshow("resultImg", frameImg);
//        cv::imwrite(img_path ,frameImg);
//        cv::waitKey(10);

//    }


//    return 0;
//}

This snippet took 0.01 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).