def elastic_transform(image, alpha, sigma):
"""
Elastic deformation of images as described in [1].
[1] Simard, Steinkraus and Platt, "Best Practices for Convolutional
Neural Networks applied to Visual Document Analysis", in Proc. of the
International Conference on Document Analysis and Recognition, 2003.
Based on gist https://gist.github.com/erniejunior/601cdf56d2b424757de5
Args:
image (np.ndarray): image to be deformed
alpha (list): scale of transformation for each dimension, where larger
values have more deformation
sigma (list): Gaussian window of deformation for each dimension, where
smaller values have more localised deformation
Returns:
np.ndarray: deformed image
"""
assert len(alpha) == len(sigma), \
"Dimensions of alpha and sigma are different"
channelbool = image.ndim - len(alpha)
out = np.zeros((len(alpha) + channelbool, ) + image.shape)
# Generate a Gaussian filter, leaving channel dimensions zeroes
for jj in range(len(alpha)):
array = (np.random.rand(*image.shape) * 2 - 1)
out[jj] = gaussian_filter(array, sigma[jj],
mode="constant", cval=0) * alpha[jj]
# Map mask to indices
shapes = list(map(lambda x: slice(0, x, None), image.shape))
grid = np.broadcast_arrays(*np.ogrid[shapes])
indices = list(map((lambda x: np.reshape(x, (-1, 1))), grid + np.array(out)))
# Transform image based on masked indices
transformed_image = map_coordinates(image, indices, order=0,
mode='reflect').reshape(image.shape)
return transformed_image
python类broadcast_arrays()的实例源码
def min(self, source_depths, receiver_depths, distances, method='linear'):
'''
Returns the minimum (minima) travel time(s) for the point(s) identified by
(source_depths, receiver_depths, distances) by building a grid and
interpolating on the points identified by each
P[i] = (source_depths[i], receiver_depths[i], distances[i])
```
if the source file has been built with
receiver depths == [0]. It uses a 2d linear interpolation on a grid. It uses
scipy griddata
:param source_depths: numeric or numpy array of length n: the source depth(s), in km
:param receiver_depths: numeric or numpy array of length n: the receiver depth(s), in km.
For most applications, this value can be set to zero
:param distances: numeric or numpy array of length n: the distance(s), in degrees
:param method: forwarded to `scipy.griddata` function
:return: a numpy array of length n denoting the minimum travel time(s) of this model for
each P
'''
# Handle the case some arguments are scalars and some arrays:
source_depths, receiver_depths, distances = \
np.broadcast_arrays(source_depths, receiver_depths, distances)
# handle the case all arguments scalars. See
# https://stackoverflow.com/questions/29318459/python-function-that-handles-scalar-or-arrays
allscalars = all(_.ndim == 0 for _ in (source_depths, receiver_depths, distances))
if source_depths.ndim == 0:
source_depths = source_depths[None] # Makes x 1D
if receiver_depths.ndim == 0:
receiver_depths = receiver_depths[None] # Makes x 1D
if distances.ndim == 0:
distances = distances[None] # Makes x 1D
# correct source depths and receiver depths
source_depths[source_depths < 0] = 0
receiver_depths[receiver_depths < 0] = 0
# correct distances to be compatible with obpsy traveltimes calculations:
distances = distances % 360
# set values symmetric to 180 degrees if greater than 180:
_mask = distances > 180
if _mask.any(): # does this speeds up (allocate mask array once)? FIXME: check
distances[_mask] = 360 - distances[_mask]
# set source depths to nan if out of bounds. This prevent method = 'nearest'
# to return non nan values and be consistent with 'linear' and 'cubic'
if self._unique_receiver_depth:
# get values without receiver depth dimension:
values = np.hstack((self._km2deg(source_depths).reshape(-1, 1),
distances.reshape(-1, 1)))
else:
values = np.hstack((self._km2deg(source_depths).reshape(-1, 1),
self._km2deg(receiver_depths).reshape(-1, 1),
distances.reshape(-1, 1)))
ret = griddata(self._gridpts, self._gridvals, values,
method=method, rescale=False, fill_value=np.nan)
# ret is almost likely a float, so we can set now nans for out of boun values
# we cannot do it before on any input array cause int arrays do not support nan assignement
ret[(source_depths > self._sourcedepth_bounds_km[1]) |
(receiver_depths > self._receiverdepth_bounds_km[1])] = np.nan
# return scalar if inputs are scalar, array oitherwise
return np.squeeze(ret) if allscalars else ret
```