def elastictransform(sigma, alpha, randomstate=None, invert=False, padding=0, ignorechannels=True):
# rng is going to end up in _elastictransform's closure, which should guarantee persistence over function calls
if isinstance(randomstate, int):
rng = np.random.RandomState(randomstate)
elif isinstance(randomstate, np.random.RandomState):
rng = randomstate
else:
rng = np.random.RandomState(None)
# Define function on image
def _elastictransform(image):
assert image.ndim == 2, "Can only transform 2D images."
# Pad image if required
if not invert and padding > 0:
# Pad
image = np.pad(image, padding, mode='reflect')
# Take measurements
imshape = image.shape
# Make random fields
dx = rng.uniform(-1, 1, imshape) * alpha
dy = rng.uniform(-1, 1, imshape) * alpha
if __debug__ and False:
print("RNG Debug on _elastictransform: ")
print("Invert: {}, dx[0, 0]: {}".format(invert, dx[0, 0]))
print("Invert: {}, dy[0, 0]: {}".format(invert, dy[0, 0]))
# Smooth dx and dy
sdx = gaussian_filter(dx, sigma=sigma, mode='reflect')
sdy = gaussian_filter(dy, sigma=sigma, mode='reflect')
# Make meshgrid
x, y = np.meshgrid(np.arange(imshape[1]), np.arange(imshape[0]))
# Distort meshgrid indices (invert if required)
if not invert:
distinds = (y + sdy).reshape(-1, 1), (x + sdx).reshape(-1, 1)
else:
distinds = (y - sdy).reshape(-1, 1), (x - sdx).reshape(-1, 1)
# Map cooordinates from image to distorted index set
transformedimage = map_coordinates(image, distinds, mode='reflect').reshape(imshape)
# Crop image if required
if invert and padding > 0:
transformedimage= transformedimage[padding:-padding, padding:-padding]
return transformedimage
# Convert image function to batch function and return
return image2batchfunc(_elastictransform, ignorechannels=ignorechannels)
#: Function for random rotations of the image
python类map_coordinates()的实例源码
def elastictransform(sigma, alpha, randomstate=None, invert=False, padding=0, interpolation=3, ignorechannels=True):
# rng is going to end up in _elastictransform's closure, which should guarantee persistence over function calls
if isinstance(randomstate, int):
rng = np.random.RandomState(randomstate)
elif isinstance(randomstate, np.random.RandomState):
rng = randomstate
else:
rng = np.random.RandomState(None)
# Define function on image
def _elastictransform(image):
# Pad image if required
if not invert and padding > 0:
# Pad
image = np.pad(image, padding, mode='reflect')
# Take measurements
imshape = image.shape
# Make random fields
dx = rng.uniform(-1, 1, imshape) * alpha
dy = rng.uniform(-1, 1, imshape) * alpha
# Smooth dx and dy
sdx = gaussian_filter(dx, sigma=sigma, mode='reflect')
sdy = gaussian_filter(dy, sigma=sigma, mode='reflect')
# Make meshgrid
x, y = np.meshgrid(np.arange(imshape[1]), np.arange(imshape[0]))
# Distort meshgrid indices (invert if required)
if not invert:
distinds = (y + sdy).reshape(-1, 1), (x + sdx).reshape(-1, 1)
else:
distinds = (y - sdy).reshape(-1, 1), (x - sdx).reshape(-1, 1)
# Map cooordinates from image to distorted index set
transformedimage = map_coordinates(image, distinds, mode='reflect', order=interpolation).reshape(imshape)
# Crop image if required
if invert and padding > 0:
transformedimage= transformedimage[padding:-padding, padding:-padding]
return transformedimage
# Convert image function to batch function and return
return image2batchfunc(_elastictransform, ignorechannels=ignorechannels)
#: Function for random rotations of the image
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
def convertToLogPolar(img, centerTrans, angleStep, logBase, mode = "nearest"):
if mode == "nearest":
# Step 1 - Initialize transformed image
transformedImage = np.zeros(img.shape, dtype = img.dtype)
# Step 2 - Apply reverse log polar transformation
for radius in range(img.shape[COLS_AXIS]): # start with radius, because calculating exponential power is time consuming
actRadius = logBase ** radius
for angle in range(img.shape[ROWS_AXIS]):
anglePi = angle * angleStep
# calculate euclidian coordinates (source: https://en.wikipedia.org/wiki/Log-polar_coordinates)
row = int(centerTrans[ROWS_AXIS] + actRadius * math.sin(anglePi))
col = int(centerTrans[COLS_AXIS] + actRadius * math.cos(anglePi))
# copy pixel from the location to log polar image
if 0 <= row < img.shape[ROWS_AXIS] and 0 <= col < img.shape[COLS_AXIS]:
transformedImage[angle, radius] = img[row, col]
return transformedImage
else:
print("Base: " + str(logBase))
# create matrix with angles
anglesMap = np.zeros(img.shape, dtype=np.float64)
# each column has 0 in its first row and -pi in its last row
anglesVector = -np.linspace(0, np.pi, img.shape[0], endpoint=False)
# initialize it by columns using the same vector
anglesMap.T[:] = anglesVector
# create matrix with radii
radiusMap = np.zeros(img.shape, dtype=np.float64)
# each line contains a vector with numbers from in (0, cols) to power logBase
radiusVector = np.power(logBase, np.arange(img.shape[1], dtype=np.float64)) - 1.0
# initialize it by rows using the same vector
radiusMap[:] = radiusVector
# calculate x coordinates (source: https://en.wikipedia.org/wiki/Log-polar_coordinates)
x = radiusMap * np.sin(anglesMap) + centerTrans[1]
# calculate y coordinates (source: https://en.wikipedia.org/wiki/Log-polar_coordinates)
y = radiusMap * np.cos(anglesMap) + centerTrans[0]
# initialize final image
outputImg = np.zeros(img.shape)
# use spline interpolation to map pixels from original image to calculated coordinates
ndii.map_coordinates(img, [x, y], output=outputImg)
return outputImg
# computes phase correlation and returns position of pixel with highest value (row, column)