代码之家  ›  专栏  ›  技术社区  ›  Jame

如何从二进制图像中分离单元格

  •  4
  • Jame  · 技术社区  · 6 年前

    我有一个细胞的二值图像。我想使用python单独分离这些单元格。每个单元格将保存在图像中。例如,我有1000个单元格,那么输出将是1000个图像,每个图像包含1个单元格。目前,我使用两种方法获得它,但输出错误

    from skimage.morphology import watershed
    from skimage.feature import peak_local_max
    from skimage import morphology
    import numpy as np
    import cv2
    from scipy import ndimage
    from skimage import segmentation
    
    image=cv2.imread('/home/toanhoi/Downloads/nuclei/9261_500_f00020_mask.png',0)
    image=image[300:600,600:900]
    # First way: peak_local_max
    distance = ndimage.distance_transform_edt(image)
    local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((3, 3)), labels=image)
    markers = morphology.label(local_maxi)
    labels_ws = watershed(-distance, markers, mask=image)
    markers[~image] = -1
    labels_rw = segmentation.random_walker(image, markers)
    cv2.imshow('watershed',labels_rw)
    cv2.waitKey(5000)
    # Second way way: using contour
    _,contours,heirarchy=cv2.findContours(image,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(image,contours,-1,(125,125,0),1)
    
    cv2.imshow('contours',image)
    cv2.waitKey(5000)
    

    enter image description here

    2 回复  |  直到 5 年前
        1
  •  3
  •   Ruaidhrí Primrose    5 年前

    我们也可以这样做 scikit-image morphology's label() 通过在二值图像中查找连接的组件来实现。但找到的单元格数为421。 Morphologial 操作,如 erosion / dilation / closing / opening 也可用于预处理输入图像并获得所需的输出。

    from skimage import morphology as morph
    from skimage.io import imread, imsave
    from skimage.color import rgb2gray
    import numpy as np
    import matplotlib.pyplot as plt
    
    im = rgb2gray(imread('sLUel.png'))
    #im = (im > 0).astype(np.uint8)
    
    #labeled = morph.label(morph.binary_opening(im, selem=morph.disk(radius=2)), connectivity=2)
    labeled = morph.label(im, connectivity=2)
    
    print(len(np.unique(labeled)))
    for i in np.unique(labeled)[1:]: # skip the first component since it's the background
        im_obj = np.zeros(im.shape) 
        im_obj[labeled == i] = 1
        imsave('sLUel_{:03d}.png'.format(i), im_obj)
    
    plt.figure(figsize=(20,10))
    plt.subplot(121), plt.imshow(im), plt.axis('off'), plt.title('original binary image', size=15)
    plt.subplot(122), plt.imshow(labeled, cmap='spectral'), plt.axis('off'), plt.title('connected components (radius 2)', size=15)
    plt.show()
    

    具有以下输出

    enter image description here

    以下是已识别和分离的细胞:

    enter image description here

        2
  •  2
  •   Aniket Navlur    6 年前

    一种方法是,

    import numpy as np
    import cv2
    
    img = cv2.imread('sLUel.png')       # image provided in question
    img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    mask = np.zeros(img.shape[:2],np.uint8)
    
    _,contours,hierarchy = cv2.findContours(img,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
    count = 0
    
    for i, c in enumerate(contours):
        if hierarchy[0,i,3] != -1:
            continue
    
        mask_copy = mask.copy()
    
        cv2.drawContours(mask_copy,c,-1,(255,255,255),-1)
        cv2.floodFill(mask_copy,None,(0,0),255)
        mask_inv=cv2.bitwise_not(mask_copy)
    
        cv2.imwrite(str(count)+'.png', mask_inv)
        count+=1
    

    图像中有420个单元格。