将图像转换为灰度

4

我希望将任何图片转换为灰度图像,但是我不理解这些实现的区别。

image = cv2.imread('lenna.jpg')
gray = cv2.cvtColor(image, cv2.IMREAD_GRAYSCALE)

gray1 = rgb2gray(image)

gray2 = cv2.imread('lenna.jpg', cv2.IMREAD_GRAYSCALE)

image1 = Image.open('lenna.jpg', 'r')
gray3 = image1.convert('L')

当我绘制它们时,分别以蓝色、绿色、绿色和灰色的比例显示。何时应该使用每个比例?

你如何绘制它们?此外,rgb2gray 函数来自哪个模块? - sgarizvi
我正在使用 plt.imshow() 和 plt.show()。然而,即使数组不同 - asdas
2个回答

8
您遇到了Python类型系统无法像C++那样保护您的情况。 cv2.IMREAD_GRAYSCALEcv2.COLOR_BGR2GRAY是来自不同枚举的值。前者的数值为0,适用于cv2.imread()。后者的数值为6,适用于cv2.cvtColor()。C++会告诉您cv2.IMREAD_GRAYSCALE不能传递给cv2.cvtColor()。但是Python却安静地接受对应的整数值。
因此,您认为自己正在要求cv2将彩色图像转换为灰度图像,但通过传递cv2.IMREAD_GRAYSCALEcv2.cvtColor()看到的值是0,并认为您正在传递cv2.COLOR_BGR2BGRA。因此,您得到的不是灰度图像,而是原始带有alpha通道的图像。
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

以下是您需要的内容。

另一个问题是,假设您正在使用Jupyter笔记本电脑,cv2将颜色平面按BGR顺序排序而不是RGB。为了正确显示它们,请先执行以下操作:

您需要的是:

image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

然后展示结果。

但是当我使用 cv2.imread(image, cv2.IMREAD_GRAYSCALE) 时,不应该会得到正确的转换吗?查看OpenCV的文档,它应该可以工作。 - asdas
啊,是的。我猜问题出在显示时。在笔记本中正确显示灰度图像的诀窍是做类似于 plt.imshow(gray, cmap='gray') 的事情。(这是从记忆中得出的,所以 cmap 值可能是其他值。有很多选项可供选择。) - Dave W. Smith

0

那些不是灰色的图像仍然是3D数组,也就是说它们仍然保留着颜色信息。你看到蓝色和绿色是因为在这些3D数组中,第一种情况下的红色和绿色通道以及第二种情况下的蓝色和红色通道已经被减少到0,只剩下你看到的蓝色和绿色。

为了将图像读取为灰度图像,您可以使用以下方法:

img_gray=cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

这将产生一个二维数组,其值介于0到255之间,对应于像素应该有多亮,而不是像素的每个3个颜色通道应该有多亮。


但它们之间有什么区别呢? - asdas
我认为灰度的工作方式是将每个像素分配为三个通道的平均值,以某种程度上保留所有三个通道的表示,而如果您只表示一个通道,则会丢失其他两个通道中的信息。 - vencaslac

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