Color Transfer: What's wrong with my code in OpenCV C++ -


i want implement color transfer algorithm in paper , refer tutorial transfer algorithm in opencv c++.

but got strange result, example: this source image , this target, combined result this. part of result strange.

this source code

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 = mv[1];     mat b = mv[2];      /*pixel color modify*/     (int = 0; i<l.rows; i++){         (int j = 0; j<l.cols; j++){             double li = l.data[l.step[0] * + l.step[1] * j];             if (i == 426 && j == 467)                 cout << "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] * + l.step[1] * j] = li;         }     }      (int = 0; i<a.rows; i++){         (int j = 0; j<a.cols; j++){             double ai = a.data[a.step[0] * + 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] * + a.step[1] * j] = ai;         }     }      (int = 0; i<b.rows; i++){         (int j = 0; j<b.cols; j++){             double bi = b.data[b.step[0] * + 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] * + 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 function:

 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 = mv[1];     mat b = mv[2];      /*statistics l space*/     (int = 0; i<l.rows; i++){         (int j = 0; j<l.cols; j++){             int li = l.data[l.step[0] * + 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 space*/     (int = 0; i<a.rows; i++){         (int j = 0; j<a.cols; j++){             int ai = a.data[a.step[0] * + 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*/     (int = 0; i<b.rows; i++){         (int j = 0; j<b.cols; j++){             int bi = b.data[b.step[0] * + 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;   } 

in main function should bound result values upper & lower limits [0; 255], not take modulo. if li = 256; code li = (int)li % 256; make zero.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -