当前位置: 首页 > 工具软件 > Mahotas > 使用案例 >

mahotas 距离变换Distance Transform -结合分水岭进行图像分割

燕玉堂
2023-12-01
实例1:distance()图像距离计算
import pylab as p,numpy as np  
import mahotas as mh
        
f = np.ones((256,256), bool)#原图像
f[200:,240:] = False  
f[128:144,32:48] = False  

# dmap像素(y,x)到最接近背景(黑色)像素的欧几里德距离平方;
# f[y,x] == True dmap[y,x] == 0
dmap = mh.distance(f)       #距离计算后的图像

p.imshow(dmap)  
p.show()  
====================================================================================
实例2:距离变换和分水岭-Distance Transform and Watershed
  
# 距离变换通常与分水岭结合以进行分割

import mahotas as mh,numpy as np
from matplotlib import pyplot as plt

def getThreshed():
    rgb = mh.demos.nuclear_image() #导入图像
    gray = rgb[:,:,0]

    gray = mh.gaussian_filter(gray, 1.)#高斯滤波
    threshed  = (gray > gray.mean())  #二值化
    return gray,threshed

gray,threshed=getThreshed()

def watershed_new(threshed):
    distances = mh.stretch(mh.distance(threshed))# 计算距离变换

    # 找到并标记区域最大值:
    Bc = np.ones((9,9))#关键参数
    maxima = mh.morph.regmax(distances, Bc=Bc)
    labeled,n_label = mh.label(maxima, Bc=Bc)

    # 为获得上面图像,反转距离变换(由于cwatershed定义的方式)并计算分水岭:
    surface = (distances.max() - distances)
    areas = mh.cwatershed(surface, labeled)
    areas *= threshed

    print(distances)
    print(labeled)
    print(n_label)

    return labeled,areas
"""
distances=[
        [42 42 42 ...  0  0  0]
        [39 39 39 ...  0  0  0]
        [36 36 36 ...  0  0  0]
        ...
        [ 0  0  0 ...  0  0  0]
        [ 0  0  0 ...  0  0  0]
        [ 0  0  0 ...  0  0  0]
        ]
        
labeled=[
        [1 1 1 ... 0 0 0]
        [0 0 0 ... 0 0 0]
        [0 0 0 ... 0 0 0]
        ...
        [0 0 0 ... 0 0 0]
        [0 0 0 ... 0 0 0]
        [0 0 0 ... 0 0 0]
        ]
n_label=59
"""
labeled,areas=watershed_new(threshed)

def  randomColors(gray,areas):#随机颜色填充黑色背景
    import random
    from matplotlib import colors as c
    colors =list( map(plt.cm.jet,range(0, 256, 4)))
    random.shuffle(colors)
    colors[0] = (0.,0.,0.,1.)
    rmap = c.ListedColormap(colors)

    plt.subplot(121)
    plt.imshow(gray, cmap='gray')
    plt.subplot(122)
    plt.imshow(areas, cmap=rmap)
    plt.show()

randomColors(gray,areas)

def watershed_old(threshed):#效果没有上面的好
    # 我们打算将Watershed应用于阈值图像的距离变换(使用矩阵最大值减去矩阵内所有元素,
    # 使得矩阵元素的数值原来大的变小,小的变大,得到下图):

    dist =  mh.distance(threshed)
    dist =  dist.max()-dist
    dist -= dist.min()
    dist  = dist/float(dist.ptp())*255
    dist  = dist.astype(np.uint8)
    plt.subplot(121)
    plt.imshow(dist)

    # 之前得到一堆最高峰labeled为核心位置,观察每个核心与邻居核心之间边界(元素数值局域极大值)
    # 把这个边界标记出来, 就得到了核心的区域划分图
    nuclei=mh.cwatershed(dist,labeled)
    plt.subplot(122)
    plt.imshow(nuclei)
    plt.show()

watershed_old(threshed)

2.函数:
mh.distance(bw, metric='euclidean2')  
用途:
# 计算图像bw的欧几里得距离:计算每个点到背景的距离;
# 如没有背景,那么将在所有像素中返回很高的值(无穷大inf)

参数:  
bw:ndarray;如元素为boolean,False/True表示背景前景。非布尔值被解释为bw != 0 
metric:str可选计算模式  'euclidean2','euclidean'
返回值:dmap:ndarray距离图
================================================================================
filtered = locmax(f, Bc={3x3 cross}, out={np.empty(f.shape, bool)})#局部最大值
filtered = regmax(f, Bc={3x3 cross}, out={np.empty(f.shape, bool)})# 区域最大值;考虑整体而不仅仅是邻域
参量:
f:ndarray
BC:ndarray,可选-结构元素
out:ndarray,可选-用于输出。必须是大小与`f`相同的布尔值ndarray
Returns:filtered : ndarray与f大小相同的布尔图像。

实例3:
image=np.zeros((6,5))
image[1,2]=2
image[2,2]=2
image[3,2]=3
image[4,2]=3

image
Out[13]: 
array([  [0., 0., 0., 0., 0.],
           [0., 0., 2., 0., 0.],top 2是局部最大值,因为它是邻域的最大值但这不是区域最大值
           [0., 0., 2., 0., 0.],
           [0., 0., 3., 0., 0.],
           [0., 0., 3., 0., 0.],
           [0., 0., 0., 0., 0.]])

mh.regmax(image)
Out[14]: 
array([  [False, False, False, False, False],
           [False, False, False, False, False],
           [False, False, False, False, False],
           [False, False,  True, False, False],
           [False, False,  True, False, False],
           [False, False, False, False, False]])
           
mh.locmax(image)
Out[16]: 
array([  [ True,  True, False,  True,  True],
           [ True, False,  True, False,  True],
           [ True, False, False, False,  True],
           [ True, False,  True, False,  True],
           [ True, False,  True, False,  True],
           [ True,  True, False,  True,  True]])
           
a=mh.distance(image)

a
Out[20]: 
array([[0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 0.]])

 

 类似资料: