Suppose I have a image with some dimension (1920, 1080, 3) , I want to extract out R,G,B values into separate arrays R , G, B . I tried to do it like
for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            B = np.append(B, image[i, j][0])
            G = np.append(G, image[i, j][1])
            R = np.append(R, image[i, j][2])
But as expected this is very slow , How can I do this with numpy in built function?
If you want it to use in OpenCV way then you may use cv2.split(), keeping in mind channels of your image:
b, g, r    = cv2.split(image) # For BGR image
b, g, r, a = cv2.split(image) # for BGRA image
Or if you may like direct numpy format then you may use directly [which seems to be more efficient as per comments of @igaurav]
b, g, r    = image[:, :, 0], image[:, :, 1], image[:, :, 2] # For RGB image
b, g, r, a = image[:, :, 0], image[:, :, 1], image[:, :, 2], image[:, :, 3] # for BGRA image
You may use np.shape[2] to check the number of channels in the given image.
dsplit it.
import numpy as np
def channelSplit(image):
    return np.dsplit(image,image.shape[-1])
[B,G,R]=channelSplit(image)
This works for RGB or RGBA images.
This works for me:
def split_channels(im: np.ndarray):
    assert len(im.shape) == 3 and im.shape[-1] == 3
    return np.squeeze(np.split(im, im.shape[-1], -1), axis=-1)
Note that, the np.split itself is not enough, which will leave you a (M, N, 1) image. But if you want to have (M, N), then the squeeze works.
You can remove the assert if you have other cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With