1

I have a list of 128x512 arrays as shown below:

        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.]], dtype=float32),
 array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        ..., 
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.]], dtype=float32),
 array([[ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ...,  0.,  0.,  0.],
        ..., 

I am converting this list of arrays to a list of RGB images and so far my code is:

#makes an array of all the images 

image_out = [[] for i in range(len(blue_Rad_list))]

for i in range(len(blue_Rad_list)):

    startTime = time.time()

    image_arr = [np.int_(np.float_(x/np.amax(blue_Rad_list))*256) for x in blue_Rad_list[i]]
    image_out[i] = Image.new('RGB', (width, height))
    image_out[i].putdata(np.asarray(image_arr).ravel())


    del image_arr[:]

    stopTime = time.time()

    print(stopTime - startTime)

After running my code, I get something like this:

 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CDCE90>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CDCED0>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CDCF10>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CDCF50>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CDCF90>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CDCFD0>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CE9050>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CE9090>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CE90D0>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CE9110>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CE9150>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CE9190>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CE91D0>,
 <PIL.Image.Image image mode=RGB size=128x512 at 0x7F47D4CE9210>]

In the above code, blue_Rad_list is the list of 128x512 arrays. This code works but its taking a lot of time to give me the entire list of images when there are around 180 elements. Is there a more efficient way I can do this. Thanks for any help.

Shank
  • 97
  • 2
  • 3
  • 13
  • https://stackoverflow.com/questions/2659312/how-do-i-convert-a-numpy-array-to-and-display-an-image or https://stackoverflow.com/questions/10443295/combine-3-separate-numpy-arrays-to-an-rgb-image-in-python – Dadep Jun 20 '17 at 16:45
  • Thanks for the links but they tell me how to create images. I am already able to do that and I used something similar shown in these links. My question is how to make it more efficient because its taking a lot of time to do that. – Shank Jun 20 '17 at 16:48
  • How did you end up with list of arrays? Can't you have a multi-dimensional array as input? – Divakar Jun 20 '17 at 16:48
  • Can you elaborate on your question. If you mean how I got blue_Rad_list then I had a 3-d numpy array which I converted to a list of 128x512 arrays. But I still have that multi-dimensional array. Will it be easier to use that instead? – Shank Jun 20 '17 at 16:53

1 Answers1

1

With the idea of performing less work once we go inside the loop, specially those compute heavy work, here's an approach making use of a multi-dim array instead of list of arrays as input. In the process, we would be leveraging the vectorized operations supported by NumPy to cover all elements -

# Convert to 3D array. If you already have the multi-dim array that was used to
# create the list of arrays. Use that instead of imgs
imgs = np.array(blue_Rad_list)

# Perfomr the image conversion operation formerly done within loop
imgs1 = np.int_(np.float_(imgs/np.amax(imgs))*256).reshape(imgs.shape[0],-1)

# Loop through and create list of PIL images
image_out = [[] for i in range(len(blue_Rad_list))]
for i in range(len(imgs)):
    image_out[i] = Image.new('RGB', (width, height))
    image_out[i].putdata(imgs1[i])

It seems we could optimize one-step further by initializing for the data storage before going into loop, like so -

image_out = [Image.new('RGB', (width, height))]*len(imgs)
for i in range(len(imgs)):
    image_out[i].putdata(imgs1[i])
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • This has significantly improve my code efficiency. Earlier each loop iteration was taking more than 4-5 seconds to run. It has decreased to less than 0.0025 seconds. Thank you so much for your help. – Shank Jun 20 '17 at 18:20
  • @Akkida_x That's awesome really! – Divakar Jun 20 '17 at 18:21
  • Also for future reference what is line of code for imgs1 doing? – Shank Jun 20 '17 at 18:27
  • @Akkida_x That line is performing the equivalent of what we had in the original code inside the loop to get `image_arr`, but operates across all images in one go. So, we replaced `x` by `imgs`. `x` was each image from `blue_Rad_list`, whereas `imgs` represent all images. – Divakar Jun 20 '17 at 18:30