0

I need help figuring out how OpenCV handles setting a matrix equal to something.

I have an 8-Bit Mat called Radiance that I want to tone map. Here is working code that accomplishes this for me, with K being the constant 450.

cv::cvtColor(radiance, radiance, CV_BGR2XYZ);
radiance = (K * radiance)/(1 + (K * radiance));
cv::cvtColor(radiance, radiance, CV_XYZ2BGR);`

This does not seem like it should work, but it does. It will create a fully tone mapped image that looks great. However, if you try to do this method on the individual pixels, they become a decimal that is between 0 and 1, which truncates to 0. Here is an example of this -

cv::cvtColor(radiance, radiance, CV_BGR2XYZ);
int x = radiance.at<cv::Vec3b>(500, 500)[0];
x = (K * x)/(1 + (K * x));
std::cout << x << "\n";

The output of this is exactly what I would expect

0

I understand why the second snippet of code prints out a zero, but what is going on in the first part that allows it to tone map the image properly, and how can I recreate this on the individual pixel level?

and3212
  • 1
  • 2
  • I think OpenCV does not truncate the values but round them... at least on a small test I did... try in your second test to do std::round to the assignment of x (or add 0.5 ) and you may get the same results – api55 Jan 19 '18 at 07:53

1 Answers1

1

Can't you just define radiance as float matrix?

Mat radiance(m, n, DataType<float>::type);

So you can get a float

cv::cvtColor(radiance, radiance, CV_BGR2XYZ);
float x = radiance.at<cv::Vec3b>(500, 500)[0];
x = (K*x)/(1 + (K*x));
std::cout << x << "\n";
Blasco
  • 1,607
  • 16
  • 30