Obtenga coordenadas de máximos locales en una matriz 2D por encima de cierto valor

from PIL import Image import numpy as np from scipy.ndimage.filters import maximum_filter import pylab # the picture (256 * 256 pixels) contains bright spots of which I wanna get positions # problem: data has high background around value 900 - 1000 im = Image.open('slice0000.png') data = np.array(im) # as far as I understand, data == maximum_filter gives True-value for pixels # being the brightest in their neighborhood (here 10 * 10 pixels) maxima = (data == maximum_filter(data,10)) # How can I get only maxima, outstanding the background a certain value, let's say 500 ? 

Me temo que no entiendo realmente la función scipy.ndimage.filters.maximum_filter() . ¿Hay una manera de obtener coordenadas de píxeles solo dentro de los puntos y no dentro del fondo?

http://sofes.miximages.com/python/RImHW.png (imagen en escala de grises de 16 bits, 256 * 256 píxeles)

 import numpy as np import scipy import scipy.ndimage as ndimage import scipy.ndimage.filters as filters import matplotlib.pyplot as plt fname = '/tmp/slice0000.png' neighborhood_size = 5 threshold = 1500 data = scipy.misc.imread(fname) data_max = filters.maximum_filter(data, neighborhood_size) maxima = (data == data_max) data_min = filters.minimum_filter(data, neighborhood_size) diff = ((data_max - data_min) > threshold) maxima[diff == 0] = 0 labeled, num_objects = ndimage.label(maxima) slices = ndimage.find_objects(labeled) x, y = [], [] for dy,dx in slices: x_center = (dx.start + dx.stop - 1)/2 x.append(x_center) y_center = (dy.start + dy.stop - 1)/2 y.append(y_center) plt.imshow(data) plt.savefig('/tmp/data.png', bbox_inches = 'tight') plt.autoscale(False) plt.plot(x,y, 'ro') plt.savefig('/tmp/result.png', bbox_inches = 'tight') 

Datos dados.png :

introduzca la descripción de la imagen aquí

el progtwig anterior produce result.png con threshold = 1500 . Baje el threshold para recoger más máximos locales:

introduzca la descripción de la imagen aquí

Referencias :

  • JF Sebastian cuenta los núcleos.
  • Joe Kington encuentra huellas de pata
  • Ivan encuentra máximos locales
 import numpy as np import scipy import scipy.ndimage as ndimage import scipy.ndimage.filters as filters import matplotlib.pyplot as plt fname = '/tmp/slice0000.png' neighborhood_size = 5 threshold = 1500 data = scipy.misc.imread(fname) data_max = filters.maximum_filter(data, neighborhood_size) maxima = (data == data_max) data_min = filters.minimum_filter(data, neighborhood_size) diff = ((data_max - data_min) > threshold) maxima[diff == 0] = 0 labeled, num_objects = ndimage.label(maxima) xy = np.array(ndimage.center_of_mass(data, labeled, range(1, num_objects+1))) plt.imshow(data) plt.savefig('/tmp/data.png', bbox_inches = 'tight') plt.autoscale(False) plt.plot(xy[:, 1], xy[:, 0], 'ro') plt.savefig('/tmp/result.png', bbox_inches = 'tight') 

La entrada anterior fue muy útil para mí, pero el bucle for ralentizó mi aplicación. Descubrí que ndimage.center_of_mass () hace un trabajo excelente y rápido para obtener las coordenadas … de ahí esta sugerencia.

Esto ahora se puede hacer con skimage.

 from skimage.feature import peak_local_max xy = peak_local_max(data, min_distance=2,threshold_abs=1500) 

En mi computadora, para un tamaño de imagen VGA, se ejecuta 4 veces más rápido que la solución anterior y también devolvió una posición más precisa en ciertos casos.