如何使用OpenCV for Python编写灰度(1通道)图像

10
我想知道是否可以使用OpenCV从RGB图像中保存灰度1通道图像。
import cv2
bgr_img = cv2.imread('anyrgbimage.jpg')
print(bgr_img.shape) #(x,y,3)
gray_img = cv2.cvtColor(bgr_img,cv2.COLOR_BGR2GRAY)
cv2.imwrite('hopefully_gray_image.jpg',gray_img)
#cv2.imwrite('hopefully_gray_image.jpg',gray_img,[int(cv2.COLOR_BGR2GRAY)])
buh_img = cv2.imread('hopefully_gray_image.jpg')
print(buh_img.shape) #(x,y,3)

我知道可以在cv2.imwrite中添加一些参数,但是我不知道应该添加哪些参数。


带有PNG格式的图像是一样的。无论如何,我想知道如何编写参数以使其成为1通道,而不是读取灰度图像的方法。 - arj
bmp图像具有灰度格式。 - Nuzhny
@Miki 啊,我的错误。谢谢指出。 - Quang Hoang
@miki:你的第二个答案更详细,我理解了。它有效。谢谢。 - arj
1个回答

17
是的,没错。让我详细说明@Miki's comment对你的回答。如果你查看imread(filename[, flags])的文档,你会发现默认标志是cv2.IMREAD_COLOR,也就是说,OpenCV默认情况下将使用3通道加载图像(即使它只有1个或4个通道)。如果你想使用相同的imread(...)来加载三通道和单通道图像,你应该使用标志cv2.IMREAD_UNCHANGED。在实践中,这是如何工作的?
import cv2
import numpy as np

img = (np.random.random((300, 300, 3)) * 255.).astype(np.uint8)
# let's save 4 images (color/gray, png/jpg)
cv2.imwrite('img-png-color.png', img)          # output size: 270KB
cv2.imwrite('img-png-gray.png', img[:, :, 1])  # output size: 90KB
cv2.imwrite('img-jpg-color.jpg', img)          # output size: 109KB
cv2.imwrite('img-jpg-gray.jpg', img[:, :, 1])  # output size: 93KB

需要注意两点:

  • 彩色PNG图像文件比灰度PNG图像文件大3倍;
  • JPEG工作正常,谢谢:)

现在,如果您使用默认标志读取这些图像中的任何一个,它们将以形状(300,300,3)加载。但是,如果您按照@Miki告诉您的方式继续进行:

cv2.imread('img-png-color.png', cv2.IMREAD_UNCHANGED).shape  # (300, 300, 3)
cv2.imread('img-png-gray.png', cv2.IMREAD_UNCHANGED).shape   # (300, 300)
cv2.imread('img-jpg-color.jpg', cv2.IMREAD_UNCHANGED).shape  # (300, 300, 3)
cv2.imread('img-jpg-gray.jpg', cv2.IMREAD_UNCHANGED).shape   # (300, 300)

因此,实际上,灰度图像被“保存”为单通道。

1
不错...我会把这个保存下来,以备下次处理一千个重复项时使用... ;) - Miki
@Miki 我经常看到自己也使用你的答案来处理重复问题 =] - Berriel
我使用Keras ImageDatagenerator的flow_from_directory读取灰色图像,因此讨论如何使用cv2进行读取是毫无意义的。无论如何,我已经理解了原理,就像我之前说过的那样。 - arj
@arj?那是什么?你的问题与Keras无关,你还用OpenCV打了标签。我有什么地方错过了吗? - Berriel
这与“写”有什么关系? - KansaiRobot
@KansaiRobot 这个答案不仅告诉你如何编写代码,还告诉你如何正确地阅读它;否则你可能会认为自己以错误的方式编写了代码,但这并不是 OP 的问题。 - Berriel

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