由于图像杂质,skimage 峰值局部最大值发现多个非常接近的点

kom*_*an_ 1 python image-processing scikit-image

我的图像看起来像这样,有一些较大的杂质/曝光过度的斑点。通常,它们是否被检测到并不重要,因为测量是时间解析的,因此它们稍后会被删除。

然而,我对尽可能多的小点感兴趣——尽可能快。skimage.feature.peak_local_max做得非常好,并且很容易在不同的数据上使用,因为不需要花太多时间进行强度缩放。

在此输入图像描述

但问题是,由于某种原因,大点会带来非常强烈的积极影响。

import skimage.io
import skimage.feature
import skimage.morphology
from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt


def plotRoi(spots, img_ax, color, radius):
    patches = []
    for spot in spots:
        y, x = spot
        c = plt.Circle((x, y), radius)
        patches.append(c)
    img_ax.add_collection(PatchCollection(patches, facecolors = "None", edgecolors = color, alpha = 0.3, linewidths = 1))


img = skimage.io.imread("/Path/to/img.png")
img = img[:,:,0]

fig, ax = plt.subplots()

ax.imshow(img, cmap = "Greys")
spots = skimage.feature.peak_local_max(img, min_distance = 0, exclude_border = True, num_peaks = 2000)
plotRoi(spots, ax, "red", radius = 10)

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在某些图像中搜索数千个点会导致大量局部最大值几乎彼此重叠。有没有办法避免这种情况,例如通过在图像加载上应用过滤器,因为我不想转向较慢的峰值拟合类型?

Jac*_*sen 6

问题在于,在具有完全相同值的像素区域中存在峰值。解决此问题的一种方法是将峰合并到这些区域的质心。

下面我重新创建了问题并按照所述解决了它。

import numpy as np
import matplotlib.pyplot as plt
from skimage.feature import peak_local_max
from scipy.ndimage.measurements import center_of_mass, label

# Generate test data with two peaks, one of which consists of two pixels of equal value
image = np.zeros((11,11),dtype=np.uint8)
image[5,3] = 128
image[5,2] = 255
image[5,7:9] = 255
image[6,8] = 128

# Finding peaks normally; results in three peaks
peaks = peak_local_max(image)

# Find peaks and merge equal regions; results in two peaks
is_peak = peak_local_max(image, indices=False) # outputs bool image
labels = label(is_peak)[0]
merged_peaks = center_of_mass(is_peak, labels, range(1, np.max(labels)+1))
merged_peaks = np.array(merged_peaks)

# Visualize the results
fig,(ax1,ax2)=plt.subplots(1,2)
ax1.imshow(image.T,cmap='gray')
ax1.plot(peaks[:,0],peaks[:,1],'ro')

ax2.imshow(image.T,cmap='gray')
ax2.plot(merged_peaks[:,0],merged_peaks[:,1],'ro')
Run Code Online (Sandbox Code Playgroud)

结果:

合并峰