2

我正在尝试分析灰度 TIFF 堆栈,其中给定的帧看起来像这样。我对其进行过滤(使用高斯模糊),然后对其进行二值化(使用 Otsu 的阈值方法)。

MATLAB 代码,效果很好:

image_conncomp = bwconncomp(image_binary); # entire stack is held in image_binary

for i=1:image_conncomp.NumObjects
    object_size = length(image_conncomp.PixelIdxList{i});
end

示例图像中的每个白点都被拾取,其体积(以像素为单位)非常准确地由 给出object_size

Python代码:

from skimage import measure

labels = measure.label(image_binary, background=1) # same image_binary as above
propsa = measure.regionprops(labels)

for label in propsa:
    object_size = len(label.coords)

Python 代码似乎工作得很好……除了大多数检测到的对象将有object_size1 - 200 个,然后几个将有几千个像素的大小。

这些功能有什么不同?我很乐意在 Python 中尝试另一种方法来计算对象大小,但我很难找到另一种方法。如果我能找到一个很好的 Matlabbwconncomp函数替代品,那么拥有这段代码的 Python 版本会很棒。

在此处输入图像描述

4

2 回答 2

4

像这样的东西?

from skimage.io import imread, imshow
from skimage.filters import gaussian, threshold_otsu
from skimage import measure
import matplotlib.pyplot as plt

original = imread('https://i.stack.imgur.com/nkQpj.png')
blurred = gaussian(original, sigma=.8)
binary = blurred > threshold_otsu(blurred)
labels = measure.label(binary)

plots = {'Original': original, 'Blurred': blurred, 
         'Binary': binary, 'Labels': labels}
fig, ax = plt.subplots(1, len(plots))
for n, (title, img) in enumerate(plots.items()):
    cmap = plt.cm.gnuplot if n == len(plots) - 1 else plt.cm.gray
    ax[n].imshow(img, cmap=cmap)
    ax[n].axis('off')
    ax[n].set_title(title)
plt.show(fig)

props = measure.regionprops(labels)
for prop in props:
    print('Label: {} >> Object size: {}'.format(prop.label, prop.area))

输出:

情节

Label: 1 >> Object size: 37
Label: 2 >> Object size: 66
Label: 3 >> Object size: 1
于 2018-07-21T11:40:38.773 回答
0

我们可以通过首先scipy.ndimage对阈值二值图像应用 的形态学关闭,然后使用label()函数合并二值图像中的连接区域来做同样的事情,如下所示(区域的大小有点不同,取决于大小形态内核):

from scipy.ndimage import label
from scipy.ndimage.morphology import binary_closing
from skimage.filters import threshold_otsu
import matplotlib.pylab as plt

original = plt.imread('https://i.stack.imgur.com/nkQpj.png')
thres = threshold_otsu(original)
binary = original > thres
binary_closed = binary_closing(binary, structure=np.ones((2,2)))
labeled_image, num_features = label(binary_closed)
feature_areas = np.bincount(labeled_image.ravel())[1:]   
print(feature_areas) # if we use 3x3 SE we shall get two regions with areas 24, 46
# [24 42  1]

plt.figure(figsize=(8,7))
plt.gray()
plt.subplot(221), plt.imshow(original), plt.axis('off'), plt.title('original')
plt.subplot(222), plt.imshow(binary), plt.axis('off'), plt.title('binray')
plt.subplot(223), plt.imshow(binary_closed), plt.axis('off'), plt.title('binray closed')
plt.subplot(224), plt.imshow(labeled_image, cmap='inferno'), plt.axis('off'), plt.title('labelled')
plt.show()

获得以下输出:

在此处输入图像描述

于 2019-10-20T10:47:58.190 回答