this is my first post on stackoverflow, so I hope to do everything right, sorry if I don't.
I'm writing code for a function to convert a single RGB value into CIE L*a*b* color space. The function is supposed to take a 3 floats array (RGB channels with values in [0-255]) and to give in output a 3 floats array with the L*a*b* values. To do so, I'm using the cvtColor
function available with OpenCV.
As suggested on the openCV website I'm creating the Mat structures (needed by cvtColor
) by contructor.
My problem is that, although I think the code runs properly and performs the conversion, I'm unable to get the values contained in the Mat structure back.
Here's my code:
float * rgb2lab(float rgb[3]) {
// bring input in range [0,1]
rgb[0] = rgb[0] / 255;
rgb[1] = rgb[1] / 255;
rgb[2] = rgb[2] / 255;
// copy rgb in Mat data structure and check values
cv::Mat rgb_m(1, 1, CV_32FC3, cv::Scalar(rgb[0], rgb[1], rgb[2]));
std::cout << "rgb_m = " << std::endl << " " << rgb_m << std::endl;
cv::Vec3f elem = rgb_m.at<cv::Vec3f>(1, 1);
float R = elem[0];
float G = elem[1];
float B = elem[2];
printf("RGB =\n [%f, %f, %f]\n", R, G, B);
// create lab data structure and check values
cv::Mat lab_m(1, 1, CV_32FC3, cv::Scalar(0, 0, 0));
std::cout << "lab_m = " << std::endl << " " << lab_m << std::endl;
// convert
cv::cvtColor(rgb_m, lab_m, CV_RGB2Lab);
// check lab value after conversion
std::cout << "lab_m2 = " << std::endl << " " << lab_m << std::endl;
cv::Vec3f elem2 = lab_m.at<cv::Vec3f>(1, 1);
float l = elem2[0];
float a = elem2[1];
float b = elem2[2];
printf("lab =\n [%f, %f, %f]\n", l, a, b);
// generate the output and return
static float lab[] = { l, a, b };
return lab;
}
As you can see, I'm extracting all channels from the Mat structure by the at
function and then accessing them individually from the vector. This is proposed as the solution in many places (one of them).
But if I run this code (input vector was {123,10,200}), on cout
I correctly get the outputs of the Mat structures (from which I get the algorithm is converting correctly), but as you can see the extracted values are wrong:
rgb_m =
[0.48235294, 0.039215688, 0.78431374]
RGB =
[0.000000, 0.000000, -5758185472.000000]
lab_m =
[0, 0, 0]
lab_m2 =
[35.198029, 70.120964, -71.303688]
lab =
[0.000000, 0.000000, 4822177514157213323960797626368.000000]
Anyone have an idea of what I'm doing wrong?
Thank you so much for all your help!
The first element of a cv::Mat
is always at (0, 0)
, so just correct cv::Vec3f elem = rgb_m.at<cv::Vec3f>(1, 1);
by cv::Vec3f elem = rgb_m.at<cv::Vec3f>(0, 0);
and cv::Vec3f elem2 = lab_m.at<cv::Vec3f>(1, 1);
by cv::Vec3f elem2 = lab_m.at<cv::Vec3f>(0, 0);