【发布时间】:2018-01-20 01:16:14
【问题描述】:
我编写了一个函数(如下所示)来查找图像中顶部num_peaks 强度值的位置,同时执行非最大值抑制以仅选择局部最大值:
def find_peaks(img, num_peaks, threshold_fraction=0.5, nhood_size=None):
"""Find locally maximum intensities in an image"""
# calculate threshold as a fraction of intensity range in the image
threshold = (threshold_fraction * (img.max() - img.min())) + img.min()
# determine offsets in each direction that constitute a neighbourhood
if nhood_size is None:
nhood_size = np.array(img.shape) * 0.02
nhood_offset = (np.around(nhood_size / 2)).astype(int)
# create array with labelled fields to allow intensity-specific sorting
rows, cols = np.array(np.where(img >= threshold))
values = []
for i, j in zip(rows, cols):
values.append((i, j, img[i, j]))
dtype = [('row', int), ('col', int), ('intensity', np.float64)]
indices = np.array(values, dtype=dtype)
# sort in-place in descending order
indices[::-1].sort(order='intensity')
# Perform suppression
for idx_set in indices:
intensity = idx_set[2]
if not intensity:
continue
x0 = idx_set[1] - nhood_offset[1]
xend = idx_set[1] + nhood_offset[1]
y0 = idx_set[0] - nhood_offset[0]
yend = idx_set[0] + nhood_offset[0]
indices_to_suppress = np.where((indices['col'] >= x0) &
(indices['col'] <= xend) &
(indices['row'] >= y0) &
(indices['row'] <= yend))
if indices_to_suppress:
indices['intensity'][indices_to_suppress] = 0
idx_set[2] = intensity
# perform second sorting & return the remaining n (num_peaks) most
# intense values
indices[::-1].sort(order='intensity')
if len(indices) <= num_peaks:
return np.array([np.array([i, j])
for i, j in zip(indices['row'], indices['col'])])
# or return all of them
return np.array([np.array([i, j])
for i, j in zip(indices['row'][:num_peaks], indices['col'][:num_peaks])])
这似乎适用于小图像和大threshold_fraction(要抑制的值较少),但事实证明对于我的目的来说效率很低,因为我的阈值较低,例如 0.1 到 0.2。我无法用我的初学者 numpy 技能来提高效率。
我想知道是否可以对这段代码进行任何更改以提高其性能。另外,由于我使用的是 numpy 和 OpenCV,因此很高兴知道是否有一个库函数可以实现类似的功能或以某种方式利用它来编写高效的峰值查找器。
【问题讨论】:
标签: python numpy opencv image-processing