Caleb Renfroe
Caleb Renfroe

Reputation: 375

How to normalize pixel values in an image and save it

I am trying to normalize my data to prepare it as input for this model. I tried following this guide, but have been having issues.

First off, my min and max values aren't starting off as 0 and 255, and the final results are not normalized between 0 and 1.

Here is my function

def process_image(image_path):
    image = Image.open(image_path)
    new_image = image.resize((224,224))
    
    pixels = asarray(new_image)

    # confirm pixel range is 0-255
    print('Data Type: %s' % pixels.dtype)
    print('Min: %.3f, Max: %.3f' % (pixels.min(), pixels.max()))

    # convert from integers to floats
    pixels = pixels.astype('float32')

    # normalize to the range 0-1
    pixels /= 255.0

    # confirm the normalization
    print('Min: %.3f, Max: %.3f' % (pixels.min(), pixels.max()))
    new_image.save("result.jpg")
    
    return new_image

and here is my resulting output

Data Type: uint8
Min: 8.000, Max: 216.000
Min: 0.031, Max: 0.847

Any ideas why? And also, how can I save the image with these normalized results. As the code is written now, the pixels aren't being changed because I am only creating a copy of the pixels from new_image.

Thanks for any help that can be provided.

UPDATED CODE

Thanks to @relh for the help! I implemented his code and it runs great now

The code

def process_image(image_path):
    min = sys.maxsize
    max = -sys.maxsize


    image = Image.open(image_path)
    new_image = image.resize((224,224))    
    np_image = asarray(image)
    if min > np_image.min():
        min = np_image.min()
    if max < np_image.max():
        max = np_image.max()    

    np_image = np_image.astype('float32')
    print("BEGINNING PIXEL VALUES", np_image)
    print('Data Type: %s' % np_image.dtype)
    print('Min: %.3f, Max: %.3f' % (np_image.min(), np_image.max()))
    np_image -= min
    np_image /= (max - min)

    print('Min: %.3f, Max: %.3f' % (np_image.min(), np_image.max()))
    print(np_image)

Output snippet

Min: 2.000, Max: 223.000
Min: 0.000, Max: 1.000

[[0.22171946 0.4162896  0.37104073]
  [0.23076923 0.42533937 0.3846154 ]
  [0.18099548 0.37556562 0.33484164]
  ...
  [0.12217195 0.51583713 0.47511312]
  [0.15837105 0.54751134 0.50678736]
  [0.16742082 0.5565611  0.51583713]]]

Upvotes: 0

Views: 8674

Answers (1)

relh
relh

Reputation: 146

What you can do is calculate the real minimum and maximum values for your dataset, before doing your own minmax normalization.

Here's what that might look like:

import sys
from PIL import Image
import numpy as np

image_paths = ['image_path1.jpg', 'image_path2.jpg', 'image_path3.jpg']
min = sys.maxsize
max = -sys.maxsize

for image_path in image_paths:
    image = Image.open(image_path)
    np_image = np.asarray(image)
    if min > np_image.min()
        min = np_image.min()
    if max < np_image.max()
        max = np_image.max()

This will give you the variables min and max and you can now use them to normalize between 0 and 1 with this instead of the /= 255 you had!

    ...
    pixels -= min
    pixels /= (max - min)
    ...

Let me know if that helps!

Upvotes: 1

Related Questions