Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract R,G,B values with numpy into seperate arrays

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?

like image 687
Sigma Avatar asked Jan 06 '17 07:01

Sigma


3 Answers

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.

like image 159
ZdaR Avatar answered Oct 11 '22 23:10

ZdaR


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.

like image 40
Daniel F Avatar answered Oct 12 '22 00:10

Daniel F


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.

like image 2
ch271828n Avatar answered Oct 12 '22 00:10

ch271828n