Как заставить ndimage.filters.maximum_filter работать как функция imregionalmax в MATLAB? - PullRequest
1 голос
/ 14 мая 2019

Прочитав этот пост и поиграв также с SciKit-изображением, я обнаружил разницу в Python по сравнению с функцией MATLAB imregionalmax.

У меня есть эти строки кода:

from skimage.feature import peak_local_max

manos = np.ones([5,5])
manos[2,2] = 0.
manos[2,4] = 2.

giannis = peak_local_max(manos,min_distance=1, indices=False, exclude_border=False)

giorgos = ndimage.filters.maximum_filter(manos, footprint=np.ones([3,3]))
giorgos = (giorgos == manos)

Я бы ожидал двумерный массив только с одним значением True ([2,4]) для переменных giannis или giorgos, как я получаю в MATLAB. Вместо этого я беру больше одного максимума.

Есть идеи, почему это работает и как заставить работать так же, как в MATLAB?

1 Ответ

2 голосов
/ 14 мая 2019

И giannis, и giorgos похожи в том, что они находят пиксели, которые равны или больше других пикселей в окрестности 3х3.Я полагаю, что giannis будет иметь дополнительное пороговое значение.

Ни один из этих методов не гарантирует, что найденные пиксели на самом деле являются локальными максимумами.Обратите внимание, где я сказал «больше или равно» выше.Любое плато на вашем изображении (область, где все пиксели имеют одинаковое значение), достаточно большое, будет помечено алгоритмом, независимо от того, являются ли они локальными максимумами, локальными минимумами или где-то между ними.

Например:

import numpy as np
import matplotlib.pyplot as pp
import scipy.ndimage as ndimage

manos = np.sin(np.arange(100)/10)
manos = np.round(30*manos)/30     # Rounding to create plateaus

giorgos = ndimage.filters.maximum_filter(manos, footprint=np.ones([3]))
giorgos = (giorgos == manos)

pp.plot(manos);
pp.plot(giorgos);
pp.show()

A 1D

Обратите внимание, как фильтр определил три точки вблизи локального минимума синусоиды.Средний из них является фактическим локальным минимумом, остальные два являются плато, которые не являются ни локальными максимумами, ни минимумами.

В отличие от этого, функция MATLAB imregionalmax идентифицирует все плато, которые окружены пикселями с более низкимзначение.Алгоритм, необходимый для этого, сильно отличается от приведенного выше.Это может быть эффективно выполнено с использованием алгоритма Union-Find, или менее эффективно с использованием алгоритма типа заливки.Основная идея состоит в том, чтобы найти пиксель, который не ниже любого соседа, а затем расширить его до его равнозначных соседей, пока не будет исследовано все плато или пока вы не найдете один из пикселей на плато с более высоким соседом..

Единственная известная мне реализация этого алгоритма Одна реализация в Python находится в PyDIP (примечание: я автор; также обратите внимание: вы не можетевсе же установите это через pip, вам нужно скомпилировать из исходников):

import PyDIP as dip

nikos = dip.Maxima(manos)

pp.plot(manos);
pp.plot(nikos);
pp.show()

Same 1D image with correctly identified local maxima

Другая реализация в SciKit-Image (Спасибо Хуану за , указавшим на это ):

nikos = skimage.morphology.local_maxima(manos)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...