Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用numpy进行非最大值抑制的二维峰值查找_Python_Numpy_Opencv_Image Processing - Fatal编程技术网

Python 使用numpy进行非最大值抑制的二维峰值查找

Python 使用numpy进行非最大值抑制的二维峰值查找,python,numpy,opencv,image-processing,Python,Numpy,Opencv,Image Processing,我编写了一个函数,用于查找图像中顶部num_峰值强度值的位置,同时执行非最大值抑制以仅选择局部最大值: 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 imag

我编写了一个函数,用于查找图像中顶部num_峰值强度值的位置,同时执行非最大值抑制以仅选择局部最大值:

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])])
这似乎适用于较小的图像和较大的阈值,但事实证明,对于我的目的来说,这是非常低效的,因为我有较低的阈值,如0.1到0.2。我还没有能够使我的初学者numpy技能更有效


我想知道是否可以对这段代码进行任何更改,以提高其性能。另外,由于我使用的是numpy和OpenCV,如果有一个库函数可以实现类似的功能,或者以某种方式利用它来编写一个高效的峰值查找器,那就很好了。

值得一提的是,既然您已经在使用numpy,那么在pip install scikit image中安装skimage的额外使用应该是轻而易举的事。然后,您可以使用skimage.feature.peak_local_max或skimage.ndimage.maximum_过滤器创建感兴趣位置的地图,由于对象本机被视为numpy数组,您可以通过从原始数组中减去结果数组的一部分来抑制这些区域。

您的算法依赖于对图像值进行排序,因此其时间复杂度取决于图像像素数N中的logn,并且需要额外的内存缓冲区来存储排序后的值

标准的局部极大值检测器依赖于使用一个小的结构元素来扩展图像,该结构元素的大小取决于图像的噪声或峰值,然后找到原始图像和扩展图像具有相等值的像素。这是及时开启的,需要额外的开启缓冲区。非局部极大值像素的抑制是自动的,并且通过对发现的局部极大值进行排序(其数量通常为