实例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.]])