0

I'm trying to do some mathematical operations on single pixels using PIL.

From the internet I could load an image into a 2d array like this:

from PIL import Image
img_filename = "CNH.JPG" 
im = Image.open(img_filename)
im = im.convert('L')
pix = im.load()

I did some changes to a single pixel value aftwards, but when I try to make a division (even if it returns an int) it just rounds to 0 or 255:

>>> i=30
>>> j=45
>>> pix[i,j]
37
>>> pix[i,j]+5
42
>>> pix[i,j]*2
84
>>> pix[i,j]/2
0
>>> pix[i,j]*2
0

It seems the problem I'm having has to do with divisions.

My goal is to normalize my pixels values to floats in range (0,1) instead of (0,255). Therefore I would just divide each pixel value by 255.

Anything I'm missing in Python language?

Also, for future works, I plan on implementing some feature extraction and classification algorithms in Python. Is PIL the right package for this purpose?

Sample code:

from PIL import Image

img_filename = "yourimage.JPG"
im = Image.open(img_filename)
im = im.convert('L')
pix = im.load() 

i=30
j=45

print(pix[i,j])
pix[i,j] = pix[i,j]+5
print(pix[i,j])
pix[i,j] = pix[i,j]*2
print(pix[i,j])
pix[i,j] = float(pix[i,j]/2)
print(pix[i,j])
pix[i,j] = pix[i,j]*2
print(pix[i,j])
fabda01
  • 3,384
  • 2
  • 31
  • 37
  • I can't seem to repro your issue. Is the image you're loading available? – Matt Jun 03 '16 at 17:58
  • I can not reproduce this, either. Please post the image. – nwk Jun 03 '16 at 17:59
  • 1
    Are you sure that your issue isn't [integer division in Python 2.X](http://stackoverflow.com/questions/1267869/how-can-i-force-division-to-be-floating-point-in-python)? – Jared Goguen Jun 03 '16 at 18:00
  • There is no particular image I'm using. I'm just checking a random image pixel. So at pix index (30,45) the pixel value in greyscale is 37. Also I try to force float division, but in the example shown, I'm dividing an even value by 2 which should have given an integer – fabda01 Jun 03 '16 at 18:15
  • 1
    Any reason not to use a well-written library like [scikit-image](http://scikit-image.org/) which supports all that basic stuff? It has a lot of functionality and is based on numpy which helps your next steps regarding machine-learning algos. – sascha Jun 03 '16 at 18:17
  • If you plan to do anything serious on pixels you should transform the PIL image to a numpy array to exploit the vectorized operations and the way better documentation. Personally I always used PIL just to read the image and to save it at the end, using numpy for whatever elaboration I had to do. – Matteo Italia Jun 03 '16 at 19:11

1 Answers1

0

It works fine here:

In [15]: pix[i,j]
Out[15]: 145

In [16]: pix[i,j]+5
Out[16]: 150

In [17]: pix[i,j]/2
Out[17]: 72

In [18]: float(pix[i,j]/2)
Out[18]: 72.0

In [19]: pix[i,j] = float(pix[i,j]/2)
In [20]: pix[i,j]
Out[20]: 72

Of course, this is integer division (hence 145/2 is 72, not 72.5). If you are dividing by 255, everything will come out 0 (except 255 itself, which will come out 1.)

If you want float output, divide by a float (pix[i,j] / 255.0), or else

from __future__ import division

to have the result of dividing two integers give a floating point number by default.

Nick Matteo
  • 4,453
  • 1
  • 24
  • 35