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
Post a Comment