7

I am trying to find some relative maximums of a given image. I understand that there are two possible methods, the first is using scipy.ndimage.maximum_filter() and the second using skimage.feature.peak_local_max().

In order to compare both methods I have modified an example from skimage shown here in order to compare the peaks found.

from scipy import ndimage as ndi
import matplotlib.pyplot as plt
from skimage.feature import peak_local_max
from skimage import data, img_as_float

im = img_as_float(data.coins())

# use ndimage to find the coordinates of maximum peaks
image_max = ndi.maximum_filter(im, size=20) == im

j, i = np.where(image_max)
coordinates_2 = np.array(zip(i,j))

# use skimage to find the coordinates of local maxima
coordinates = peak_local_max(im, min_distance=20)

# display results
fig, axes = plt.subplots(1, 2, figsize=(8, 3), sharex=True, sharey=True)
ax = axes.ravel()

ax[0].imshow(im, cmap=plt.cm.gray)
ax[0].plot(coordinates_2[:, 0], coordinates_2[:, 1], 'r.')
ax[0].axis('off')
ax[0].set_title('Maximum filter')

ax[1].imshow(im, cmap=plt.cm.gray)
ax[1].autoscale(False)
ax[1].plot(coordinates[:, 1], coordinates[:, 0], 'r.')
ax[1].axis('off')
ax[1].set_title('Peak local max')

fig.tight_layout()

plt.show()

This gives the next peaks for each method: image

I understand that the parameter size for maximum_filter is not equivalent to the min_distance from peak_local_max, but I'd like to know if there is a method in which both give the same result. Is that possible?

Some related question on stackoverflow are:

Get coordinates of local maxima in 2D array above certain value

Peak detection in a 2D array

funie200
  • 3,688
  • 5
  • 21
  • 34
Jose M Gonzalez
  • 349
  • 3
  • 16

1 Answers1

4

have you been able to come up with a solution?

I think one step into the direction is simply setting size=41 in the maximum filter. This gives me rather similar, though not identical results. The idea behind that is that peak_local_max looks for peaks in a region specified by 2 * min_distance + 1 (Source: Documentation).

Most of the additional peaks identified by ndi.maximum_filter are close to the boundary, but there also two additional peaks in the middle of the picture (additional peaks are marked in blue).

Peaks

At assume that peak_local_max employs some logic to strip boundary peaks and peaks that are close to other peak. Most likely based on the value of the peak.

CJS
  • 68
  • 7
  • 1
    You are right! I messed it with the fact that maximum filter uses a square area while peak_loca_max just uses the radius. The other part is that I see on the documentation that you have shared that `peak_local_max` has a parameter called `exclude_border`. By default it is equal to `min_distance` and this removes boundary points. If you edit this i'll accept the answer as the solution. Thanks again – Jose M Gonzalez Jan 19 '21 at 14:38