我对 openCV 很陌生,而且我边走边学。
我使用的是 openCV 4.3,但以下来自 2.4:
“如果您将 cvtColor 与 8 位图像一起使用,转换会丢失一些信息。对于许多应用程序,这不会很明显,但建议在需要全范围颜色或转换的应用程序中使用 32 位图像手术前的图像,然后转换回来。”
我正在使用 24 位 jpg 图像并在转换回 BGR 之前对 LAB 通道进行了一些小的颜色校正(类似于 2.4 注释中的警告)。
我加载图像:
//Ask user for filename and load with IMREAD_COLOR
string filename, finalFilename;
cout << "Which would you like to load? " << "\n";
cin >> filename;
cout << "What would you like to call the final image? " << "\n";
cin >> finalFilename;
Mat img = imread(filename, IMREAD_COLOR);
//Convert to CIEL*a*b* format and split for histogram
Mat imgLab;
cvtColor(img, imgLab, COLOR_BGR2Lab);
//Checking type and depth of image to ensure CV_8U (Note: This may have to be converted as to not lose information)
cout << "IMREAD_COLOR Loaded this image with a depth value of " << img.depth() << " and a type value of " << img.type() << "\n";
cout << "cvtColor has changed this image to one with a type value of " << imgLab.type() << "\n\n";
然后在将通道分配给临时变量后,我稍后会对其进行操作:
{
for (int j = 0; j < img.cols; j++)
{
modA.at<uint8_t>(i, j) = (float)tempA.at<uint8_t>(i, j) + (0.7f * ((float)mask.at<uint8_t>(i, j))/255 * (128-((float)aBlur.at<uint8_t>(i, j))));
modB.at<uint8_t>(i, j) = (float)tempB.at<uint8_t>(i, j) + (0.7f * ((float)mask.at<uint8_t>(i, j))/255 * (128-((float)bBlur.at<uint8_t>(i, j))));
}
}
掩码是一个 1 通道 8 位矩阵,包含 0-255 的值。aBlur 是应用了高斯模糊的 tempA(同样适用于 tempB/bBLur)。
出于某种原因,转换后,通道似乎仍然从 0-255 倾斜。(虽然我可能错了,但我注意到它们超过 127 并且从未低于大约 100,有点奇怪。
我做了一些测试,在转换为 LAB 之前和之后的类型保持不变(CV_8UC3)。由于 (float) 代码可能会丢失信息,因此会发出警告:
Severity Code Description Project File Line Suppression State
Warning C4244 '=': conversion from 'float' to '_Tp', possible loss of data OpenCvLearning
我的问题是:我是否在这个过程中丢失了信息?我注意到我的输出不像我试图重新实现的论文那样令人愉快。
这是原始的,我的小鬼,以及他们的结果:
更新
所以我更新了我的代码以使用浮点数,它现在有更多可能的数据点 (2^32)。然而,当轮询数据时,它仍然是 8bit (0-255)。
我正在尝试将 normalize min n max 与 8 位函数的旧最小值和最大值一起使用,并将 32 位缩放到 0-1。但是,我担心在不引入 8 位错误的情况下缩小到 8 位(如何在 32 位版本中没有 0 或 1 的矩阵中标准化 0-255?)