mrGreenBrown mrGreenBrown - 4 months ago 41x
Python Question

How to slice an image into red, green and blue channels with misc.imread

I am trying to slice an image into RGB and I have a problem with plotting these images.
I obtain all images from a certain folder with this function:

def get_images(path, image_type):
image_list = []
for filename in glob.glob(path + '/*'+ image_type):
im=misc.imread(filename, mode='RGB')
return image_list

This function creates 4d array (30, 1536, 2048, 3) and I am quite sure that the first value represents number of images, second and third are dimensions and third are RGB values.

After I obtained all the images, I stored them as a numpy array

image_list = get_images('C:\HDR\images', '.jpg')
temp = np.array(image_list)

After that I tried to use simple slicing on order to take specific colors from these images:

red_images = temp[:,:,:,0]
green_images = temp[:,:,:,1]
blue_images = temp[:,:,:,2]

When I print out the values, everything seems to be fine.


And I get the following:

[105 97 76]

So far, everything seems to be fine, but the problem arises when I try to display the image. I used
to display it and I get the image like:

Image red channel

Which is reasonable, because I choose red:


But when I change it to different color channel, like this:


I get the image like this:

Image bug channel

My question is simple. What is happening here?


I think matplotlib is just treating each channel (i.e., intensities) as a "heat map".

Pass a color map to the imshow function like so to tell it how you want it to color your image:



@mrGreenBrown in response to your comment, I'm assuming that the misc.imread function you used is from scipy, i.e., scipy.misc.imread. That function is no different from that of matplotlib.pyplot.

A single channel of any image is just intensities. It does not have color. For an image expressed in RGB color space, color is obtained by "mixing" amounts (given by the respective channel's intensities) of red, green, and blue. A single channel cannot express color.

What happened was Matplotlib by default displays the intensities as a heatmap, hence the "color".

When you save a single channel as an image in a format say JPEG, the function merely duplicates the single channel 3 times so that the R, G, and B channels all contain the same intensities. This is the typical behavior unless you save it in a format such as PGM which can handle single channel grayscale image. When you try to visualize this image which has the same channel duplicated 3 times, because the contributions from red, green, and blue are the same at each pixel, the image appears as grey.

Passing to the cmap argument simply tells imshow not to "color-code" the intensities. So, brighter pixels (pixels approaching white) means there is "more" of that "color" at those locations.

If you want color, you have to make copies of the 3 channel image and set the other channels to have values of 0.

For e.g., to display a red channel as "red":

# Assuming I is numpy array with 3 channels in RGB order
I_red = image.copy()  # Duplicate image
I_red[:, :, 1] = 0    # Zero out contribution from green
I_red[:, :, 2] = 0    # Zero out contribution from blue

A related question from stackoverflow here.