我怎样才能从二进制图像中分离出细胞
How could I separate cells from binary image
我有细胞的二值图像。我想使用 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)
一种方法是,
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 个单元格。
可以通过查找二值图像中的连通分量来使用 scikit-image morphology's label()
函数执行相同的操作。虽然找到的单元格数量是 421。 Morphologial
操作,如 erosion / dilation / closing / opening
也可用于 pre-processing 输入图像并获得所需的输出。
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()
具有以下输出
这里是识别和分离的细胞:
我有细胞的二值图像。我想使用 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)
一种方法是,
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 个单元格。
可以通过查找二值图像中的连通分量来使用 scikit-image morphology's label()
函数执行相同的操作。虽然找到的单元格数量是 421。 Morphologial
操作,如 erosion / dilation / closing / opening
也可用于 pre-processing 输入图像并获得所需的输出。
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()
具有以下输出
这里是识别和分离的细胞: