opencv 和 matlab 之间的像素值不同
Pixel values differ between opencv and matlab
当我在 matlab 中使用 "display" 函数显示图像(RGB 图像转换为灰度)的像素值时,我发现像素值小于 1(所有值都在 0 和1).而当我在 opencv 中做同样的事情时,我得到了更高的价值。为什么会发生价值观的变化?
打开CV代码和matlab代码如下:
for (int i = 0; i < img1.rows; i++)
{
for (int j = 0; j < img1.cols; j++)
{
cout << (unsigned int)img1.at<uchar>(i, j) << endl;
}
}
Matlab code:
gI=rgb2gray(I);
imshow(gI);
抱歉让你失望了。
没有人保证将 RGB 转换为灰度会产生相同的结果。有2个原因
- 转换不是数学上正确的公式,而是主观问题。在过去 50 年的过程中,编写了一些不同的标准(主要用于支持灰度信号的彩色电视)如何将 RGB 转换为灰度级。不同的标准导致几乎相同的可见结果,尽管像素的实际值略有不同(约 0.2%)。您可以在维基百科中阅读有关标准的更多信息。例如:一个标准定义了RGB 到灰色的转换,而另一个标准定义了RGB 到YUV 的转换并以Y 通道作为灰度。其他标准也很少(保持亮度、强度、对比度等)。由于标准的偏好随时间而变化,因此很难知道 RGB 到灰色的具体实现方式。 Here is an example of 3 different methods. Open CV uses completely different method (
0.299f*RED + 0.587f*GREEN + 0.114f*BLUE
Here) while Matlab uses another method (0.2989*RED + 0.587*GREEN + 0.1140*BLUE. Here)。请注意 openCV 0.299 和 Matlabs 0.2989 之间的区别。
可以在这个答案中找到更多信息 (here)
- 第二个原因 - 硬件和软件的浮点表示不同。浮点计算(无论是 double 还是 float)并不精确,取决于您使用的特定硬件、编译器的类型 您构建的软件和特定的编译器指令。相同的数学计算在不同的计算机上甚至在同一台计算机上的 2 个不同程序中可能会产生略有不同的结果。因此不幸的是,RGB 到灰色的转换不会得到完全相同的结果,但如果将值四舍五入到 [0..255] 范围内,通常会出现不超过 2 个级别的差异。我会说,在 99.9% 的像素中,您将获得相同的值,而在其他像素中,差异为 1。2 非常罕见,我从未见过 3 的差异,除非您进行一些顺序转换,如 RGB->XYZ->HSV ->YUV
My Mat is of type 8UC3. How to convert normalised double value of
MATLAB to 8UC3 ? Multipying by 255 alone is enough?
在 8UC3
字节的情况下, 是的 足以乘以 255。它们被设计为以这种方式工作。 8UC3中的3表示三个通道Red,Green和蓝色
无论如何,在 0 to 255
个范围值和 0.0 to 1.0
个范围值之间转换
//Psuedo-code formula:
col_val = 210; //range 0-255
normalised = col_val / 255; //always divide by 255 for a normalised to "1.0" version
normal_reverse_to255 = normalised * 255; //make it back into "0 to 255" range
预期结果:
col_val = 210 //original value before normalised
归一化 = 0.8235 //...294117647058 etc etc //after normalised to 0.0 to 1.0 range
normal_reverse_to255 = 210; //multiply result is same as original value
希望对您有所帮助。
编辑:
我刚意识到您正在使用 gI=rgb2gray(I);
来获取灰度图像。
试试这样的东西:
cvtColor(src,dst,CV_GRAY2RGB);
从 this answer
劫持
当我在 matlab 中使用 "display" 函数显示图像(RGB 图像转换为灰度)的像素值时,我发现像素值小于 1(所有值都在 0 和1).而当我在 opencv 中做同样的事情时,我得到了更高的价值。为什么会发生价值观的变化? 打开CV代码和matlab代码如下:
for (int i = 0; i < img1.rows; i++)
{
for (int j = 0; j < img1.cols; j++)
{
cout << (unsigned int)img1.at<uchar>(i, j) << endl;
}
}
Matlab code:
gI=rgb2gray(I);
imshow(gI);
抱歉让你失望了。 没有人保证将 RGB 转换为灰度会产生相同的结果。有2个原因
- 转换不是数学上正确的公式,而是主观问题。在过去 50 年的过程中,编写了一些不同的标准(主要用于支持灰度信号的彩色电视)如何将 RGB 转换为灰度级。不同的标准导致几乎相同的可见结果,尽管像素的实际值略有不同(约 0.2%)。您可以在维基百科中阅读有关标准的更多信息。例如:一个标准定义了RGB 到灰色的转换,而另一个标准定义了RGB 到YUV 的转换并以Y 通道作为灰度。其他标准也很少(保持亮度、强度、对比度等)。由于标准的偏好随时间而变化,因此很难知道 RGB 到灰色的具体实现方式。 Here is an example of 3 different methods. Open CV uses completely different method (
0.299f*RED + 0.587f*GREEN + 0.114f*BLUE
Here) while Matlab uses another method (0.2989*RED + 0.587*GREEN + 0.1140*BLUE. Here)。请注意 openCV 0.299 和 Matlabs 0.2989 之间的区别。 可以在这个答案中找到更多信息 (here) - 第二个原因 - 硬件和软件的浮点表示不同。浮点计算(无论是 double 还是 float)并不精确,取决于您使用的特定硬件、编译器的类型 您构建的软件和特定的编译器指令。相同的数学计算在不同的计算机上甚至在同一台计算机上的 2 个不同程序中可能会产生略有不同的结果。因此不幸的是,RGB 到灰色的转换不会得到完全相同的结果,但如果将值四舍五入到 [0..255] 范围内,通常会出现不超过 2 个级别的差异。我会说,在 99.9% 的像素中,您将获得相同的值,而在其他像素中,差异为 1。2 非常罕见,我从未见过 3 的差异,除非您进行一些顺序转换,如 RGB->XYZ->HSV ->YUV
My Mat is of type 8UC3. How to convert normalised double value of MATLAB to 8UC3 ? Multipying by 255 alone is enough?
在 8UC3
字节的情况下, 是的 足以乘以 255。它们被设计为以这种方式工作。 8UC3中的3表示三个通道Red,Green和蓝色
无论如何,在 0 to 255
个范围值和 0.0 to 1.0
个范围值之间转换
//Psuedo-code formula:
col_val = 210; //range 0-255
normalised = col_val / 255; //always divide by 255 for a normalised to "1.0" version
normal_reverse_to255 = normalised * 255; //make it back into "0 to 255" range
预期结果:
col_val = 210 //original value before normalised
归一化 = 0.8235 //...294117647058 etc etc //after normalised to 0.0 to 1.0 range
normal_reverse_to255 = 210; //multiply result is same as original value
希望对您有所帮助。
编辑:
我刚意识到您正在使用 gI=rgb2gray(I);
来获取灰度图像。
试试这样的东西:
cvtColor(src,dst,CV_GRAY2RGB);
从 this answer