Package ndimage :: Module measurements
[hide private]
[frames] | no frames]

Source Code for Module ndimage.measurements

  1  # Copyright (C) 2003-2005 Peter J. Verveer 
  2  # 
  3  # Redistribution and use in source and binary forms, with or without 
  4  # modification, are permitted provided that the following conditions 
  5  # are met: 
  6  # 
  7  # 1. Redistributions of source code must retain the above copyright 
  8  #    notice, this list of conditions and the following disclaimer. 
  9  # 
 10  # 2. Redistributions in binary form must reproduce the above 
 11  #    copyright notice, this list of conditions and the following 
 12  #    disclaimer in the documentation and/or other materials provided 
 13  #    with the distribution. 
 14  # 
 15  # 3. The name of the author may not be used to endorse or promote 
 16  #    products derived from this software without specific prior 
 17  #    written permission. 
 18  # 
 19  # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 
 20  # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 21  # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 22  # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 
 23  # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 24  # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
 25  # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 26  # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 27  # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 28  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 29  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 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
74 -def find_objects(input, max_label = 0):
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
168 -def standard_deviation(input, labels = None, index = None):
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
221 -def _index_to_position(index, shape):
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
235 -def minimum_position(input, labels = None, index = None):
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
258 -def maximum_position(input, labels = None, index = None):
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
310 -def center_of_mass(input, labels = None, index = None):
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
401 -def _broadcast(arr, sshape):
402 """Return broadcast view of arr, else return None.""" 403 ashape = arr.shape 404 return_value = numpy.zeros(sshape, arr.dtype) 405 # Just return arr if they have the same shape 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