Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly convert png to npy numpy array (Image to Array)

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

like image 707
satolas Avatar asked Dec 17 '17 20:12

satolas


People also ask

How images are converted to arrays?

imread() function is used to load the image and It also reads the given image (PIL image) in the NumPy array format. Then we need to convert the image color from BGR to RGB. imwrite() is used to save the image in the file.

Why do we convert image to NumPy array?

Converting an image to an array is an important task to train a machine learning model based on the features of an image. We mainly use the NumPy library in Python to work with arrays so we can also use it to convert images to an array. Other than NumPy, we can also use the Keras library in Python for the same task.


1 Answers

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.

like image 89
Jggrnaut Avatar answered Sep 28 '22 05:09

Jggrnaut