Python:如何正确分割这张图片?

Python: how could this image be properly segmented?

我想分割(隔离)图中所示的棒状结构:

我做到的最好的就是这个

# Imports the libraries.
from skimage import io, filters
import matplotlib.pyplot as plt
import numpy as np

# Imports the image as a numpy array.
img = io.imread('C:/Users/lopez/Desktop/Test electron/test.tif')

# Thresholds the images using a local threshold.
thresh = filters.threshold_local(img,301,offset=0)
binary_local = img > thresh # Thresholds the image
binary_local = np.invert(binary_local) # inverts the thresholded image (True becomes False and vice versa).

# Shows the image.
plt.figure(figsize=(10,10))
plt.imshow(binary_local,cmap='Greys')
plt.axis('off')
plt.show()

产生这个结果

但是,正如您从分割图像中看到的那样,我还没有成功地分离出杆状物。应该是黑色背景的东西充满了相互连接的结构。有没有办法巧妙地将杆状结构与图像中的所有其他元素隔离开来?

原图可在本站下载

https://dropoff.nbi.ac.uk/pickup.php

索赔 ID:qMNrDHnfEn4nPwB8

领取密码:UkwcYoYfXUfeDto8

这是我使用 Meijering 过滤器的尝试。 Meijering 过滤器在寻找管状结构时依赖于对称性,因此杆重叠的区域(破坏管状形状的对称性)没有很好地恢复,如下图所示。

此外,还有一些随机的废话我无法通过数字方式清除,但也许您可以在成像前多清理一下您的准备工作。

#!/usr/bin/env python

import numpy as np
import matplotlib.pyplot as plt

from skimage.io import imread
from skimage.transform import rescale
from skimage.restoration import denoise_nl_means
from skimage.filters import meijering
from skimage.measure import label
from skimage.color import label2rgb


def remove_small_objects(binary_mask, size_threshold):
    label_image = label(binary_mask)
    object_sizes = np.bincount(label_image.ravel())
    labels2keep, = np.where(object_sizes > size_threshold)
    labels2keep = labels2keep[1:] # remove the first label, which corresponds to the background
    clean = np.in1d(label_image.ravel(), labels2keep).reshape(label_image.shape)
    return clean


if __name__ == '__main__':

    raw = imread('test.tif')
    raw -= raw.min()
    raw /= raw.max()

    # running everything on the large image took too long for my patience;
    raw = rescale(raw, 0.25, anti_aliasing=True)

    # smooth image while preserving edges
    smoothed = denoise_nl_means(raw, h=0.05, fast_mode=True)

    # filter for tubular shapes
    sigmas = range(1, 5)
    filtered = meijering(smoothed, sigmas=sigmas, black_ridges=False)
    # Meijering filter always evaluates to high values at the image frame;
    # we hence set the filtered image to zero at those locations
    frame = np.ones_like(filtered, dtype=np.bool)
    d = 2 * np.max(sigmas) + 1 # this is the theoretical minimum ...
    d += 2 # ... but doesn't seem to be enough so we increase d
    frame[d:-d, d:-d] = False
    filtered[frame] = np.min(filtered)

    thresholded = filtered > np.percentile(filtered, 80)
    cleaned = remove_small_objects(thresholded, 200)

    overlay = raw.copy()
    overlay[np.invert(cleaned)] = overlay[np.invert(cleaned)] * 2/3

    fig, axes = plt.subplots(2, 3, sharex=True, sharey=True)
    axes = axes.ravel()
    axes[0].imshow(raw, cmap='gray')
    axes[1].imshow(smoothed, cmap='gray')
    axes[2].imshow(filtered, cmap='gray')
    axes[3].imshow(thresholded, cmap='gray')
    axes[4].imshow(cleaned, cmap='gray')
    axes[5].imshow(overlay, cmap='gray')

    for ax in axes:
        ax.axis('off')

    fig, ax = plt.subplots()
    ax.imshow(overlay, cmap='gray')
    ax.axis('off')
    plt.show()

如果这段代码写成论文,我想要一份确认书和一份论文副本。 ;-)