如何在python中统一拆分图像?

时间:2017-08-24 18:55:34

标签: python opencv numpy

我有一张用cv2加载的图片。我重新缩放图像,将其转换为YCbCR色彩空间。我将图像分成3个组件。

    image_rescaled.shape
    Output[8]: (2016, 1512, 3)
    Y, Cr, Cb = cv2.split(image_rescaled)
    Y.shape
    Output[9]: (2016, 1512)

一旦我执行了我需要的任何操作,我想要将这三个组件合并回来。我怎么能这样做?我现在陷入困境。

1 个答案:

答案 0 :(得分:1)

OpenCV具有cv2.merge()功能,可以执行此操作。它可以合并任意数量的通道。此外,np.dstack()也会做同样的事情。

您还可以使用np.split()np.dsplit()将三通道图像分割为单独的通道;但这非常cv2.split()略有不同;检查结果操作的形状(特别是拆分后单个通道的形状):

使用OpenCV功能:

>>> img = cv2.imread('image.png')
>>> b, g, r = cv2.split(img)
>>> bgr = cv2.merge([b, g, r])
>>> img.shape
(508, 640, 3)
>>> b.shape
(508, 640)
>>> bgr.shape
(508, 640, 3)

使用numpy函数:

>>> img = cv2.imread('image.png')
>>> b, g, r = np.dsplit(img, 3)
>>> bgr = np.merge([b, g, r])
>>> img.shape
(508, 640, 3)
>>> b.shape
(508, 640, 1)
>>> bgr.shape
(508, 640, 3)

无论哪种方式,在与OpenCV或numpy合并后,生成的形状都是您想要的。请注意,两者都可用于堆叠任意矩阵,但需要多个通道。这有助于堆叠图像序列以进行处理或存储。您甚至可以使用例如单个频道图像堆叠多通道图像(或者,更常见的是,将通道或多个通道添加到图像堆栈中):

>>> bgr = cv2.merge([b, g, r, img])
>>> bgr.shape # b, g, r each 1ch, img is 3ch, should be 6ch total
(508, 640, 6)
>>> bgr = np.dstack([b, g, r, img])
>>> bgr.shape
(508, 640, 6)

所以下一个问题是"有没有理由使用其中一个?"由于输出是相同的,它们都在我们可能想要的输入上工作,唯一的另一个主要问题是速度。而且(令我惊讶的是),事实证明,OpenCV的cv2.merge()功能最终只会快一个数量级:

import cv2
import numpy as np

img = cv2.imread('image.png')
b, g, r = cv2.split(img)

import timeit
times = range(50000)

start_time = timeit.default_timer()
for t in times:
    A = cv2.merge([b, g, r])
print("cv2.merge: ", timeit.default_timer() - start_time, "s")

start_time = timeit.default_timer()
for t in times:
    A = np.dstack([b, g, r])
print("np.dstack: ", timeit.default_timer() - start_time, "s")
  

cv2.merge:3.0349163499922724 s

     

np.dstack:22.386054433998652 s