I am trying to compute a local maxima filter on a matrix, using a circular kernel. The output should be the cells that are local maximas. For each pixel in the input 'data', I need to see if it is a local maximum by a circular window, thus returning a value of 1, otherwise 0.
I have this code, built upon answers from here: 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')
The kernel has this shape:
[[ 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.]]
So the search cells will be only the ones that have value 1. The cells with 0 should be excluded from the local maxima search.
But the script gives the error below on line 21:
RuntimeError: function parameter is not callable
Thanks for any help!
The second parameter of sc.filters.generic_filter()
should be a function, you are passing it the value returned by the local_maxima(data, np.shape(kernel))
call, ie a matrix.
I'm a bit confused as to what exactly you have done here, but I think you do not need the generic_filter
call at all, maximum_filter
should do what you want:
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')
(I do not have python installed on this computer so I have not tested this out, sorry)
Edit: I've tested it and it seems to give the correct result:
[[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]]
You can use the code below that return 1
if the cell visited is a local maximum by a circular window defined by kernel
(I just used %pylab
to plot the results as an illustration):
%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()
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()
def filter_func(a):
return a[len(a)/2] == a.max()
out = sc.generic_filter(data, filter_func, footprint=kernel)
matshow(out)
colorbar()
Below is the result with a random input data array:
data = np.random.random(size=data.shape)
matshow(data)
out = sc.generic_filter(data, filter_func, footprint=kernel)
matshow(out)
colorbar()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.