Combine 3 separate numpy arrays to an RGB image in Python

110,069

Solution 1

rgb = np.dstack((r,g,b))  # stacks 3 h x w arrays -> h x w x 3

To also convert floats 0 .. 1 to uint8 s,

rgb_uint8 = (np.dstack((r,g,b)) * 255.999) .astype(np.uint8)  # right, Janna, not 256

Solution 2

I don't really understand your question but here is an example of something similar I've done recently that seems like it might help:

# r, g, and b are 512x512 float arrays with values >= 0 and < 1.
from PIL import Image
import numpy as np
rgbArray = np.zeros((512,512,3), 'uint8')
rgbArray[..., 0] = r*256
rgbArray[..., 1] = g*256
rgbArray[..., 2] = b*256
img = Image.fromarray(rgbArray)
img.save('myimg.jpeg')

I hope that helps

Solution 3

rgb = np.dstack((r,g,b))  # stacks 3 h x w arrays -> h x w x 3

This code doesnt create 3d array if you pass 3 channels. 2 channels remain.

Solution 4

Convert the numpy arrays to uint8 before passing them to Image.fromarray

Eg. if you have floats in the range [0..1]:

r = Image.fromarray(numpy.uint8(r_array*255.999))

Solution 5

Your distortion i believe is caused by the way you are splitting your original image into its individual bands and then resizing it again before putting it into merge;

`
image=Image.open("your image")

print(image.size) #size is inverted i.e columns first rows second eg: 500,250

#convert to array
li_r=list(image.getdata(band=0))
arr_r=np.array(li_r,dtype="uint8")
li_g=list(image.getdata(band=1))
arr_g=np.array(li_g,dtype="uint8")
li_b=list(image.getdata(band=2))
arr_b=np.array(li_b,dtype="uint8")

# reshape 
reshaper=arr_r.reshape(250,500) #size flipped so it reshapes correctly
reshapeb=arr_b.reshape(250,500)
reshapeg=arr_g.reshape(250,500)

imr=Image.fromarray(reshaper,mode=None) # mode I
imb=Image.fromarray(reshapeb,mode=None)
img=Image.fromarray(reshapeg,mode=None)

#merge
merged=Image.merge("RGB",(imr,img,imb))
merged.show()
`

this works well !

Share:
110,069
Ishan Tomar
Author by

Ishan Tomar

Updated on November 05, 2020

Comments

  • Ishan Tomar
    Ishan Tomar over 3 years

    So I have a set of data which I am able to convert to form separate numpy arrays of R, G, B bands. Now I need to combine them to form an RGB image.

    I tried 'Image' to do the job but it requires 'mode' to be attributed.

    I tried to do a trick. I would use Image.fromarray() to take the array to image but it attains 'F' mode by default when Image.merge requires 'L' mode images to merge. If I would declare the attribute of array in fromarray() to 'L' at first place, all the R G B images become distorted.

    But, if I save the images and then open them and then merge, it works fine. Image reads the image with 'L' mode.

    Now I have two issues.

    First, I dont think it is an elegant way of doing the work. So if anyone knows the better way of doing it, please tell

    Secondly, Image.SAVE is not working properly. Following are the errors I face:

    In [7]: Image.SAVE(imagefile, 'JPEG')
    ----------------------------------------------------------------------------------
    
    TypeError                                 Traceback (most recent call last)
    
    /media/New Volume/Documents/My own works/ISAC/SAMPLES/<ipython console> in <module>()
    
    TypeError: 'dict' object is not callable
    

    Please suggest solutions.

    And please mind that the image is around 4000x4000 size array.

  • Bach
    Bach almost 10 years
    @IshanTomar - you may wish to accept that answer if it was helpful.
  • icypy
    icypy over 8 years
    If you want to save the array as an image it should be "toimage"
  • Ishan Tomar
    Ishan Tomar over 7 years
    Thank you guys Thanks for the answer
  • Walter Tross
    Walter Tross over 5 years
    @IshanTomar you really should accept the most helpful answers, that's an important part of what keeps StackOverflow ticking
  • xdevs23
    xdevs23 almost 5 years
    This is perfect. ` data[..., 0] = b data[..., 1] = g data[..., 2] = r` is what I needed
  • Lei Yang
    Lei Yang almost 4 years
    what does the three dots(...) mean?
  • Dwa
    Dwa almost 3 years
    In fact @denis 's answer helped me.
  • Josh Bone
    Josh Bone over 2 years
    @LeiYang it means to slice all of the previous dimensions. See this: python-reference.readthedocs.io/en/latest/docs/brackets/…
  • Coder
    Coder over 2 years
    hello, could you help with this stackoverflow.com/questions/69778351/…
  • Coder
    Coder over 2 years
    Hello, can you help with -: stackoverflow.com/questions/69778351/…