【问题标题】:Opencv - Grayscale mode Vs gray color conversionOpencv - 灰度模式与灰度转换
【发布时间】:2016-09-09 07:04:15
【问题描述】:

我正在使用 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 中使用这两个图像时,关键点是不同的,这可能会导致不同的结果,特别是在处理质量差的图像时。

【问题讨论】:

标签: python python-2.7 opencv


【解决方案1】:

注意:这不是重复的,因为 OP 知道来自 cv2.imread 的图像是 BGR 格式(与假设它是 RGB 的建议重复问题不同,因此提供的答案仅解决该问题)

为了说明,我打开了这张相同颜色的 JPEG 图片:

使用一次转换

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

另一个以灰度模式加载

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

就像您记录的那样,两个图像之间的差异不是完全为 0,我可以看到左侧和底部的差异像素

我也总结了差异来看看

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 中打开的图像相同的差异

差异似乎没有那么大。我的猜测是来自两种方法中数值计算的差异(加载灰度vs转换为灰度)

当然,您要避免在特定版本的图像上微调您的代码,只是为了发现它对于来自不同来源的图像不是最佳的。

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

所以我会保持图像来源同质化,例如如果您在 BGR 中从摄像机捕获图像,那么我将使用 BGR 作为源,并将 BGR 转换为灰度cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

反之亦然,如果我的最终来源是灰度,那么我会以灰度打开文件和视频捕获cv2.imread(path, cv2.IMREAD_GRAYSCALE)

【讨论】:

  • 原因是灰度转换有多种实现在起作用。 cvtColor() 是 opencv 的实现,并且跨平台是一致的。当您使用imread() 转换为灰度时,您将受制于imread() 的特定于平台的实现。如果imread() 在每个平台上返回略有不同的灰度值,我不会感到惊讶。我想不出任何理由在imread 中转换为灰度。
  • @MichaelGallacher 说了什么。 cvtColor 使用的系数在这里:github.com/opencv/opencv/blob/master/modules/imgproc/src/…