16

When I generate an image and then generate a numpy array from it, the original .npy file differs from the new one. I thought new-array.npy would be exactly the same as original-array.npy since they are coming from the same image.

For an example, I used this little image with 4*4 pixels:
original-image.png

Here is a larger version (not the one I'm working with): enter image description here

The last part of the code is the one that converts the .png to .npy. I think the problem is in here somewhere.

import numpy as np
from PIL import Image
from matplotlib import pyplot as plt

filename = 'image-test'

img = Image.open( filename + '.png' )
data = np.array( img, dtype='uint8' )

np.save( filename + '.npy', data)

# visually testing our output
img_array = np.load(filename + '.npy')
plt.imshow(img_array) 

My simple algorithm:

  1. Generate random rgb array and save it as .npy
  2. Save a .png file from that numpy array.
  3. Load that .png file and save it back to .npy
import numpy as np
from matplotlib import pyplot as plt
import matplotlib

from PIL import Image                                                                                


####create a matrix of random colors
filename = "original-array"

matrix=np.random.random((4,4,3))
nx,ny,nz=np.shape(matrix)
CXY=np.zeros([ny, nx])
for i in range(ny):
    for j in range(nx):
        CXY[i,j]=np.max(matrix[j,i,:])

#Save binary data
np.save(filename + '.npy', CXY)
print(filename + " was saved")

#Load npy
img_array = np.load(filename + '.npy')
plt.imshow(img_array)


####Save npy as png
filename = "original-image"

img_name = filename +".png"
matplotlib.image.imsave(img_name, img_array)
print(filename + " was saved")


#### Convert that png back to numpy array

img = Image.open( filename + '.png' )
data = np.array( img, dtype='uint8' )

#Convert the new npy file to png
filename = "new-array"

np.save( filename + '.npy', data)
print(filename + " was saved")


#Load npy
img_array = np.load(filename + '.npy')

filename = "new-image"
#Save as png
img_name = filename +".png"
matplotlib.image.imsave(img_name, img_array)
print(filename + " was saved")

Here is the result : enter image description here

When I regenerate an image from new-array.npy I get exactly the same image as original-image.png:
enter image description here

7
  • 1
    Just so you know, the pixel data in PNG files is compressed. A tiny change in the data, but also a different compression algorithm, may change the file size. To compare the actual data, do so on the decompressed pixels. Commented Dec 17, 2017 at 20:23
  • 1
    Thanks for the answer, but the problem is that my idea is to be able to use that array back for a machine learning algorithm and for that it has to be the same after conversion. How could I do ? Commented Dec 17, 2017 at 20:26
  • 1
    I mean because of that tiny change I'm getting the error : IndexError: index 2323 is out of bounds for axis 0 with size 1400 When I convert an 2400*1400 png to a numpy array and the try to use it. Which is not so strange since the files seems to have different bounds.. Commented Dec 17, 2017 at 20:34
  • The PNG file format stores pixels as integers. You can't save data from a floating point array (such as your CXY or img_array) to a PNG file and expect to read back the same values. Commented Dec 17, 2017 at 21:25
  • 1
    Your array CXY contains floating point numbers in the range 0..1. PNG files can only store integer numbers, and cannot therefore store your floating point values. Commented Aug 18, 2019 at 15:53

1 Answer 1

1

The files are different because the arrays have different data types.

The first time you save the data is when you save the array CXY. This array has a type of np.float64, since that is the default data type returned by np.zeros.

The second array is created by loading the original image, not the saved npy file. This is where the inconsistencies are introduced, since the PNG data is of type np.uint8 (and is cast again to np.uint8 in the next line). This is a smaller data type, hence the smaller overall file size.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.