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')
image_list.append(im)
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.
print(temp[11,125,311,:])
print(red_images[11,125,311])
print(green_images[11,125,311])
print(blue_images[11,125,311])
And I get the following:
[105 97 76]
105
97
76
So far, everything seems to be fine, but the problem arises when I try to display the image. I used matplotlib.pyplot.imshow
to display it and I get the image like:
Which is reasonable, because I choose red:
plt.imshow(temp[29,:,:,0])
But when I change it to different color channel, like this:
plt.imshow(temp[29,:,:,2])
I get the image like this:
My question is simple. What is happening here?
Create an RGB image with uninterrupted areas of red, green, and blue. Display the image. Separate the three color channels. [R,G,B] = imsplit(RGB);
split() method is used to split the image into individual bands. This method returns a tuple of individual image bands from an image. Splitting an “RGB” image creates three new images each containing a copy of one of the original bands (red, green, blue).
Try img. transpose(2,0,1) or img. transpose(2,1,0) .
So, you want to show in different colors the different RGB channels of an image...
import matplotlib.pyplot as plt
from matplotlib.cbook import get_sample_data
image = plt.imread(get_sample_data('grace_hopper.jpg'))
titles = ['Grace Hopper', 'Red channel', 'Green channel', 'Blue channel']
cmaps = [None, plt.cm.Reds_r, plt.cm.Greens_r, plt.cm.Blues_r]
fig, axes = plt.subplots(1, 4, figsize=(13,3))
objs = zip(axes, (image, *image.transpose(2,0,1)), titles, cmaps)
for ax, channel, title, cmap in objs:
ax.imshow(channel, cmap=cmap)
ax.set_title(title)
ax.set_xticks(())
ax.set_yticks(())
plt.savefig('RGB1.png')
Note that when you have a dark room with a red pen on a dark table, if you turn on a red lamp you percept the pen as almost white...
Another possibility is to create a different image for each color, with the pixel values for the other colors turned to zero. Starting from where we left we define a function to extract a channel into an otherwise black image
...
from numpy import array, zeros_like
def channel(image, color):
if color not in (0, 1, 2): return image
c = image[..., color]
z = zeros_like(c)
return array([(c, z, z), (z, c, z), (z, z, c)][color]).transpose(1,2,0)
and finally use it...
colors = range(-1, 3)
fig, axes = plt.subplots(1, 4, figsize=(13,3))
objs = zip(axes, titles, colors)
for ax, title, color in objs:
ax.imshow(channel(image, color))
ax.set_title(title)
ax.set_xticks(())
ax.set_yticks(())
plt.savefig('RGB2.png')
I can't tell which is the version that I like better, perhaps the 1st one is looking more realistic to me (maybe it looks less artificial) but it's quite subjective...
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