c++ - 颜色转移 : What's wrong with my code in OpenCV C++

标签 c++ opencv colors

我想在这个paper中实现颜色迁移算法我引用这个tutorial在 OpenCV C++ 中传输算法。

但是我得到了一些奇怪的结果,例如: This是源图像,this是目标,但组合结果看起来像 this . 结果的某些部分看起来很奇怪。

这是我的源代码

Mat src; Mat tar; Mat result;

class imageInfo{
public:
    double lMean, lStd, aMean, aStd, bMean, bStd;
};

/// Function header
void image_stats(Mat img,imageInfo *info);

/** @function main */
int main(int argc, char** argv)
{
    vector<Mat> mv;
    imageInfo srcInfo, tarInfo;

    src = imread("images/autumn.jpg");
    tar = imread("images/fallingwater.jpg");
    imshow("src", src);
    imshow("tar", tar);



    cvtColor(src, src, CV_BGR2Lab);
    cvtColor(tar, tar, CV_BGR2Lab);

    image_stats(src, &srcInfo);
    image_stats(tar, &tarInfo);

    split(tar, mv);
    Mat l = mv[0];
    Mat a = mv[1];
    Mat b = mv[2];

    /*pixel color modify*/
    for (int i = 0; i<l.rows; i++){
        for (int j = 0; j<l.cols; j++){
            double li = l.data[l.step[0] * i + l.step[1] * j];
            if (i == 426 && j == 467)
                cout << "i:" << i << "j:" << j << " " << li << endl;
            li -= tarInfo.lMean;
            li = (tarInfo.lStd / srcInfo.lStd)*li;
            li += srcInfo.lMean;
            li = (int)li % 256;
            l.data[l.step[0] * i + l.step[1] * j] = li;
        }
    }

    for (int i = 0; i<a.rows; i++){
        for (int j = 0; j<a.cols; j++){
            double ai = a.data[a.step[0] * i + a.step[1] * j];
            ai -= tarInfo.aMean;
            ai = (tarInfo.aStd / srcInfo.aStd)*ai;
            ai += srcInfo.aMean;
            ai = (int)ai % 256;
            a.data[a.step[0] * i + a.step[1] * j] = ai;
        }
    }

    for (int i = 0; i<b.rows; i++){
        for (int j = 0; j<b.cols; j++){
            double bi = b.data[b.step[0] * i + b.step[1] * j];
            bi -= tarInfo.bMean;
            bi = (tarInfo.bStd / srcInfo.bStd)*bi;
            bi += srcInfo.bMean;
            bi = (int)bi % 256;
            b.data[b.step[0] * i + b.step[1] * j] = bi;
        }
    }

    mv.clear();
    mv.push_back(l);
    mv.push_back(a);
    mv.push_back(b);


    merge(mv, result);
    cvtColor(result, result, CV_Lab2BGR);
    imshow("result", result);
    imwrite("result.png", result);
    waitKey(0);

    return(0);
}

image_stats 函数:

 void image_stats(Mat img, imageInfo *info){
    int Max=0;
    vector<Mat> mv;
    vector<int> vl, va, vb;
    split(img, mv);
    Mat l = mv[0];
    Mat a = mv[1];
    Mat b = mv[2];

    /*statistics L space*/
    for (int i = 0; i<l.rows; i++){
        for (int j = 0; j<l.cols; j++){
            int li = l.data[l.step[0] * i + l.step[1] * j];
            vl.push_back(li);
        }
    }
    double sum_l = std::accumulate(vl.begin(), vl.end(), 0.0);
    double mean_l = sum_l / vl.size();
    std::vector<double> diff_l(vl.size());
    std::transform(vl.begin(), vl.end(), diff_l.begin(),
        std::bind2nd(std::minus<double>(), mean_l));
    double sq_sum_l = std::inner_product(diff_l.begin(), diff_l.end(), diff_l.begin(), 0.0);
    double stdev_l = std::sqrt(sq_sum_l / vl.size());
    info->lMean = mean_l;
    info->lStd = stdev_l;

    /*statistics A space*/
    for (int i = 0; i<a.rows; i++){
        for (int j = 0; j<a.cols; j++){
            int ai = a.data[a.step[0] * i + a.step[1] * j];
            va.push_back(ai);
        }
    }
    double sum_a = std::accumulate(va.begin(), va.end(), 0.0);
    double mean_a = sum_a / va.size();
    std::vector<double> diff_a(va.size());
    std::transform(va.begin(), va.end(), diff_a.begin(),
        std::bind2nd(std::minus<double>(), mean_a));
    double sq_sum_a = std::inner_product(diff_a.begin(), diff_a.end(), diff_a.begin(), 0.0);
    double stdev_a = std::sqrt(sq_sum_a / va.size());
    info->aMean = mean_a;
    info->aStd = stdev_a;

    /*statistics B space*/
    for (int i = 0; i<b.rows; i++){
        for (int j = 0; j<b.cols; j++){
            int bi = b.data[b.step[0] * i + b.step[1] * j];
            vb.push_back(bi);
        }
    }
    double sum_b = std::accumulate(vb.begin(), vb.end(), 0.0);
    double mean_b = sum_b / vb.size();
    std::vector<double> diff_b(vb.size());
    std::transform(vb.begin(), vb.end(), diff_b.begin(),
        std::bind2nd(std::minus<double>(), mean_b));
    double sq_sum_b = std::inner_product(diff_b.begin(), diff_b.end(), diff_b.begin(), 0.0);
    double stdev_b = std::sqrt(sq_sum_b / vb.size());
    info->bMean = mean_b;
    info->bStd = stdev_b;


}

最佳答案

在您的主要功能中,您应该将结果值限制在上限和下限范围内 [0; 255],不取模。如果 li = 256; 则代码 li = (int)li % 256; 将使其变为零。

关于c++ - 颜色转移 : What's wrong with my code in OpenCV C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30570628/

相关文章:

c - opencv中如何根据图像宽高动态绘制矩形?

python - 是否可以在 python 中使用 curses 获取默认背景颜色?

C++ 内联汇编(英特尔编译器): LEA and MOV behaving differently in Windows and Linux

c++ - 如何阻止 automake 添加 -I.到我的编译行?

python - OpenCV:在不使用 RETR_EXTERNAL 的情况下删除形状轮廓上的双轮廓

c++ - OpenCV - 匹配 SURF 点运行时错误

bash 提示符和函数内的回显颜色

php - 在 PHP 中插值颜色

c++ - 在 C++03 中模拟显式转换

c++ - boost::archive::xml_oarchive 中的 class_id