Opencv - 灰度模式 vs 灰色颜色转换

74

我正在使用opencv(2.4.11) python(2.7)工作,并且在处理灰度图像时进行了一些尝试。当以灰度模式加载图像并将图像从BGR转换为GRAY时,我发现了一种不寻常的行为。以下是我的实验代码:

import cv2

path = 'some/path/to/color/image.jpg'

# Load color image (BGR) and convert to gray
img = cv2.imread(path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Load in grayscale mode
img_gray_mode = cv2.imread(path, 0)

# diff = img_gray_mode - img_gray
diff = cv2.bitwise_xor(img_gray,img_gray_mode)

cv2.imshow('diff', diff)
cv2.waitKey()

当我查看差异图像时,我可以看到漏掉的像素而不是纯黑色的图像。你能提供任何原因吗?处理灰度图像的正确方法是什么?

P.S. 当我在SIFT中使用这两个图像时,关键点是不同的,这可能会导致在处理低质量图像时产生不同的结果。


1
可能是OpenCV使用imread将RGB图像转换为灰度图像的结果不佳的重复问题。 - Jean-Baptiste Yunès
4
请注意,这不是重复问题,因为提问者知道 cv2.imread 读入的图像格式是 BGR(不同于被认为是 RGB 的重复问题,因此提供的答案只针对了那个问题)。 - bakkal
1个回答

82
注意:这不是重复问题,因为 OP 知道从 cv2.imread 读取的图像是 BGR 格式(与所假定为 RGB 的建议重复问题不同,因此提供的答案只解决了那个问题)。
为了说明,我打开了这张相同的彩色 JPEG 图像:

enter image description here

一旦使用转换

img = cv2.imread(path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

通过以灰度模式加载另一个

img_gray_mode = cv2.imread(path, cv2.IMREAD_GRAYSCALE)

正如您所记录的那样,这两个图像之间的差异并不完全为0,我可以看到向左和向下的差异像素。

enter image description here

我也总结了差异以查看

import numpy as np
np.sum(diff)
# I got 6143, on a 494 x 750 image

我尝试了所有的cv2.imread()模式

cv2.imread()的所有IMREAD_模式中,只有IMREAD_COLORIMREAD_ANYCOLOR可以使用COLOR_BGR2GRAY进行转换,而且它们都给出了与在IMREAD_GRAYSCALE中打开的图像相同的差异。

这个差异似乎不是很大。我的猜测是来自两种方法中数字计算的差异(加载灰度与转换为灰度)。

当然,你想要避免的是对特定版本的图像进行微调,只是发现它对来自不同来源的图像是次优的。

简而言之,在处理管道中不要混合版本和类型。

因此,我会保持图像来源的同质性,例如,如果您从BGR的视频摄像机中捕获图像,则我将使用BGR作为源,并执行BGR到灰度的转换cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

如果我的最终来源是灰度图像,那么我会以灰度模式打开文件和视频捕获:cv2.imread(path, cv2.IMREAD_GRAYSCALE)

12
原因是有多个灰度转换实现在使用中。cvtColor()是OpenCV的实现,将在各个平台上保持一致。当您使用imread()将其转换为灰度时,您要看平台特定的imread()实现。我不会感到惊讶,如果imread()在每个平台上返回稍微不同的灰度值。我想不出任何理由在imread()中转换为灰度。 - Michael Gallacher
就像 @MichaelGallacher 所说的那样。cvtColor 所使用的系数在这里: https://github.com/opencv/opencv/blob/master/modules/imgproc/src/color.simd_helpers.hpp#L22 - darda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接