Fix imageanalyzer bug when min >= max.
[pyplotsuite.git] / common / img.py
blob977fdf2f6803dc9a13b092b3048557affab997d9
1 #!/usr/bin/env python
2 # -*- coding: UTF8 -*-
4 # Copyright (C) 2006-2007 Antonio Ingargiola <tritemio@gmail.com>
6 # This file is part of Image Analyzer.
8 # Image Analyzer is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 import sys
14 from PIL import Image
15 from numpy import fromstring, resize, array, around, arange, zeros
17 class WrongImageFormat(Exception):
18 """ Exception for image format not known. """
19 def __init__(self, value):
20 self.value = value
21 def __str__(self):
22 return repr(self.value)
24 def image2array(image):
25 """ Converts an image object (PIL) to an array (NumPy). """
26 if image.mode == "RGB":
27 dimensions = (image.size[1], image.size[0], 3)
28 type = 'uint8'
29 elif image.mode == "RGBA":
30 dimensions = (image.size[1], image.size[0], 4)
31 type = 'uint8'
32 elif image.mode == "L":
33 dimensions = (image.size[1], image.size[0])
34 type = 'uint8'
35 elif image.mode == "I;16":
36 dimensions = (image.size[1], image.size[0])
37 type = 'uint16'
38 else:
39 raise WrongImageFormat, "Image type "+image.mode+" unknown."
41 image_string = image.tostring()
42 image_array = fromstring(image_string, type)
43 return resize(image_array, dimensions)
45 def image2array2(image):
46 """Converts an image object (PIL) into an array (NumPy).
47 Seems slightly slower than image2array()."""
48 if image.mode == "RGB":
49 dimensions = (image.size[1], image.size[0], 3)
50 type = 'UInt8'
51 elif image.mode == "RGBA":
52 dimensions = (image.size[1], image.size[0], 4)
53 type = 'UInt8'
54 elif image.mode == "L":
55 dimensions = (image.size[1], image.size[0])
56 type = 'UInt8'
57 elif image.mode == "I;16":
58 dimensions = (image.size[1], image.size[0])
59 type = 'UInt16'
60 else:
61 raise WrongImageFormat, "Image type "+image.mode+" unknown."
63 image_array = array(image.getdata(), dtype='UInt16')
64 return resize(image_array, dimensions)
66 def histogram3(image, nbit):
67 """
68 It is used instead of image.histogram() because the latter does not work
69 with high dynamic images (for example 14 bit).
71 Takes as parameters a PIL image and the number of bit and returns an array
72 2**nbit length containing the image histogram.
74 This function has been written by Fredrik Lundh, in the article:
76 http://effbot.org/zone/image-histogram-optimization.htm
78 This code snipped is public domain as stated at:
80 http://effbot.org/zone/copyright.htm
81 """
83 # wait, use a list, but get rid of that getpixel call
84 result = [0] * 2**nbit
85 for v in image.getdata():
86 result[v] = result[v] + 1
87 return result
89 def histogramfloat(farray, nbit=10, rescale=True):
90 """
91 Calculates (quite) efficiently the histogram of a float array.
93 Returns two arrays of the same length:
94 - an equally spaced array of (quantized) values
95 - the occurrence of each value
97 The optional 'nbit' parameter set the quantization number of bit.
98 The optional 'rescale' flag can inhibit data rescaling. This is useful if
99 your data comes from a source with a known number of bit (for example an
100 image converted to array). In this case you must set the correct 'nbit'
101 and assure that the 'farray' data is contained in the range 0..(2^nbit)-1
102 (extreme included).
105 if rescale:
106 m = farray.max()
107 else:
108 m = (2.**nbit) - 1
110 rarray = around(farray*((2.**nbit)-1)/m).astype(int)
111 values = arange(2**nbit)*m/(2.**nbit-1)
113 hist_data = zeros(2**nbit)
114 for v in rarray.ravel():
115 hist_data[v] += 1
116 return values, hist_data
118 def speed_test():
119 files = sys.argv[1:]
120 if len(files) < 1:
121 files = ['test-img.tif']
123 for file_name in files:
124 try:
125 image = Image.open(file_name)
126 except IOError:
127 print "\n File '"+file_name+"' cannot be opened.\n"
128 sys.exit()
130 profile.run('ia = image2array(image)', 'ia')
131 profile.run('ia2 = image2array2(image)', 'ia2')
133 if __name__ == "__main__":
134 from pylab import *
135 from scipy import lena
136 import profile
138 a = lena()
139 v, h = histogramfloat(a, nbit=8, rescale=False)
140 step = 1
141 print v[0], v[-1]
142 print v[20:30]
143 print h[20:30]
145 plot(v, h, 'ro')
146 bar(v,h, width=step, bottom=0.01, edgecolor='blue')
147 grid(True)
148 show()