2016-09-01 6 views
1

Ich versuche, einen lokalen Maxima-Filter auf einer Matrix zu berechnen, mit einem kreisförmigen Kern. Die Ausgabe sollte die Zellen sein, die lokale Maxima sind. Für jedes Pixel in der Eingabe "Daten" muss ich sehen, ob es ein lokales Maximum durch ein kreisförmiges Fenster ist und so einen Wert von 1 zurückgibt, sonst 0.Lokale Maxima mit kreisförmigen Fenster

Ich habe diesen Code, auf Antworten von hier aufgebaut: How to apply a disc shaped mask to a numpy array?

import numpy as np 
import scipy.ndimage as sc 

radius = 2 
kernel = np.zeros((2*radius+1, 2*radius+1)) 
y,x = np.ogrid[-radius:radius+1, -radius:radius+1] 
mask2 = x**2 + y**2 <= radius**2 
kernel[mask2] = 1 

def local_maxima(matrix, window_size): 
    loc_max = sc.maximum_filter(matrix, window_size, mode='constant') 
    return loc_max 


data = np.array([(1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 4, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1)]) 

loc_max = sc.filters.generic_filter(data, local_maxima(data, np.shape(kernel)), footprint=kernel) 
max_matrix = np.where(loc_max == data, 1, 0) 
np.savetxt('.....\Local\Test_Local_Max.txt', max_matrix, delimiter='\t') 

der Kernel hat diese Form:

[[ 0. 0. 1. 0. 0.] 
[ 0. 1. 1. 1. 0.] 
[ 1. 1. 1. 1. 1.] 
[ 0. 1. 1. 1. 0.] 
[ 0. 0. 1. 0. 0.]] 

Also die Suche Zellen nur diejenigen sein, den Wert 1. die Zellen mit 0 sollten von der lokalen Maxima Suche ausgeschlossen werden.

Aber das Skript gibt den Fehler unten auf der Linie 21:

RuntimeError: function parameter is not callable 

Vielen Dank für jede Hilfe!

+0

Das Problem ist, dass die Funktion, die Sie 'sc.filters geben.generic_filter 'wird auf jedes Element des Eingabearrays angewendet, das Sie angeben:' data', was nicht möglich ist, da die Funktion local_maxima ein Array als Argument und nicht als float oder integer verwendet ... Ich weiß nicht genau, welches Ziel Sie haben Code, aber warum wenden Sie das nicht einfach an: 'loc_max = sc.maximum_filter (Daten, kernel.shape, mode = 'constant', footprint = kernel)' – bougui

+0

Da der Footprint - Kernel nur die Positionen einnehmen sollte, die in der Kernel-Matrix, nicht die mit 0 auch. – Litwos

Antwort

1

Sie können den Code unterhalb dieser Rückkehr 1 verwenden, wenn die besuchte Zelle ein lokales Maximum von einem kreisförmigen Fenster von kernel (I verwendet nur %pylab die Ergebnisse als Illustration plotten) definiert ist:

%pylab 
import scipy.ndimage as sc 
data = np.array([(1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 4, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1)]) 
matshow(data) 
colorbar() 

data

radius = 2 
kernel = np.zeros((2*radius+1, 2*radius+1)) 
y,x = np.ogrid[-radius:radius+1, -radius:radius+1] 
mask2 = x**2 + y**2 <= radius**2 
kernel[mask2] = 1 
matshow(kernel) 
colorbar() 

kernel

def filter_func(a): 
    return a[len(a)/2] == a.max() 
out = sc.generic_filter(data, filter_func, footprint=kernel) 
matshow(out) 
colorbar() 

output

Unten finden Sie das Ergebnis mit einem zufälligen Eingangsdaten-Array:

data = np.random.random(size=data.shape) 
matshow(data) 

random array

out = sc.generic_filter(data, filter_func, footprint=kernel) 
matshow(out) 
colorbar() 

output on random array

+0

Danke für die Antwort. Es ist was ich brauchte. Schöne Grundstücke! :) – Litwos

+0

Gern geschehen, und vergessen Sie nicht, eine der Antworten zu akzeptieren ... – bougui

+0

Ich weiß nicht, welche Antwort zu akzeptieren. pseudoDusts Antwort war zuerst, aber deine ist einfacher zu folgen ... – Litwos

1

Der zweite Parameter von sc.filters.generic_filter() sollte eine Funktion sein, Sie übergeben es den Wert, der von local_maxima(data, np.shape(kernel)) Aufruf zurückgegeben wird, d. H. Eine Matrix.

Ich bin ein wenig verwirrt, was genau Sie hier getan haben, aber ich glaube, Sie brauchen nicht die generic_filter Anruf überhaupt, sollte maximum_filter tun, was Sie wollen:

import numpy as np 
import scipy.ndimage as sc 

radius = 2 
kernel = np.zeros((2*radius+1, 2*radius+1)) 
y,x = np.ogrid[-radius:radius+1, -radius:radius+1] 
mask2 = x**2 + y**2 <= radius**2 
kernel[mask2] = 1 

data = np.array([(1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 4, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1), 
       (1, 1, 1, 1, 1, 1, 1, 1, 1)]) 

loc_max = sc.maximum_filter(data, footprint=kernel, mode='constant') 
max_matrix = np.where(loc_max == data, 1, 0) 
np.savetxt('.....\Local\Test_Local_Max.txt', max_matrix, delimiter='\t') 

(Ich glaube nicht, hat python auf diesem Computer installiert ist, so habe ich nicht diesen heraus getestet, sorry)

Edit: ich habe es getestet und es scheint, das richtige Ergebnis zu geben:

[[1, 1, 1, 1, 1, 1, 1, 1, 1], 
[1, 1, 1, 1, 1, 1, 1, 1, 1], 
[1, 1, 1, 1, 0, 1, 1, 1, 1], 
[1, 1, 1, 0, 0, 0, 1, 1, 1], 
[1, 1, 0, 0, 1, 0, 0, 1, 1], 
[1, 1, 1, 0, 0, 0, 1, 1, 1], 
[1, 1, 1, 1, 0, 1, 1, 1, 1], 
[1, 1, 1, 1, 1, 1, 1, 1, 1], 
[1, 1, 1, 1, 1, 1, 1, 1, 1], 
[1, 1, 1, 1, 1, 1, 1, 1, 1]] 
+0

Es läuft, aber es ist nicht das Ergebnis, das ich erwarte. Für jedes Pixel in den Eingabedaten muss ich durch ein kreisförmiges Fenster sehen, ob es sich um ein lokales Maximum handelt, und so den Wert 1 zurückgeben, sonst 0. Die Ausgabe Ihrer Antwort addiert nicht 0, wenn die Zelle ist keine lokalen Maxima. – Litwos

+0

Ich habe es jetzt getestet, scheint zu tun, was Sie wollen, ich füge das Ergebnis Ich bin auf die Antwort – pseudoDust

+0

Es funktioniert. Vielen Dank. Ich habe es erneut getestet. – Litwos