使用导数确定二维数组中局部最大值的坐标
Determine the coordinates of local maximas in a two-dimensional array using derivative
我有一个 fits
图像,我试图在我的图像中找到 局部最大值 的坐标,但到目前为止我还不能完全让它工作。 My image 可以在这里找到。
到目前为止我所拥有的是
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
这就是我找到图像全局最大值的方法,但我想获得局部最大值的坐标,它具有的意义大于三.
我通过在网上查找发现的 this following answer 对我来说不能正常工作。
更新: 这个功能我用过
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
我想找到一种使用更好方法的方法,例如数组中的导数或分治法。我会推荐更好的解决方案。
所以我有了这个,使用 skimage 自适应阈值。希望对您有所帮助:
原创
代码
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()
输出
更改阈值参数将对找到局部最大值的位置以及找到的最大值有很大影响。
您可以使用 photutils.detection.find_peaks function, which is one of the photutils detection methods.
如果你看看
photutils.detection.find_peaks implementation, you'll see that it's using scipy.ndimage.maximum_filter 计算最大图像(默认情况下在 3x3 框大小的足迹中)并找到原始图像等于最大图像的像素。
函数的其余部分主要用于您可能也感兴趣的两件事:
- 如果你传入一个
wcs
对象,你可以得到天空坐标,而不仅仅是像素坐标。
- 有一个选项可以获取亚像素精度坐标。
我有一个 fits
图像,我试图在我的图像中找到 局部最大值 的坐标,但到目前为止我还不能完全让它工作。 My image 可以在这里找到。
到目前为止我所拥有的是
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
这就是我找到图像全局最大值的方法,但我想获得局部最大值的坐标,它具有的意义大于三.
我通过在网上查找发现的 this following answer 对我来说不能正常工作。 更新: 这个功能我用过
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
我想找到一种使用更好方法的方法,例如数组中的导数或分治法。我会推荐更好的解决方案。
所以我有了这个,使用 skimage 自适应阈值。希望对您有所帮助:
原创
代码
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()
输出
更改阈值参数将对找到局部最大值的位置以及找到的最大值有很大影响。
您可以使用 photutils.detection.find_peaks function, which is one of the photutils detection methods.
如果你看看 photutils.detection.find_peaks implementation, you'll see that it's using scipy.ndimage.maximum_filter 计算最大图像(默认情况下在 3x3 框大小的足迹中)并找到原始图像等于最大图像的像素。
函数的其余部分主要用于您可能也感兴趣的两件事:
- 如果你传入一个
wcs
对象,你可以得到天空坐标,而不仅仅是像素坐标。 - 有一个选项可以获取亚像素精度坐标。