>>> footprint = array([[0,1,0],[1,1,1],[0,1,0]]) >>> print footprint [[0 1 0] [1 1 1] [0 1 0]]
>>> a = [0, 0, 0, 1, 0, 0, 0] >>> correlate1d(a, [1, 1, 1]) [0 0 1 1 1 0 0]
>>> a = [0, 0, 0, 1, 0, 0, 0] >>> print correlate1d(a, [1, 1, 1], origin = -1) [0 1 1 1 0 0 0]
>>> a = [0, 0, 1, 1, 1, 0, 0] >>> print correlate1d(a, [-1, 1]) ## backward difference [ 0 0 1 0 0 -1 0] >>> print correlate1d(a, [-1, 1], origin = -1) ## forward difference [ 0 1 0 0 -1 0 0]
>>> print correlate1d(a, [0, -1, 1]) [ 0 1 0 0 -1 0 0]
Since the output elements are a function of elements in the neighborhood of the input elements, the borders of the array need to be dealt with appropriately by providing the values outside the borders. This is done by assuming that the arrays are extended beyond their boundaries according certain boundary conditions. In the functions described below, the boundary conditions can be selected using the mode parameter which must be a string with the name of the boundary condition. Following boundary conditions are currently supported:
Boundary condition | Description | Example |
---|---|---|
"nearest" | Use the value at the boundary | [1 2 3]->[1 1 2 3 3] |
"wrap" | Periodically replicate the array | [1 2 3]->[3 1 2 3 1] |
"reflect" | Reflect the array at the boundary | [1 2 3]->[1 1 2 3 3] |
"constant" | Use a constant value, default value is 0.0 | [1 2 3]->[0 1 2 3 0] |
Note: The easiest way to implement such boundary conditions would be to copy the data to a larger array and extend the data at the borders according to the boundary conditions. For large arrays and large filter kernels, this would be very memory consuming, and the functions described below therefore use a different approach that does not require allocating large temporary buffers.
input, weights, axis=-1, output=None, mode='reflect', cval=0.0, origin=0, output_type=None) |
input, weights, output=None, mode='reflect', cval=0.0, origin=0, output_type=None) |
input, weights, axis=-1, output=None, mode='reflect', cval=0.0, origin=0, output_type=None) |
Note: A convolution is essentially a correlation after mirroring the kernel. As a result, the origin parameter behaves differently than in the case of a correlation: the result is shifted in the opposite directions.
input, weights, output=None, mode='reflect', cval=0.0, origin=0, output_type=None) |
Note: A convolution is essentially a correlation after mirroring the kernel. As a result, the origin parameter behaves differently than in the case of a correlation: the results is shifted in the opposite direction.
input, sigma, axis=-1, order=0, output=None, mode='reflect', cval=0.0, output_type=None) |
input, sigma, order=0, output=None, mode='reflect', cval=0.0, output_type=None) |
Note: The multi-dimensional filter is implemented as a sequence of one-dimensional Gaussian filters. The intermediate arrays are stored in the same data type as the output. Therefore, for output types with a lower precision, the results may be imprecise because intermediate results may be stored with insufficient precision. This can be prevented by specifying a more precise output type.
input, size, axis=-1, output=None, mode='reflect', cval=0.0, origin=0, output_type=None) |
input, size, output=None, mode='reflect', cval=0.0, origin=0, output_type=None) |
Note: The multi-dimensional filter is implemented as a sequence of one-dimensional uniform filters. The intermediate arrays are stored in the same data type as the output. Therefore, for output types with a lower precision, the results may be imprecise because intermediate results may be stored with insufficient precision. This can be prevented by specifying a more precise output type.
input, size, axis=-1, output=None, mode='reflect', cval=0.0, origin=0) |
input, size, axis=-1, output=None, mode='reflect', cval=0.0, origin=0) |
input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0) |
input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0) |
input, rank, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0) |
input, percentile, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0) |
input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0) |
Derivative filters can be constructed in several ways. The function gaussian_filter1d described in section 21.3.2 can be used to calculate derivatives along a given axis using the order parameter. Other derivative filters are the Prewitt and Sobel filters:
input, axis=-1, output=None, mode='reflect', cval=0.0) |
input, axis=-1, output=None, mode='reflect', cval=0.0) |
The Laplace filter is calculated by the sum of the second derivatives along all axes. Thus, different Laplace filters can be constructed using different second derivative functions. Therefore we provide a general function that takes a function argument to calculate the second derivative along a given direction and to construct the Laplace filter:
input, derivative2, output=None, mode='reflect', cval=0.0, output_type=None, extra_arguments = (), extra_keywords = ) |
derivative2(input, axis, output, mode, cval, *extra_arguments, **extra_keywords)
It should calculate the second derivative along the dimension axis. If output is not None it should use that for the output and return None, otherwise it should return the result. mode, cval have the usual meaning.
The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and a dictionary of named arguments that are passed to derivative2 at each call.
For example:
>>> def d2(input, axis, output, mode, cval): ... return correlate1d(input, [1, -2, 1], axis, output, mode, cval, 0) ... >>> a = zeros((5, 5)) >>> a[2, 2] = 1 >>> print generic_laplace(a, d2) [[ 0 0 0 0 0] [ 0 0 1 0 0] [ 0 1 -4 1 0] [ 0 0 1 0 0] [ 0 0 0 0 0]]
>>> def d2(input, axis, output, mode, cval, weights): ... return correlate1d(input, weights, axis, output, mode, cval, 0,) ... >>> a = zeros((5, 5)) >>> a[2, 2] = 1 >>> print generic_laplace(a, d2, extra_arguments = ([1, -2, 1],)) [[ 0 0 0 0 0] [ 0 0 1 0 0] [ 0 1 -4 1 0] [ 0 0 1 0 0] [ 0 0 0 0 0]]
>>> print generic_laplace(a, d2, extra_keywords = {'weights': [1, -2, 1]}) [[ 0 0 0 0 0] [ 0 0 1 0 0] [ 0 1 -4 1 0] [ 0 0 1 0 0] [ 0 0 0 0 0]]
The following two functions are implemented using generic_laplace by providing appropriate functions for the second derivative function:
input, output=None, mode='reflect', cval=0.0, output_type=None) |
input, sigma, output=None, mode='reflect', cval=0.0, output_type=None) |
The gradient magnitude is defined as the square root of the sum of the squares of the gradients in all directions. Similar to the generic Laplace function there is a generic_gradient_magnitude function that calculated the gradient magnitude of an array:
input, derivative, output=None, mode='reflect', cval=0.0, output_type=None, extra_arguments = (), extra_keywords = ) |
derivative(input, axis, output, mode, cval, *extra_arguments, **extra_keywords)
It should calculate the derivative along the dimension axis. If output is not None it should use that for the output and return None, otherwise it should return the result. mode, cval have the usual meaning.
The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and a dictionary of named arguments that are passed to derivative at each call.
For example, the sobel function fits the required signature:
>>> a = zeros((5, 5)) >>> a[2, 2] = 1 >>> print generic_gradient_magnitude(a, sobel) [[0 0 0 0 0] [0 1 2 1 0] [0 2 0 2 0] [0 1 2 1 0] [0 0 0 0 0]]
The sobel and prewitt functions fit the required signature and can therefore directly be used with generic_gradient_magnitude. The following function implements the gradient magnitude using Gaussian derivatives:
input, sigma, output=None, mode='reflect', cval=0.0, output_type=None) |
input, function, filter_size, axis=-1, output=None, mode="reflect", cval=0.0, origin=0, output_type=None, extra_arguments = (), extra_keywords = ) |
>>> a = arange(12, shape = (3,4)) >>> print correlate1d(a, [1, 2, 3]) [[ 3 8 14 17] [27 32 38 41] [51 56 62 65]]
>>> def fnc(iline, oline): ... oline[...] = iline[:-2] + 2 * iline[1:-1] + 3 * iline[2:] ... >>> print generic_filter1d(a, fnc, 3) [[ 3 8 14 17] [27 32 38 41] [51 56 62 65]]
Optionally extra arguments can be defined and passed to the filter function. The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and/or a dictionary of named arguments that are passed to derivative at each call. For example, we can pass the parameters of our filter as an argument:
>>> def fnc(iline, oline, a, b): ... oline[...] = iline[:-2] + a * iline[1:-1] + b * iline[2:] ... >>> print generic_filter1d(a, fnc, 3, extra_arguments = (2, 3)) [[ 3 8 14 17] [27 32 38 41] [51 56 62 65]]
>>> print generic_filter1d(a, fnc, 3, extra_keywords = {'a':2, 'b':3}) [[ 3 8 14 17] [27 32 38 41] [51 56 62 65]]
input, function, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0, output_type=None, extra_arguments = (), extra_keywords = ) |
>>> a = arange(12, shape = (3,4)) >>> print correlate(a, [[1, 0], [0, 3]]) [[ 0 3 7 11] [12 15 19 23] [28 31 35 39]]
>>> def fnc(buffer): ... return (buffer * array([1, 3])).sum() ... >>> print generic_filter(a, fnc, footprint = [[1, 0], [0, 1]]) [[ 0 3 7 11] [12 15 19 23] [28 31 35 39]]
When calling generic_filter, either the sizes of a rectangular kernel or the footprint of the kernel must be provided. The size parameter, if provided, must be a sequence of sizes or a single number in which case the size of the filter is assumed to be equal along each axis. The footprint, if provided, must be an array that defines the shape of the kernel by its non-zero elements.
Optionally extra arguments can be defined and passed to the filter function. The extra_arguments and extra_keywords arguments can be used to pass a tuple of extra arguments and/or a dictionary of named arguments that are passed to derivative at each call. For example, we can pass the parameters of our filter as an argument:
>>> def fnc(buffer, weights): ... weights = asarray(weights) ... return (buffer * weights).sum() ... >>> print generic_filter(a, fnc, footprint = [[1, 0], [0, 1]], extra_arguments = ([1, 3],)) [[ 0 3 7 11] [12 15 19 23] [28 31 35 39]]
>>> print generic_filter(a, fnc, footprint = [[1, 0], [0, 1]], extra_keywords= {'weights': [1, 3]}) [[ 0 3 7 11] [12 15 19 23] [28 31 35 39]]
These functions iterate over the lines or elements starting at the last axis, i.e. the last index changest the fastest. This order of iteration is garantueed for the case that it is important to adapt the filter dependening on spatial location. Here is an example of using a class that implements the filter and keeps track of the current coordinates while iterating. It performs the same filter operation as described above for generic_filter, but additionally prints the current coordinates:
>>> a = arange(12, shape = (3,4)) >>> >>> class fnc_class: ... def __init__(self, shape): ... # store the shape: ... self.shape = shape ... # initialize the coordinates: ... self.coordinates = [0] * len(shape) ... ... def filter(self, buffer): ... result = (buffer * array([1, 3])).sum() ... print self.coordinates ... # calculate the next coordinates: ... axes = range(len(self.shape)) ... axes.reverse() ... for jj in axes: ... if self.coordinates[jj] < self.shape[jj] - 1: ... self.coordinates[jj] += 1 ... break ... else: ... self.coordinates[jj] = 0 ... return result ... >>> fnc = fnc_class(shape = (3,4)) >>> print generic_filter(a, fnc.filter, footprint = [[1, 0], [0, 1]]) [0, 0] [0, 1] [0, 2] [0, 3] [1, 0] [1, 1] [1, 2] [1, 3] [2, 0] [2, 1] [2, 2] [2, 3] [[ 0 3 7 11] [12 15 19 23] [28 31 35 39]]
For the generic_filter1d function the same approach works, except that this function does not iterate over the axis that is being filtered. The example for generic_filte1d then becomes this:
>>> a = arange(12, shape = (3,4)) >>> >>> class fnc1d_class: ... def __init__(self, shape, axis = -1): ... # store the filter axis: ... self.axis = axis ... # store the shape: ... self.shape = shape ... # initialize the coordinates: ... self.coordinates = [0] * len(shape) ... ... def filter(self, iline, oline): ... oline[...] = iline[:-2] + 2 * iline[1:-1] + 3 * iline[2:] ... print self.coordinates ... # calculate the next coordinates: ... axes = range(len(self.shape)) ... # skip the filter axis: ... del axes[self.axis] ... axes.reverse() ... for jj in axes: ... if self.coordinates[jj] < self.shape[jj] - 1: ... self.coordinates[jj] += 1 ... break ... else: ... self.coordinates[jj] = 0 ... >>> fnc = fnc1d_class(shape = (3,4)) >>> print generic_filter1d(a, fnc.filter, 3) [0, 0] [1, 0] [2, 0] [[ 3 8 14 17] [27 32 38 41] [51 56 62 65]]
Send comments to the NumArray community.