我编写了一个函数(如下所示)来查找图像中顶部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,很高兴知道是否有一个库函数可以实现相似的功能或以某种方式利用它来编写高效的峰值查找器。 最佳答案 您的算法依赖于对图像值进行排序,因此其时间复杂度为图像像素数N中的O(N log N),并且需要额外的O(N)内存缓冲区来存储排序后的值。标准的局部最大值检测器依赖于使用小的结构元素对图像进行放大(其大小取决于图像的“噪点”或“峰值”程度),然后找到原始图像和经过放大的像素所在的像素具有相等的值。时间为O(N),需要额外的O(N)缓冲区。非局部最大值像素的抑制是自动的,并且可以通过按图像强度对找到的局部最大值(其数量通常为因此,对于足够大的图像,后一种算法在理论上性能更高,并且实际上也可能性能更高。当然,YMMV取决于实现方式和图像大小。关于python - 使用numpy进行非最大抑制的2D峰发现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48099343/
10-13 00:04