简体   繁体   中英

what is wrong with this code that should do whitebalancing in opencv

I have this code:

vector<Mat> brg;
Mat output;
split(inputImage, brg);


double mb=mean(brg[0])[0];
double mg=mean(brg[1])[0];
double mr=mean(brg[2])[0];
cout << "mb "<< mb<< " mg "<< mg<< " mr "<< mr << endl;
double max=MAX(mb,MAX(mg,mr));

mb=max/mb;
mg=max/mg;
mr=max/mr;
brg[0]=brg[0] *mb;
brg[1]=brg[1] *mg;
brg[2]=brg[2] *mr;

{
    double mb=mean(brg[0])[0];
    double mg=mean(brg[1])[0];
    double mr=mean(brg[2])[0];
    cout << "mb "<< mb<< " mg "<< mg<< " mr "<< mr << endl;
}

merge(brg,output);
return output;

From mathematical pint of view, if I multiply a matrix by a number then its mean should be multiplied by that number, so I should get the same mb, mg, mr at the end of this function, but I am not getting. the result that I am getting is as follow:

mb 166.891 mg 176.319 mr 158.288
mb 169.619 mg 176.319 mr 164.149

as can be seen, the mean changed but they are not equal, but they should all be equal to max.

Any reason that I am not getting this?

How can I fix it?

My guess is that the data type of your matrix is something like CV_8UC3 which means the pixels are stored as unsigned 8 bit values.

When you scale, the scaled results are clipped to the range 0 to 255 so the mean does not change by the same scaling amount.

For example, suppose we had values:

0 , 64 , 64 , 128

and try to scale by a factor of 4.

The result would be:

0, 255, 255, 255 

If this is the problem, then you may wish to use the convertTo method to change your matrix to a different data type (such as a floating point data type) with a greater dynamic range.

Note that the convertTo method also has an optional scale (and offset) so you can apply scaling while converting data type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM