I've looked at these two algorithms, and the biggest difference seems to be in the output. `is_local_maximum` returns a Boolean array, while `peak_local_max` returns the indices of points corresponding to maxima (a la `np.sort` vs. `np.argsort`, though you cannot just pass the output of `peak_local_max` as indices).
The other differences are more subtle, but significant.
The API for `peak_local_max` could use some cleanup - the first threshold kwarg is set to 'deprecated'(!) and IMHO should be removed - but this algorithm allows finer control over thresholding and peak searching. This would be good to avoid finding phantom peaks in noise if large dark regions were present. One significant drawback of this algorithm is the min_distance kwarg is set by default to 10, rather arbitrary, and ANY input (even the minimum value of 1) excludes both neighboring pixels AND the border. See example below.
In contrast, `is_local_maximum` has a much simpler API. It doesn't have the finer thresholding / peak searching controls, but has a unique ability to search for peaks ONLY within arbitrary, connected, labeled regions. This has some interesting potentials for masking etc, though I believe within each label only one peak will be found. This algorithm also has the ability to search arbitrary local regions for peaks using something akin to a morphological structuring element, through the `footprint=` kwarg. The documentation for this could probably be clarified.
The way `peak_local_max` excludes borders concerns me for general use, as does its default `min_distance=10`, and personally I would prefer to wok around the limitations in `is_local_maximum`.
A best-of-both-worlds combination could probably be created without overly much effort...
Snippet showing border-excluding behavior of `peak_local_max`, which will only get worse with higher values of `min_distance`:
import numpy as np
import matplotlib.pyplot as plt
from skimage.feature import peak_local_max
from skimage.morphology import is_local_maximum
# Generate standardized random data
np.random.seed(seed=1234)
testim = np.random.randint(0, 255, size=(20, 20))
# Find peaks using both methods
ismax = is_local_maximum(testim) # Boolean image returned
peakmax = peak_local_max(testim, min_distance=1) # (M, 2) indices returned
# `peakmax` not plottable - placing values in 2d array
Ipeakmax = np.zeros(testim.shape)
Ipeakmax[peakmax[:, 0], peakmax[:, 1]] = 1
# Show the results
fig, ax = plt.subplots(ncols=2, nrows=1)
ax[0].imshow(ismax, cmap='gray')
ax[0].set_title('Peaks found by `is_local_maximum`')
ax[1].imshow(Ipeakmax, cmap='gray')
ax[1].set_title('Peaks found by `peak_local_max`')
plt.show()