2

我最近一直在研究角膜内皮细胞的分割过程,我发现了一篇相当不错的论文,描述了执行该分割过程并取得了不错的结果。我一直在尝试遵循那篇论文并使用 scikit-image 和 openCV 来实现它,但我被困在了分水岭分割上。

我将简要描述该过程应该如何:

首先,你有原始的内皮细胞图像 原始图像

然后,他们指示您执行形态灰度重建,以便稍微调整图像的灰度(但是,他们没有解释如何获取灰度的标记,所以我一直在鬼混并试图自己买一些)

这就是重建的图像应该看起来的样子: 期望的重建

这就是我重建的图像(让我们将其标记为r)的样子: 我的重建

目的是使用重建的图像来获得分水岭分割的标记,我们该怎么做?!我们得到原始图像(让我们将其标记为f ),并在 ( f - r )中执行阈值以提取单元格的 h 圆顶,即我们的标记。

这是 hdomes 图像应该看起来的样子: 所需的 hdomes

这是我的 hdomes 图像的样子: 我的 hdomes

我相信我得到的 hdome 和他们的一样好,所以,最后一步是最终对原始图像进行分水岭分割,使用我们一直在努力获得的 hdome!

作为输入图像,我们将使用反转的原始图像,作为标记,我们的标记。

这是被删除的输出:

期望的输出

但是,我只得到一个黑色图像,每个像素都是黑色的,我不知道发生了什么......我也尝试使用他们的标记和倒置图像,但是,也得到黑色图像。我一直在使用的论文是Luc M. Vincent、Barry R. Masters,“角膜内皮细胞图像的形态图像处理和网络分析”,Proc。间谍 1769

我为长文本道歉,但是我真的很想详细解释到目前为止我的理解的一切,顺便说一句,我已经尝试从 scikit-image 和 opencv 进行分水岭分割,两者都给了我黑色图像。

这是我一直在使用的以下代码

img = cv2.imread('input.png',0)
mask = img


marker = cv2.erode(mask, cv2.getStructuringElement(cv2.MORPH_ERODE,(3,3)), iterations = 3)
reconstructedImage = reconstruction(marker, mask)


hdomes = img - reconstructedImage
cell_markers = cv2.threshold(hdomes, 0, 255, cv2.THRESH_BINARY)[1]


inverted = (255 - img)
labels = watershed(inverted, cell_markers)

cv2.imwrite('test.png', labels)


plt.figure()
plt.imshow(labels)
plt.show()

谢谢!

4

1 回答 1

2

这是使用 scikit-image 对图像进行分水岭分割的粗略示例。

您的脚本中缺少的是计算欧几里得距离(参见此处此处)并从中提取局部最大值。

请注意,分水岭算法输出一个分段常数图像,其中相同区域中的像素被分配相同的值。您的“所需输出”面板 (e) 中显示的是区域之间的边缘。

import numpy as np
import cv2
import matplotlib.pyplot as plt
from skimage.morphology import watershed
from scipy import ndimage as ndi
from skimage.feature import peak_local_max
from skimage.filters import  threshold_local

img = cv2.imread('input.jpg',0)

'''Adaptive thersholding 
   calculates thresholds in regions of size block_size surrounding each pixel
   to handle the non-uniform background'''
block_size = 41
adaptive_thresh = threshold_local(img, block_size)#, offset=10)
binary_adaptive = img > adaptive_thresh

# Calculate Euclidean distance
distance = ndi.distance_transform_edt(binary_adaptive)

# Find local maxima of the distance map 
local_maxi = peak_local_max(distance, labels=binary_adaptive, footprint=np.ones((3, 3)), indices=False)
# Label the maxima
markers = ndi.label(local_maxi)[0]

''' Watershed algorithm
    The option watershed_line=True leave a one-pixel wide line 
    with label 0 separating the regions obtained by the watershed algorithm '''
labels = watershed(-distance, markers, watershed_line=True)

# Plot the result
plt.imshow(img, cmap='gray')
plt.imshow(labels==0,alpha=.3, cmap='Reds')
plt.show()
于 2017-12-02T04:16:10.173 回答