# Source code for ncempy.algo.local_max

"""
Module to find local maxima in an image.
"""

import numpy as np
import scipy.ndimage.filters

[docs]def local_max(img, r, thresh):
"""Find local maxima from comparing dilated and eroded images.

Calculates images with maximum and minimum within given radius. If the difference is larger than the threshold, the
original pixel position with max value is detected as local maximum.

Parameters
----------
img : np.ndarray
Input image.
r : int
thresh : int or float
Intensity difference threshold.

Returns
-------
: np.ndarray
Array of points.

"""

try:
r = int(r)
thresh = int(thresh)
assert(isinstance(img, np.ndarray))
except:

# prepare circular kernel
y, x = np.ogrid[-r:r+1, -r:r+1]
kernel = x**2 + y**2 <= r**2

# calculate max and min images
img_dil = scipy.ndimage.filters.maximum_filter(img, footprint=kernel)
img_ero = scipy.ndimage.filters.minimum_filter(img, footprint=kernel)

# get selection of local maxima
sel = (img == img_dil)*(img-img_ero > thresh)

if sel.any():
# retrieve and return points
points = np.argwhere(sel)

return points
else:
# otherwise return None to avoid having an empty list
return None

[docs]def points_todim(points, dims):
"""Convert points from px coordinates to real dim.

Points are expected to be array indices for the first two dimensions in dims.

Parameters
----------
points : np.ndarray
Points to convert.
dims : tuple
Tuple of dimensions.

Returns
-------
: np.ndarray
Converted points.

"""

try:
# try to convert input to np.ndarray with 2 columns (necessary if only one entry provided)
points = np.reshape(np.array(points), (-1,2))
# check if enough dims available
assert(len(dims) >= 2)
assert(len(dims) == 3)
except:
raise TypeError('Something wrong with the input!')

# do the conversion by looking up thing in dimension vectors
points_d = np.array([dims[points[:, 0]], dims[points[:, 1]]]).transpose()

return points_d