1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 try:
29 from PIL import ImageFilter, ImageChops, Image, ImageDraw, ImageColor, ImageEnhance
30 except ImportError:
31 import ImageFilter, ImageChops, Image, ImageDraw, ImageColor, ImageEnhance
32
33 import numpy
34
35
37 """ Given a list of colors, create a larger list of colors interpolating
38 the first one. If flatten is True a list of numers will be returned. If
39 False, a list of (r,g,b) tuples. num_colors is the number of colors wanted
40 in the final list """
41
42 palette = []
43
44 for i in range(num_colors):
45 index = (i * (len(colors) - 1))/(num_colors - 1.0)
46 index_int = int(index)
47 alpha = index - float(index_int)
48
49 if alpha > 0:
50 r = (1.0 - alpha) * colors[index_int][0] + alpha * colors[index_int + 1][0]
51 g = (1.0 - alpha) * colors[index_int][1] + alpha * colors[index_int + 1][1]
52 b = (1.0 - alpha) * colors[index_int][2] + alpha * colors[index_int + 1][2]
53 else:
54 r = (1.0 - alpha) * colors[index_int][0]
55 g = (1.0 - alpha) * colors[index_int][1]
56 b = (1.0 - alpha) * colors[index_int][2]
57
58 if flat:
59 palette.extend((int(r), int(g), int(b)))
60 else:
61 palette.append((int(r), int(g), int(b)))
62
63 return palette
64
65
67 """
68 downsample(vector, factor):
69 Downsample (by averaging) a vector by an integer factor.
70 """
71 if (len(vector) % factor):
72 print "Length of 'vector' is not divisible by 'factor'=%d!" % factor
73 return 0
74 vector.shape = (len(vector)/factor, factor)
75 return numpy.mean(vector, axis=1)
76
77
78 -def smooth(x, window_len=10, window='hanning'):
79 """
80 Smooth the data using a window with requested size.
81
82 This method is based on the convolution of a scaled window with the signal.
83 The signal is prepared by introducing reflected copies of the signal
84 (with the window size) in both ends so that transient parts are minimized
85 in the begining and end part of the output signal.
86
87 Parameters
88 ----------
89 x : numpy.array
90 the input signal
91 window_len : int
92 the dimension of the smoothing window
93 window : str
94 the type of window from 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'
95 flat window will produce a moving average smoothing.
96
97 Returns
98 -------
99 The smoothed signal
100
101 See Also
102 -------
103
104 numpy.hanning, numpy.hamming, numpy.bartlett, numpy.blackman, numpy.convolve
105 scipy.signal.lfilter
106
107 Examples
108 --------
109
110 >>> import numpy as np
111 >>> from timeside.grapher import smooth
112 >>> t = np.arange(-2,2,0.1)
113 >>> x = np.sin(t)+np.random.randn(len(t))*0.1
114 >>> y = smooth(x)
115 >>> import matplotlib.pyplot as plt
116 >>> plt.plot(x) # doctest: +SKIP
117 [<matplotlib.lines.Line2D object at 0x...>]
118 >>> plt.plot(y) # doctest: +SKIP
119 [<matplotlib.lines.Line2D object at 0x...>]
120 >>> plt.legend(['Source signal', 'Smoothed signal']) # doctest: +SKIP
121 <matplotlib.legend.Legend object at 0x...>
122 >>> plt.show() # doctest: +SKIP
123 """
124
125
126
127 if x.ndim != 1:
128 raise ValueError, "smooth only accepts 1 dimension arrays."
129 if x.size < window_len:
130 raise ValueError, "Input vector needs to be bigger than window size."
131 if window_len < 3:
132 return x
133 if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']:
134 raise ValueError, "Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'"
135
136 s = numpy.r_[2*x[0]-x[window_len:1:-1], x, 2*x[-1]-x[-1:-window_len:-1]]
137
138 if window == 'flat':
139 w = numpy.ones(window_len,'d')
140 else:
141 w = getattr(numpy, window)(window_len)
142
143 y = numpy.convolve(w/w.sum(), s, mode='same')
144 return y[window_len-1:-window_len+1]
145
146
148 """Returns an image with reduced opacity."""
149 assert opacity >= 0 and opacity <= 1
150 if im.mode != 'RGBA':
151 im = im.convert('RGBA')
152 else:
153 im = im.copy()
154 alpha = im.split()[3]
155 alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
156 im.putalpha(alpha)
157 return im
158
159
160 -def im_watermark(im, inputtext, font=None, color=None, opacity=.6, margin=(30,30)):
161 """imprints a PIL image with the indicated text in lower-right corner"""
162 if im.mode != "RGBA":
163 im = im.convert("RGBA")
164 textlayer = Image.new("RGBA", im.size, (0,0,0,0))
165 textdraw = ImageDraw.Draw(textlayer)
166 textsize = textdraw.textsize(inputtext, font=font)
167 textpos = [im.size[i]-textsize[i]-margin[i] for i in [0,1]]
168 textdraw.text(textpos, inputtext, font=font, fill=color)
169 if opacity != 1:
170 textlayer = reduce_opacity(textlayer,opacity)
171 return Image.composite(textlayer, im, textlayer)
172
173
175 """ Find the minimum and maximum peak of the samples.
176 Returns that pair in the order they were found.
177 So if min was found first, it returns (min, max) else the other way around. """
178 max_index = numpy.argmax(samples)
179 max_value = samples[max_index]
180
181 min_index = numpy.argmin(samples)
182 min_value = samples[min_index]
183
184 if min_index < max_index:
185 return (min_value, max_value)
186 else:
187 return (max_value, min_value)
188
189
191 """ given a value between 0 and 1, return an (r,g,b) tuple """
192 return ImageColor.getrgb("hsl(%d,%d%%,%d%%)" % (int( (1.0 - value) * 360 ), 80, 50))
193
194
196 return numpy.mean(samples)
197
198
200 contour = contour-min(contour)
201 return contour/max(contour)
202