Reputation: 4318
I have a fits
image and I am trying to find the coordinates of local maxima in my image but so far I couldn't quite make it work. My image can be find here.
What I have so far is
import numpy as np
import scipy.nimage as ndimage
from astropy.wcs import WCS
from astropy import units as u
from astropy import coordinates as coord
from astropy.io import fits
import scipy.ndimage.filters as filters
from scipy.ndimage.filters import maximum_filter
hdulist=fits.open("MapSNR.fits")
#reading a two dimensional array from fits file
d=hdulist[0].data
w=WCS("MapSNR.fits")
idx,idy=np.where(d==np.max(d))
rr,dd=w.all_pix2word(idx,idy,o)
c=coord.SkyCoord(ra=rr*u.degree, dec=dd*u.degree)
#The sky coordinate of the image maximum
print c.ra
print c.dec
That is how I can find the global maximum of the image, but I would like to obtain the coordinates of the local maximas which have the significance of being greater than three.
What I have found by looking up in the web was this following answer which doesn't work properly in my case. update: I have used this function
def detect_peaks(data, threshold=1.5, neighborhood_size=5):
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 # sets values <= threshold as background
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
y_center = (dy.start + dy.stop - 1)/2
x.append(x_center)
y.append(y_center)
return x,y
I would like to find a method using a better approach like the derivative in the array or divide and conquer method. I will appropriate for a better recommended solution.
Upvotes: 1
Views: 1177
Reputation: 2940
You could use the photutils.detection.find_peaks function, which is one of the photutils detection methods.
If you look at the photutils.detection.find_peaks implementation, you'll see that it's using scipy.ndimage.maximum_filter to compute a maximum image (by default in a 3x3 box size footprint) and finding the pixels where the original image equals the maximum image.
The rest of the function is mostly for two things that might also be of interest to you:
wcs
object, you can get sky coordinates out, not just pixel coordinates.Upvotes: 3
Reputation: 3221
So I have this, using skimage adaptive threshold. Hope it helps:
Code
from skimage.filters import threshold_adaptive
import matplotlib.pyplot as plt
from scipy import misc, ndimage
import numpy as np
im = misc.imread('\Desktop\MapSNR.jpg')
# Apply a threshold
binary_adaptive = threshold_adaptive(im, block_size=40, offset=-20).astype(np.int)
# Label regions and find center of mass
lbl = ndimage.label(binary_adaptive)
points = ndimage.measurements.center_of_mass(binary_adaptive, lbl[0], [i+1 for i in range(lbl[1])])
for i in points:
p = [int(j) for j in i]
binary_adaptive[i] += 5
plt.figure()
plt.imshow(im, interpolation='nearest', cmap='gray')
plt.show()
plt.figure()
plt.imshow(binary_adaptive, interpolation='nearest', cmap='gray')
plt.show()
Output
Changing the parameters of the threshold will have a large effect on where the local maxima will be found, and how many maxima are found.
Upvotes: 4