1

I would like to generate a histogram from a 16 bit greyscale image with Python. When I run the following code, I get a buffer overflow.

#!/usr/bin/python

from PIL import Image
import numpy as np

i = Image.open('t.tif')
a = i.histogram()

print a

Error message (shortened)

tdettmer@thinkpad:~/code/histogram$ ./h.py 
*** buffer overflow detected ***: /usr/bin/python terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7f3f33ed6007]
/lib/x86_64-linux-gnu/libc.so.6(+0x107f00)[0x7f3f33ed4f00]
/usr/lib/python2.7/dist-packages/PIL/_imaging.so(ImagingHistogramNew+0x33)

Now, I can totally see that generating a histogram from a 16 bit image uses a lot of resources, but can I somehow circumvent this problem?

Eekhoorn
  • 906
  • 3
  • 10
  • 24
  • 1
    Please consider posting the versions of the packages you are using, as well as the image that's causing the problem (you can host the image on http://imgur.com/ if you don't have the rep to include images just yet). This will allow people to reproduce your problem. – mpenkov Aug 14 '12 at 08:05
  • I just found out that this script works on our Linux cluster at work, so it's really a resource problem. – Eekhoorn Aug 14 '12 at 08:23

2 Answers2

0

Since you seem to already be using numpy, it's worth pointing out that it has its own histogram function. You could use that after converting the PIL image to a numpy array. Perhaps their histogram implementation would be more resource efficient.

Community
  • 1
  • 1
mpenkov
  • 21,621
  • 10
  • 84
  • 126
0

Since the histogram method of PIL seems to be all weird on 16 bit images, I wrote my own function which generates histograms. I have microscopic images with 12 bit which are stored inside 16 bit tiff files. So the max grey value inside this tiff is 4096.

The function to open the image and read the pixels:

def getPixels(file):
    img = Image.open(file)

    pixels = img.load()
    width, height = img.size

    all_pixels =  []

    for x in range(width):
        for y in range(height):
            cpixel = pixels[x, y]
            all_pixels.append(cpixel)

    return all_pixels

... generate Histogram:

def generateHistogram(file, z):
    px = getPixels(file)
    a = np.histogram(px, bins=np.arange(z))
Eekhoorn
  • 906
  • 3
  • 10
  • 24