Пик скиджа local max находит множество пятен в непосредственной близости из-за загрязнения изображения

1

У меня есть изображение, похожее на это, с некоторыми более крупными примесями/переэкспонированными пятнами. Как правило, не имеет значения, обнаружены ли они, поскольку измерения разрешены по времени, поэтому они будут удалены позже.

Тем не менее, меня интересуют как можно больше мелких точек - как можно быстрее. skimage.feature.peak_local_max делает действительно хорошую работу и очень прост в использовании на разных данных, потому что нет необходимости много играть с масштабированием интенсивности.

Изображение 174551

Проблема в том, что большие пятна почему-то дают очень сильные положительные результаты.

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()

Изображение 174551

И поиск тысяч пятен на некоторых изображениях приводит к большому количеству локальных максимумов, которые в значительной степени находятся на вершине друг друга. Есть ли способ избежать этого, например, путем применения фильтра при загрузке изображения, поскольку я бы предпочел не переходить к более медленному типу установки пика?

Теги:
image-processing
scikit-image

1 ответ

1
Лучший ответ

Проблема в том, что в областях пикселей с одинаковым значением есть пики. Один из способов решить это - объединить пики в центр масс этих регионов.

Ниже я воссоздаю проблему и решая ее, как указано.

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')

Результат:

Изображение 174551

  • 0
    Умное решение, но это нужно делать вручную? Это кажется немного неэффективным.
  • 0
    В этом нет ничего ручного. Я просто отредактировал код, чтобы прояснить это.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню