【问题标题】:Non local maxima suppression in pythonpython中的非局部最大值抑制
【发布时间】:2015-05-17 09:45:19
【问题描述】:

目标: 输入一个图像(2d numpy 数组)和一个窗口大小,并输出相同的数组,保留局部最大值,但在其他地方为 0。

我正在努力解决的问题:我认为我在代码中犯了一个愚蠢的错误,可能在我的循环中有一些拼写错误,但我不确定(局部最大值仅在左侧图像,这是不正确的)。正如我在下面提到的,我也欢迎任何使用 OpenCV 或 numpy 的简单技巧来缩短这个解决方案。

类似问题:Finding Local Maxima in an Image

Find local maxima in grayscale image using OpenCV

我的不同,因为:我希望压制除局部最大值之外的所有值。我不必在下面使用我的代码,我无法找到 opencv 或 numpy 的内置函数来做我需要做的事情(cv 中的哈里斯角将隐含地将此作为步骤之一,但我需要一些东西来执行我需要的唯一操作)。我读了一些关于扩张的文章,但不确定这在这里是否也有用。

到目前为止我已经尝试过。

def nonMaximalSupress(image,NHoodSize):
    #For
    for x in range(0,image.shape[0]-1):

        if x+NHoodSize[0]<image.shape[0]:
            #while we can still take a square
            #print "AHH ", image.shape
            startWindow=0
            for y in range(startWindow,image.shape[1]-NHoodSize[1]):
                #try:
                if np.sum(image[x:x+NHoodSize[0]][y:y+NHoodSize[1]])==0:
                    localMax=0
                else:
                    localMax = np.amax(image[x:x+NHoodSize[0]][y:y+NHoodSize[1]])
                #except ValueError:
                    #localMax=0
                #print "local max is ", localMax

                maxCoord=np.unravel_index(np.argmax((image[x:x+NHoodSize[0],y:y+NHoodSize[1]])),
                                          image.shape)+np.array((x,y))

                #print "X is %r, Y is %r, max coord is %r \n y+nhood is %r" %(x,y,maxCoord,y+NHoodSize[1])
                #suppress everything
                image[x:x+NHoodSize[0]][y:y+NHoodSize[1]]=0

                #reset only the max
                #print maxCoord
                if localMax > 0:
                    print localMax
                    print "max coord is ", maxCoord[0], maxCoord[1]
                image[maxCoord[0]][maxCoord[1]]=localMax
                #increment y



        x+=NHoodSize[0]

    return image

【问题讨论】:

  • 是找到局部最大值的问题,还是将其他值设置为 0 的问题?
  • 在小型数组上测试类似image[x:x+NHoodSize[0]][y:y+NHoodSize[1]]=0 的语句。

标签: python opencv numpy computer-vision


【解决方案1】:

这样的事情怎么样:

# Use the max filter to make a mask
roi = 3
size = 2 * roi + 1
image_max = ndimage.maximum_filter(image, size=size, mode='constant')
mask = (image == image_max)
image *= mask

# Remove the image borders
image[:roi] = 0
image[-roi:] = 0
image[:, :roi] = 0
image[:, -roi:] = 0

# Optionally find peaks above some threshold
image_t = (image > peak_threshold) * 1

# get coordinates of peaks
f = np.transpose(image_t.nonzero())

【讨论】:

    【解决方案2】:

    这可能不完全正确,但在小型测试用例上效果更好

    def nonMaximalSupress1(image,NHoodSize):
        #
        dX, dY = NHoodSize
        M, N = image.shape
        for x in range(0,M-dX+1):
            for y in range(0,N-dY+1):
                window = image[x:x+dX, y:y+dY]
                if np.sum(window)==0:
                    localMax=0
                else:
                    localMax = np.amax(window)
                maxCoord=np.unravel_index(np.argmax(window), window.shape) + np.array((x,y))
                #suppress everything
                image[x:x+dX, y:y+dY]=0
                #reset only the max
                if localMax > 0:
                    print localMax
                    print "max coord is ", maxCoord
                image[tuple(maxCoord)] = localMax
        return image
    

    我使用局部变量使事情更易于阅读,并调整了循环范围。但最大的变化在于我索引image 的方式。特别是在使用切片进行索引时,必须使用一组括号。

    image[x:x+dX, y:y+dY] 是选择窗口的正确方法,而不是image[x:x+dX][y:y+dY]

    可以通过修改window来稍微清理一下。由于它是view,因此更改它会更改image

    def nonMaximalSupress2(image,NHoodSize):
        #
        dX, dY = NHoodSize
        M, N = image.shape
        for x in range(0,M-dX+1):
            for y in range(0,N-dY+1):
                window = image[x:x+dX, y:y+dY]
                if np.sum(window)==0:
                    localMax=0
                else:
                    localMax = np.amax(window)
                maxCoord = np.argmax(window)
                # zero all but the localMax in the window
                window[:] = 0
                window.flat[maxCoord] = localMax
        return image
    

    【讨论】:

      【解决方案3】:

      如果一个峰可能由具有相同像素强度的多个像素组成,则使用skimage.feature.peak 中的skimage.feature.peakscipy.ndimage.measurements 中的center_of_mass 来定位峰中心的不同方法:

      from skimage.feature.peak import peak_local_max
      from scipy.ndimage.measurements import center_of_mass
      from scipy.ndimage import label
      from scipy.ndimage.morphology import generate_binary_structure
      
      footprint = generate_binary_structure(3, 3)
      peaks = peak_local_max(img, indices=False, footprint=footprint)
      lbl, num_features = label(maxima)
      centers = center_of_mass(maxima, lbl, range(1, num_features + 1))
      values = img[tuple(np.int0(np.transpose(centers)))]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-19
        • 2017-08-10
        • 2014-07-22
        • 2020-10-25
        • 1970-01-01
        相关资源
        最近更新 更多