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
29
30
31 from __future__ import division
32 import types
33 import math
34 import numpy
35 import _ni_support
36 import _nd_image
37 import morphology
38
39 -def label(input, structure = None, output = None):
40 """Label an array of objects.
41
42 The structure that defines the object connections must be
43 symmetric. If no structuring element is provided an element is
44 generated with a squared connectivity equal to one. This function
45 returns a tuple consisting of the array of labels and the number
46 of objects found. If an output array is provided only the number of
47 objects found is returned.
48 """
49 input = numpy.asarray(input)
50 if numpy.iscomplexobj(input):
51 raise TypeError, 'Complex type not supported'
52 if structure is None:
53 structure = morphology.generate_binary_structure(input.ndim, 1)
54 structure = numpy.asarray(structure, dtype = bool)
55 if structure.ndim != input.ndim:
56 raise RuntimeError, 'structure and input must have equal rank'
57 for ii in structure.shape:
58 if ii != 3:
59 raise RuntimeError, 'structure dimensions must be equal to 3'
60 if not structure.flags.contiguous:
61 structure = structure.copy()
62 if isinstance(output, numpy.ndarray):
63 if output.dtype.type != numpy.int32:
64 raise RuntimeError, 'output type must be int32'
65 else:
66 output = numpy.int32
67 output, return_value = _ni_support._get_output(output, input)
68 max_label = _nd_image.label(input, structure, output)
69 if return_value is None:
70 return max_label
71 else:
72 return return_value, max_label
73
75 """Find objects in a labeled array.
76
77 The input must be an array with labeled objects. A list of slices
78 into the array is returned that contain the objects. The list
79 represents a sequence of the numbered objects. If a number is
80 missing, None is returned instead of a slice. If max_label > 0, it
81 gives the largest object number that is searched for, otherwise
82 all are returned.
83 """
84 input = numpy.asarray(input)
85 if numpy.iscomplexobj(input):
86 raise TypeError, 'Complex type not supported'
87 if max_label < 1:
88 max_label = input.max()
89 return _nd_image.find_objects(input, max_label)
90
91 -def sum(input, labels=None, index=None):
92 """Calculate the sum of the values of the array.
93
94 :Parameters:
95 labels : array of integers, same shape as input
96 Assign labels to the values of the array.
97
98 index : scalar or array
99 A single label number or a sequence of label numbers of
100 the objects to be measured. If index is None, all
101 values are used where 'labels' is larger than zero.
102
103 Examples
104 --------
105
106 >>> input = [0,1,2,3]
107 >>> labels = [1,1,2,2]
108 >>> sum(input, labels, index=[1,2])
109 [1.0, 5.0]
110
111 """
112 input = numpy.asarray(input)
113 if numpy.iscomplexobj(input):
114 raise TypeError, 'Complex type not supported'
115 if labels is not None:
116 labels = numpy.asarray(labels)
117 labels = _broadcast(labels, input.shape)
118
119 if labels.shape != input.shape:
120 raise RuntimeError, 'input and labels shape are not equal'
121 if index is not None:
122 T = getattr(index,'dtype',numpy.int32)
123 if T not in [numpy.int8, numpy.int16, numpy.int32,
124 numpy.uint8, numpy.uint16, numpy.bool]:
125 raise ValueError("Invalid index type")
126 index = numpy.asarray(index,dtype=T)
127 return _nd_image.statistics(input, labels, index, 0)
128
129
130 -def mean(input, labels = None, index = None):
131 """Calculate the mean of the values of the array.
132
133 The index parameter is a single label number or a sequence of
134 label numbers of the objects to be measured. If index is None, all
135 values are used where labels is larger than zero.
136 """
137 input = numpy.asarray(input)
138 if numpy.iscomplexobj(input):
139 raise TypeError, 'Complex type not supported'
140 if labels is not None:
141 labels = numpy.asarray(labels)
142 labels = _broadcast(labels, input.shape)
143
144 if labels.shape != input.shape:
145 raise RuntimeError, 'input and labels shape are not equal'
146 return _nd_image.statistics(input, labels, index, 1)
147
148
149 -def variance(input, labels = None, index = None):
150 """Calculate the variance of the values of the array.
151
152 The index parameter is a single label number or a sequence of
153 label numbers of the objects to be measured. If index is None, all
154 values are used where labels is larger than zero.
155 """
156 input = numpy.asarray(input)
157 if numpy.iscomplexobj(input):
158 raise TypeError, 'Complex type not supported'
159 if labels is not None:
160 labels = numpy.asarray(labels)
161 labels = _broadcast(labels, input.shape)
162
163 if labels.shape != input.shape:
164 raise RuntimeError, 'input and labels shape are not equal'
165 return _nd_image.statistics(input, labels, index, 2)
166
167
169 """Calculate the standard deviation of the values of the array.
170
171 The index parameter is a single label number or a sequence of
172 label numbers of the objects to be measured. If index is None, all
173 values are used where labels is larger than zero.
174 """
175 var = variance(input, labels, index)
176 if (isinstance(var, types.ListType)):
177 return [math.sqrt(x) for x in var]
178 else:
179 return math.sqrt(var)
180
181
182 -def minimum(input, labels = None, index = None):
183 """Calculate the minimum of the values of the array.
184
185 The index parameter is a single label number or a sequence of
186 label numbers of the objects to be measured. If index is None, all
187 values are used where labels is larger than zero.
188 """
189 input = numpy.asarray(input)
190 if numpy.iscomplexobj(input):
191 raise TypeError, 'Complex type not supported'
192 if labels is not None:
193 labels = numpy.asarray(labels)
194 labels = _broadcast(labels, input.shape)
195
196 if labels.shape != input.shape:
197 raise RuntimeError, 'input and labels shape are not equal'
198 return _nd_image.statistics(input, labels, index, 3)
199
200
201 -def maximum(input, labels=None, index=None):
202 """Return the maximum input value.
203
204 The index parameter is a single label number or a sequence of
205 label numbers of the objects to be measured. If index is None, all
206 values are used where labels is larger than zero.
207
208 """
209 input = numpy.asarray(input)
210 if numpy.iscomplexobj(input):
211 raise TypeError, 'Complex type not supported'
212 if labels is not None:
213 labels = numpy.asarray(labels)
214 labels = _broadcast(labels, input.shape)
215
216 if labels.shape != input.shape:
217 raise RuntimeError, 'input and labels shape are not equal'
218 return _nd_image.statistics(input, labels, index, 4)
219
220
222 """Convert a linear index to a position"""
223 if len(shape) > 0:
224 pos = []
225 stride = numpy.multiply.reduce(shape)
226 for size in shape:
227 stride = stride // size
228 pos.append(index // stride)
229 index -= pos[-1] * stride
230 return tuple(pos)
231 else:
232 return 0
233
234
236 """Find the position of the minimum of the values of the array.
237
238 The index parameter is a single label number or a sequence of
239 label numbers of the objects to be measured. If index is None, all
240 values are used where labels is larger than zero.
241 """
242 input = numpy.asarray(input)
243 if numpy.iscomplexobj(input):
244 raise TypeError, 'Complex type not supported'
245 if labels is not None:
246 labels = numpy.asarray(labels)
247 labels = _broadcast(labels, input.shape)
248
249 if labels.shape != input.shape:
250 raise RuntimeError, 'input and labels shape are not equal'
251 pos = _nd_image.statistics(input, labels, index, 5)
252 if (isinstance(pos, types.ListType)):
253 return [_index_to_position(x, input.shape) for x in pos]
254 else:
255 return _index_to_position(pos, input.shape)
256
257
259 """Find the position of the maximum of the values of the array.
260
261 The index parameter is a single label number or a sequence of
262 label numbers of the objects to be measured. If index is None, all
263 values are used where labels is larger than zero.
264 """
265 input = numpy.asarray(input)
266 if numpy.iscomplexobj(input):
267 raise TypeError, 'Complex type not supported'
268 if labels is not None:
269 labels = numpy.asarray(labels)
270 labels = _broadcast(labels, input.shape)
271
272 if labels.shape != input.shape:
273 raise RuntimeError, 'input and labels shape are not equal'
274 pos = _nd_image.statistics(input, labels, index, 6)
275 if (isinstance(pos, types.ListType)):
276 return [_index_to_position(x, input.shape) for x in pos]
277 else:
278 return _index_to_position(pos, input.shape)
279
280
281 -def extrema(input, labels = None, index = None):
282 """Calculate the minimum, the maximum and their positions of the
283 values of the array.
284
285 The index parameter is a single label number or a sequence of
286 label numbers of the objects to be measured. If index is None, all
287 values are used where labels is larger than zero.
288 """
289 input = numpy.asarray(input)
290 if numpy.iscomplexobj(input):
291 raise TypeError, 'Complex type not supported'
292 if labels is not None:
293 labels = numpy.asarray(labels)
294 labels = _broadcast(labels, input.shape)
295
296 if labels.shape != input.shape:
297 raise RuntimeError, 'input and labels shape are not equal'
298
299
300 min, max, minp, maxp = _nd_image.statistics(input, labels, index, 7)
301 if (isinstance(minp, types.ListType)):
302 minp = [_index_to_position(x, input.shape) for x in minp]
303 maxp = [_index_to_position(x, input.shape) for x in maxp]
304 else:
305 minp = _index_to_position(minp, input.shape)
306 maxp = _index_to_position(maxp, input.shape)
307 return min, max, minp, maxp
308
309
311 """Calculate the center of mass of of the array.
312
313 The index parameter is a single label number or a sequence of
314 label numbers of the objects to be measured. If index is None, all
315 values are used where labels is larger than zero.
316 """
317 input = numpy.asarray(input)
318 if numpy.iscomplexobj(input):
319 raise TypeError, 'Complex type not supported'
320 if labels is not None:
321 labels = numpy.asarray(labels)
322 labels = _broadcast(labels, input.shape)
323
324 if labels.shape != input.shape:
325 raise RuntimeError, 'input and labels shape are not equal'
326 return _nd_image.center_of_mass(input, labels, index)
327
328
329 -def histogram(input, min, max, bins, labels = None, index = None):
330 """Calculate a histogram of of the array.
331
332 The histogram is defined by its minimum and maximum value and the
333 number of bins.
334
335 The index parameter is a single label number or a sequence of
336 label numbers of the objects to be measured. If index is None, all
337 values are used where labels is larger than zero.
338 """
339 input = numpy.asarray(input)
340 if numpy.iscomplexobj(input):
341 raise TypeError, 'Complex type not supported'
342 if labels is not None:
343 labels = numpy.asarray(labels)
344 labels = _broadcast(labels, input.shape)
345
346 if labels.shape != input.shape:
347 raise RuntimeError, 'input and labels shape are not equal'
348 if bins < 1:
349 raise RuntimeError, 'number of bins must be >= 1'
350 if min >= max:
351 raise RuntimeError, 'min must be < max'
352 return _nd_image.histogram(input, min, max, bins, labels, index)
353
354 -def watershed_ift(input, markers, structure = None, output = None):
355 """Apply watershed from markers using a iterative forest transform
356 algorithm.
357
358 Negative markers are considered background markers which are
359 processed after the other markers. A structuring element defining
360 the connectivity of the object can be provided. If none is
361 provided an element is generated iwth a squared connecitiviy equal
362 to one. An output array can optionally be provided.
363 """
364 input = numpy.asarray(input)
365 if input.dtype.type not in [numpy.uint8, numpy.uint16]:
366 raise TypeError, 'only 8 and 16 unsigned inputs are supported'
367 if structure is None:
368 structure = morphology.generate_binary_structure(input.ndim, 1)
369 structure = numpy.asarray(structure, dtype = bool)
370 if structure.ndim != input.ndim:
371 raise RuntimeError, 'structure and input must have equal rank'
372 for ii in structure.shape:
373 if ii != 3:
374 raise RuntimeError, 'structure dimensions must be equal to 3'
375 if not structure.flags.contiguous:
376 structure = structure.copy()
377 markers = numpy.asarray(markers)
378 if input.shape != markers.shape:
379 raise RuntimeError, 'input and markers must have equal shape'
380
381 integral_types = [numpy.int0,
382 numpy.int8,
383 numpy.int16,
384 numpy.int32,
385 numpy.int_,
386 numpy.int64,
387 numpy.intc,
388 numpy.intp]
389
390 if markers.dtype.type not in integral_types:
391 raise RuntimeError, 'marker should be of integer type'
392 if isinstance(output, numpy.ndarray):
393 if output.dtype.type not in integral_types:
394 raise RuntimeError, 'output should be of integer type'
395 else:
396 output = markers.dtype
397 output, return_value = _ni_support._get_output(output, input)
398 _nd_image.watershed_ift(input, markers, structure, output)
399 return return_value
400
402 """Return broadcast view of arr, else return None."""
403 ashape = arr.shape
404 return_value = numpy.zeros(sshape, arr.dtype)
405
406 if sshape == ashape:
407 return arr
408 srank = len(sshape)
409 arank = len(ashape)
410
411 aslices = []
412 sslices = []
413 for i in range(arank):
414 aslices.append(slice(0, ashape[i], 1))
415
416 for i in range(srank):
417 sslices.append(slice(0, sshape[i], 1))
418 return_value[sslices] = arr[aslices]
419 return return_value
420