Home > Mobile >  How to save images after normalizing the pixels?
How to save images after normalizing the pixels?

Time:04-14

I want to normalize my images and use it in the training. But I couldn't find a way to save images after making changes below...How can I save and load them ?

files = ["/content/drive/MyDrive/Colab Notebooks/images/evre1/xyz.png",
         "/content/drive/MyDrive/Colab Notebooks/images/evre1/xty.png"]

def normalize(files):
  for i in files:

      image = Image.open(i)
      new_image =image.resize((224,224))
      pixels = asarray(image)
      # convert from integers to floats
      pixels = pixels.astype('float32')
      # calculate global mean and standard deviation
      mean, std = pixels.mean(), pixels.std()
      # print('Mean: %.3f, Standard Deviation: %.3f' % (mean, std))
      # global standardization of pixels
      pixels = (pixels - mean) / std
      # confirm it had the desired effect
      print(pixels)
      # mean, std = pixels.mean(), pixels.std()
      # print('Mean: %.3f, Standard Deviation: %.3f' % (mean, std))
  

normalize(files)

I tried to save them as array:

np.save(outfile, pixels)

Then,

_ = outfile.seek(0) 
t = np.load(outfile)

img_w, img_h = 224, 224
img = Image.fromarray(t, 'RGB')
img.save('test.png')
img.show()

But there is no image appeared..

I searched lots of documents and gave many hours to solve it...I am waiting any kind of helps. thanks.

CodePudding user response:

I think your best option is to save the mean and the std with each normalized image (in the same .npy file).

When loading the normalized image, also load mean and std - that allows us to restore the original image (before normalizing).


Note:
We may display the normalized image like this (for example):

Image.fromarray(((t-t.min())/(t.max()-t.min())*255).astype(np.uint8), 'RGB').show()

By the way you are asking your question, it looks like restoring the original image is a better solution.


Saving and restoring the normalized image with the original mean and std:

Example for saving pixels with mean and std:

with open(outfile_name, 'wb') as f:
    np.save(f, pixels)  # Save the normalized image.
    np.save(f, np.array([mean, std]))  # Save mean and std as 2 elements numpy array after the "pixels" array (in the same file).

Example for loading the normalized image with the mean and std, and restoring and showing the original image:

with open(outfile_name, 'rb') as f:
    norm_t = np.load(f)  # Load normalized array
    mean_std = np.load(f)  # Load mean and std (that were saved before).
    mean, std = tuple(mean_std)  # Get mean and std as two scalars

    t = norm_t*std   mean  # Unnormalized (get the original pixels before normalizing)
    t = np.round(t.clip(0, 255)).astype(np.uint8)  # Convert from float to uint8 (use rounding and clipping for "cleaner" conversion).
    img = Image.fromarray(t, 'RGB')
    img.save('test.png')
    img.show()

Complete code sample (including the loop):

import numpy as np
from PIL import Image

files = ["xyz.png", "xty.png"]

def normalize(files):
    for i in files:
        image = Image.open(i)
        new_image = image.resize((224, 224))
        pixels = np.asarray(image)
        # convert from integers to floats
        pixels = pixels.astype('float32')
        # calculate global mean and standard deviation
        mean, std = pixels.mean(), pixels.std()
        # print('Mean: %.3f, Standard Deviation: %.3f' % (mean, std))
        # global standardization of pixels
        pixels = (pixels - mean) / std
        # confirm it had the desired effect
        print(pixels)
        # mean, std = pixels.mean(), pixels.std()
        # print('Mean: %.3f, Standard Deviation: %.3f' % (mean, std))

        #t = pixels
        #Image.fromarray(((t-t.min())/(t.max()-t.min())*255).astype(np.uint8), 'RGB').show()

        outfile_name = i.replace(".png", ".npy")  # "xyz.npy" and "xty.npy"

        # Save pixels, and also save np.array([mean, std]):
        with open(outfile_name, 'wb') as f:
            np.save(f, pixels)  # Save the normalized image.
            np.save(f, np.array([mean, std]))  # Save mean and std as 2 elements numpy array after the "pixels" array (in the same file).

        # Load outfile_name (normalized image) and [mean, std] array
        with open(outfile_name, 'rb') as f:
            norm_t = np.load(f)  # Load normalized array
            mean_std = np.load(f)  # Load mean and std (that were saved before).
            mean, std = tuple(mean_std)  # Get mean and std as two scalars

            t = norm_t*std   mean  # Unnormalized (get the original pixels before normalizing)
            t = np.round(t.clip(0, 255)).astype(np.uint8)  # Convert from float to uint8 (use rounding and clipping for "cleaner" conversion).
            img = Image.fromarray(t, 'RGB')
            img.save('test.png')
            img.show()
  
normalize(files)

CodePudding user response:

If you want to store RGB images with floating point pixels, you cannot use PNG, JPEG, TGA or GIF formats. You are more or less obliged to use either TIFF, or PFM - though there are even more obscure HDR/EXR formats available.

You also cannot use these with PIL/Pillow because it doesn't support 32-bit float RGB files.

So, in short, IMHO if you want float and RGB, you probably want:

  • TIFF (maybe via tifffile) or PFM (maybe EXR) for storage format, and
  • OpenCV, scikit-image, or libvips for processing
  • Related