cvtColor(), COLOR_HSV2BGR and back: Unexpected big "rounding errors"?

Recently I generated images in HSV format with S-channel = 255.

I discovered that converting HSV to BGR and back again:

cv::Scalar tempVal = mean (visualizeFrame);
cout << tempVal.val[0] << "; " << tempVal.val[1] << "; " << tempVal.val[2];
// At this point S channel == 255 alright

cvtColor (visualizeFrame, visualizeFrame, COLOR_HSV2BGR);
cvtColor (visualizeFrame, visualizeFrame, COLOR_BGR2HSV);

tempVal = mean (visualizeFrame);
cout << tempVal.val[0] << "; " << tempVal.val[1] << "; " << tempVal.val[2];
// At this point S channel is about 240 in average for a frame,
// the range for many frames is between abt. 220 and 250.

… changes the channel values to an unexpected extend.

I get problems with my further processing having to handle such large tolerances.
However it’s hard to believe that the conversion formulas should
produce as big rounding errors…

Either I have a wrong understanding, or there is a bug in the formula.

Can someone tell?

gray values have no intensity, so their “hue” can be arbitrary. differences in hue should be expected. same goes for saturation of pure/near-black pixels.

if you see large differences in well-defined colors, please present a MRE, i.e. hardcode the data into the MRE.

make sure you are using the latest release of OpenCV.

the assertion “non-linear” cannot be made.

hues are on a circle, so taking the mean of anything involving that is meaningless.

and hues are scaled to be 0…179. that alone affects the mean, moves it towards 90, regardless of what the BGR mean was.

since you work with uint8, i.e. integers, of course there will be rounding, which introduces error.

and please don’t format code as a quote. those things are not interchangeable.

I deleted a former post of mine, as it was based upon a mistake:
In it I didn’t take into account that OpenCV assumes BGR order
when writing an image file (so swaps R and B).
Now things cleared up, and the “rounding errors” are nothing
but an information loss when converting dark HSV pixels (small V) to RGB.
Using that RGB image to compute again HSV it will obviously get
large differences to orig image.

I’m sorry for the confusion.

Still on my journey I detected the missing “backward” formulas in the documentation
for most conversion, although the headings lets expect them.
Would be helpful to have them at hand.