我有一张用cv2加载的图片。我重新缩放图像,将其转换为YCbCR色彩空间。我将图像分成3个组件。
image_rescaled.shape
Output[8]: (2016, 1512, 3)
Y, Cr, Cb = cv2.split(image_rescaled)
Y.shape
Output[9]: (2016, 1512)
一旦我执行了我需要的任何操作,我想要将这三个组件合并回来。我怎么能这样做?我现在陷入困境。
答案 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