在OpenCV(Python)中,为什么我从灰度图像中获取3个通道图像?

Ste*_*eve 33 python jpeg opencv image-processing grayscale

我在Ubuntu 12.04上使用Python(2.7)和OpenCV 2.4.6的绑定

我加载图像

    image = cv2.imread('image.jpg')
Run Code Online (Sandbox Code Playgroud)

然后我检查图像阵列的形状

    print image.shape
Run Code Online (Sandbox Code Playgroud)

我得到(480,640,3),我期望640x480彩色图像.然后我将图像转换为灰度并再次检查形状.

    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    print gray_image.shape
Run Code Online (Sandbox Code Playgroud)

我得到(480,640,1),我期望640x480 灰度图像.然后我保存图像:

    cv2.imwrite('gray.jpg', gray_image)
Run Code Online (Sandbox Code Playgroud)

我在linux上,所以我试着用gThumb查看图像,它显示了所有的颜色通道.当我将灰色图像带回OpenCV时,图像再次有三个通道.我知道这个标志用于阅读图像:

    CV_LOAD_IMAGE_GRAYSCALE - If set, always convert image to the grayscale one
Run Code Online (Sandbox Code Playgroud)

但这听起来像是将图像作为彩色图像引入然后转换它.我正在将这个项目移植到RaspberryPi,所以我不希望发生不必要的操作.

编辑:我做了一些计时检查,我发现使用CV_LOAD_IMAGE_GRAYSCALE标志设置加载图像会导致图像加载速度提高两倍,而不管图像输入如何.

     Using a 3072 x 4608 x 3 image
     0.196774959564 seconds with default loading
     0.0931899547577 seconds with CV_LOAD_IMAGE_GRAYSCALE
Run Code Online (Sandbox Code Playgroud)

问题似乎是OpenCV正在创建3通道JPG输出,无论我是否有灰度图像矩阵!

我可以用什么其他应用程序来确保我得到一个8位通道JPG图像?(也许gThumb错误地报告了频道).

如果图像不是单通道,为什么OpenCV会在磁盘写入时将我的灰度图像保存为3通道图像?

提前致谢.

jab*_*edo 42

您的代码是正确的,似乎cv2.imread加载了三个通道的图像,除非CV_LOAD_IMAGE_GRAYSCALE设置.

>>> import cv2
>>> image = cv2.imread('foo.jpg')
>>> print image.shape
 (184, 300, 3)
>>> gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
>>> print gray_image.shape 
 (184, 300)
>>> cv2.imwrite('gray.jpg', gray_image)
Run Code Online (Sandbox Code Playgroud)

现在,如果你加载图像:

>>> image = cv2.imread('gray.jpg')
>>> print image.shape
 (184, 300, 3)
Run Code Online (Sandbox Code Playgroud)

您似乎已将图像保存为BGR,但事实并非如此,它只是opencv,默认情况下它会读取带有3个通道的图像,如果是灰度,则会将其图层复制三次.如果你再次加载scipy图像,你会发现图像确实是灰度图像:

>>> from scipy.ndimage import imread
>>> image2 = imread('gray.jpg')
>>> print image2.shape
 (184, 300)
Run Code Online (Sandbox Code Playgroud)

因此,如果要加载灰度图像,则需要设置CV_LOAD_IMAGE_GRAYSCALE标记:

>>> image = cv2.imread('gray.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
>>> print image.shape
 (184, 300)
Run Code Online (Sandbox Code Playgroud)

  • 这些天看起来像cv2.IMREAD_GRAYSCALE而不是cv2.CV_LOAD_IMAGE_GRAYSCALE (19认同)
  • 除此之外,我认为`cv2.IMREAD_UNCHANGED`每次使用都非常安全. (4认同)
  • 说了全部,以单通道格式保存图像的解决方案是什么?(假设我们必须在单个通道中保存图像) (2认同)

小智 14

试试这个:

 img = cv2.imread('gray.jpg',0)
Run Code Online (Sandbox Code Playgroud)

0表示灰色,1表示颜色