簡體   English   中英

分水嶺分割后的 label 分配不正確(Python)

[英]Incorrect label assignment after watershed segmentation (Python)

我正在使用 skimage.segmentation.watershed 分割一些粒子。 這工作得很好,我設法將它們分開(見圖)。 分割后的圖像 但是,當我使用 ndi.label 到 label 時,不同的區域,並不是所有的段都被分開了,有些被分配了相同的label (即使有分水嶺,對於實例左上角的粒子)任務。 請注意先前分離的粒子是如何分配相同的 label 的 我在 Python 中相對較新,不知道我還能嘗試解決這個問題。 如果您能給我任何幫助,我將不勝感激。 提前致謝:)

我正在使用的代碼是(我將它放在一個 for 循環中,因為我想自動化同時分析多個圖像的過程):

#import hyperspy for reading directly ser or emd files
import hyperspy.api as hs
#The scikit image library will be used for segmenting the images
from skimage.exposure import histogram
from skimage.color import label2rgb
from skimage import data, io, filters
from skimage.filters import threshold_local, threshold _yen, threshold_li
from skimage.filters import try_all_threshold
from skimage.filters import gaussian
from skimage.feature import peak_local_max
from skimage.feature import canny
from skimage import measure
from skimage.morphology import label
from skimage.morphology import remove_small_objects
from skimage.draw import ellipse
from skimage.measure import label, regionprops, regionprops_table
from skimage.transform import rotate
from skimage.segmentation import watershed
#matplotlib for performing plots
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

#Basic packages (math and statistics)
import pandas as pd
import numpy as np
from scipy import ndimage as ndi
from scipy import stats
import math
import glob
import seaborn as sns
#load data
s=hs.load(folder+'*.emi',stack=True)

#threshold
thresh=threshold_li(s.data)
binary=s>thresh

#Cleaning

cleaned=remove_small_objects(binary.data, min_size=5)

分割本身

#Define variables needed

dist=np.zeros([cleaned.shape[1],cleaned.shape[1]])
water=np.zeros([cleaned.shape[0],cleaned.shape[1],cleaned.shape[1]])
mask=np.zeros(dist.shape, dtype=bool)
markers,_=ndi.label(mask)
water_particles=np.zeros([cleaned.shape[0],cleaned.shape[1],cleaned.shape[1]])
eq_diam_total=np.array([])

#for loop for segmenting all the images using watershed. 
#I will use the commented "for i in range (cleaned.shape[0])" 
#once I manage to solve the segmentation issue:


#for i in range (cleaned.shape[0]):
for i in range(2,3):
    dist = ndi.distance_transform_edt(cleaned[i,:,:]) #make distance map
    maxima=peak_local_max(gaussian(dist, sigma=1.5),threshold_rel=None, 
    min_distance=5)  # find local maxima
    print('maxima',maxima.shape)

    mask[tuple(maxima.T)]=True
    markers,_=ndi.label(mask)
    print('markers',markers.shape)
 
    #segment
    water[i,:,:]=watershed(-dist, markers,mask=cleaned[i,:,:])
    print('water', water.shape)
    
    #label each particle
    water_particles[i,:,:], water_labels = ndi.label(water[i,:,:])
    print('water_particles',water_particles.shape)
    print('water_labels',water_labels)
  
    

分割后的Plot

%matplotlib inline  
from skimage import color
fig,axes=plt.subplots(1, 2, sharey=True)  

axes[0].imshow(color.label2rgb(water[i,:,:]))
axes[0].axis('off')
axes[0].set_title('After watershed segmentation')               
               

axes[1].imshow(color.label2rgb(water_particles[i,:,:]))
axes[1].axis('off')
axes[1].set_title('After label')

skimage.segmentation.watershed 的skimage.segmentation.watershed是標注圖像,它可以將 go 直接導入測量 function ( regionprops )。

此外,該分水嶺 function 將所有局部最小值作為標記,您不需要自己找到這些。 簡化代碼:

from scipy import ndimage as ndi
from skimage.segmentation import watershed

# ...

    dist = ndi.distance_transform_edt(cleaned[i,:,:]) #make distance map
    water_particles[i,:,:] = watershed(-dist, markers,mask=cleaned[i,:,:])

如果您想接收圖像,您可以自己 label(無論出於何種原因),然后添加watershed_line=True參數。 這將保持每個區域(盆地)之間的分離,以便標記算法可以識別它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM