赞
踩
骨架提取,也叫二值图像细化。这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示。
morphology子模块提供了两个函数用于骨架提取,分别是Skeletonize()函数和medial_axis()函数。我们先来看Skeletonize()函数。
格式为:skimage.morphology.skeletonize(image)
输入和输出都是一幅二值图像。
例1:
from skimage import morphology,draw import numpy as np import matplotlib.pyplot as plt #创建一个二值图像用于测试 image = np.zeros((400, 400)) #生成目标对象1(白色U型) image[10:-10, 10:100] = 1 image[-100:-10, 10:-10] = 1 image[10:-10, -100:-10] = 1 #生成目标对象2(X型) rs, cs = draw.line(250, 150, 10, 280) for i in range(10): image[rs + i, cs] = 1 rs, cs = draw.line(10, 150, 250, 280) for i in range(20): image[rs + i, cs] = 1 #生成目标对象3(O型) ir, ic = np.indices(image.shape) circle1 = (ic - 135)**2 + (ir - 150)**2 < 30**2 circle2 = (ic - 135)**2 + (ir - 150)**2 < 20**2 image[circle1] = 1 image[circle2] = 0 #实施骨架算法 skeleton =morphology.skeletonize(image) #显示结果 fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4)) ax1.imshow(image, cmap=plt.cm.gray) ax1.axis('off') ax1.set_title('original', fontsize=20) ax2.imshow(skeleton, cmap=plt.cm.gray) ax2.axis('off') ax2.set_title('skeleton', fontsize=20) fig.tight_layout() plt.show()
代码报错:ImportError: cannot import name '_validate_lengths'
解决办法:https://blog.csdn.net/weixin_44508906/article/details/87347875
找到:Anaconda3/lib/python3.6/site-packages/numpy/lib/arraypad.py 954行,添加下面两个函数保存,重新加载即可消除错误
def _normalize_shape(ndarray, shape, cast_to_int=True): """ Private function which does some checks and normalizes the possibly much simpler representations of ‘pad_width‘, ‘stat_length‘, ‘constant_values‘, ‘end_values‘. Parameters ---------- narray : ndarray Input ndarray shape : {sequence, array_like, float, int}, optional The width of padding (pad_width), the number of elements on the edge of the narray used for statistics (stat_length), the constant value(s) to use when filling padded regions (constant_values), or the endpoint target(s) for linear ramps (end_values). ((before_1, after_1), ... (before_N, after_N)) unique number of elements for each axis where `N` is rank of `narray`. ((before, after),) yields same before and after constants for each axis. (constant,) or val is a shortcut for before = after = constant for all axes. cast_to_int : bool, optional Controls if values in ``shape`` will be rounded and cast to int before being returned. Returns ------- normalized_shape : tuple of tuples val => ((val, val), (val, val), ...) [[val1, val2], [val3, val4], ...] => ((val1, val2), (val3, val4), ...) ((val1, val2), (val3, val4), ...) => no change [[val1, val2], ] => ((val1, val2), (val1, val2), ...) ((val1, val2), ) => ((val1, val2), (val1, val2), ...) [[val , ], ] => ((val, val), (val, val), ...) ((val , ), ) => ((val, val), (val, val), ...) """ ndims = ndarray.ndim # Shortcut shape=None if shape is None: return ((None, None), ) * ndims # Convert any input `info` to a NumPy array shape_arr = np.asarray(shape) try: shape_arr = np.broadcast_to(shape_arr, (ndims, 2)) except ValueError: fmt = "Unable to create correctly shaped tuple from %s" raise ValueError(fmt % (shape,)) # Cast if necessary if cast_to_int is True: shape_arr = np.round(shape_arr).astype(int) # Convert list of lists to tuple of tuples return tuple(tuple(axis) for axis in shape_arr.tolist()) def _validate_lengths(narray, number_elements): """ Private function which does some checks and reformats pad_width and stat_length using _normalize_shape. Parameters ---------- narray : ndarray Input ndarray number_elements : {sequence, int}, optional The width of padding (pad_width) or the number of elements on the edge of the narray used for statistics (stat_length). ((before_1, after_1), ... (before_N, after_N)) unique number of elements for each axis. ((before, after),) yields same before and after constants for each axis. (constant,) or int is a shortcut for before = after = constant for all axes. Returns ------- _validate_lengths : tuple of tuples int => ((int, int), (int, int), ...) [[int1, int2], [int3, int4], ...] => ((int1, int2), (int3, int4), ...) ((int1, int2), (int3, int4), ...) => no change [[int1, int2], ] => ((int1, int2), (int1, int2), ...) ((int1, int2), ) => ((int1, int2), (int1, int2), ...) [[int , ], ] => ((int, int), (int, int), ...) ((int , ), ) => ((int, int), (int, int), ...) """ normshp = _normalize_shape(narray, number_elements) for i in normshp: chk = [1 if x is None else x for x in i] chk = [1 if x >= 0 else -1 for x in chk] if (chk[0] < 0) or (chk[1] < 0): fmt = "%s cannot contain negative values." raise ValueError(fmt % (number_elements,)) return normshp ############################################################################### # Public functions
生成一幅测试图像,上面有三个目标对象,分别进行骨架提取,结果如下:
例2:利用系统自带的马图片进行骨架提取
- from skimage import morphology,data,color
- import matplotlib.pyplot as plt
-
- image=color.rgb2gray(data.horse())
- image=1-image #反相
- #实施骨架算法
- skeleton =morphology.skeletonize(image)
-
- #显示结果
- fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4))
-
- ax1.imshow(image, cmap=plt.cm.gray)
- ax1.axis('off')
- ax1.set_title('original', fontsize=20)
-
- ax2.imshow(skeleton, cmap=plt.cm.gray)
- ax2.axis('off')
- ax2.set_title('skeleton', fontsize=20)
-
- fig.tight_layout()
- plt.show()
medial_axis就是中轴的意思,利用中轴变换方法计算前景(1值)目标对象的宽度,格式为:
skimage.morphology.medial_axis(image, mask=None, return_distance=False)
mask: 掩模。默认为None, 如果给定一个掩模,则在掩模内的像素值才执行骨架算法。
return_distance: bool型值,默认为False. 如果为True, 则除了返回骨架,还将距离变换值也同时返回。这里的距离指的是中轴线上的所有点与背景点的距离。
- import numpy as np
- import scipy.ndimage as ndi
- from skimage import morphology
- import matplotlib.pyplot as plt
-
- #编写一个函数,生成测试图像
- def microstructure(l=256):
- n = 5
- x, y = np.ogrid[0:l, 0:l]
- mask = np.zeros((l, l))
- generator = np.random.RandomState(1)
- points = l * generator.rand(2, n**2)
- mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
- mask = ndi.gaussian_filter(mask, sigma=l/(4.*n))
- return mask > mask.mean()
-
- data = microstructure(l=64) #生成测试图像
-
- #计算中轴和距离变换值
- skel, distance =morphology.medial_axis(data, return_distance=True)
-
- #中轴上的点到背景像素点的距离
- dist_on_skel = distance * skel
-
- fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
- ax1.imshow(data, cmap=plt.cm.gray, interpolation='nearest')
- #用光谱色显示中轴
- ax2.imshow(dist_on_skel, cmap=plt.cm.spectral, interpolation='nearest')
- ax2.contour(data, [0.5], colors='w') #显示轮廓线
-
- fig.tight_layout()
- plt.show()
LEAP Estimates Animal Pose(LEAP)
相关论文:Fast animal pose estimation using deep neural networks
https://blog.csdn.net/wuyang514263/article/details/86628882
https://cloud.tencent.com/developer/news/375634
我们都看过好莱坞电影中的「动作捕捉」场景,透过贴满传感器的全身套装追踪动作,计算机能够将演员变成巨人或野兽,而在现实生活中,普林斯顿神经科学研究所(PNI)也已开发出一套 AI 工具,只需要几分钟的训练,便能像演员穿戴传感器一样,在现有影片中自动追踪动物的动作细节,协助动物肢体语言的研究进行。这项被称为 LEAP 的工具只需要几分钟的训练,不需添加任何物理标记或卷标,就能够以,以高精准度自动追踪影片中数百万帧动物各个身体部位的姿态,分子生物学副教授 Mala Murthy 表示,「这个方法可广泛用于动物模型系统,用来衡量有基因突变或药物治疗后动物的行为」。
尽管论文预计会发表在 2019 年 1 月出版的《自然-方法》(Nature Methods)期刊上,但因为 5 月已经发布开放版本,目前软件已经被被许多相关实验室采用。论文第一作者、PNI 研究生 Talmo Pereira 表示,这个工具非常灵活,原则上可用于任何影像数据,「它的工作方式是在几个影片中标记几个点,接着神经网络会完成剩下的工作。我们提供了一个易于使用的界面,让任何人无需任何预先的编程知识,都可以将 LEAP 应用到自己的影片中。」当被问及 LEAP 是否在大型哺乳动物的效果和在受试的苍蝇和老鼠一样好时,Pereira 立即使用肯尼亚 Mpala 研究中心的行走的长颈鹿影片进行示范,花了不到 1 个小时在 30 帧中标记了点,而 LEAP 随后便能立即追踪剩余影片中的长颈鹿动作姿态(大约 500 帧)。
过去类似的 AI 工具都仰赖大量的手动注释数据训练,使其能够在各种不同背景、光线的数据上工作,而在 LEAP 上因为开发团队建立的系统,用户可以选择适合用户收集的数据类型的神经网络,而不会受到其他研究人员或公司进行项目的限制。”在未参与研究英国皇家兽医学院(RVC)Monica Daley 看来,这项工作在神经科学之外也具有巨大的潜力。Daley 的多数研究都在了解动物如何在不同的地形环境下有效地移动,而这当中做大的挑战便是从影片片段中提取有意义的讯息,LEAP 有望让相关研究者的工作变得比以往更自动化,能够专注于研究更多种类的动物运动行为。当研究者将 LEAP 与其他定量工具相结合后,便能透过观察动物身体运动模式来研究所谓的「肢体语言」,而团队内的神经科学家也就可以与背后的神经过程建立相关联系。过去五年中,神经科学在观察和操纵大脑活动的技术上取得了巨大进步,而在 LEAP 的协助下,未来动物行为的自动分类也能够更加自动化,研究作者之一的 Joshua Shaevitz 认为,这不仅能使研究人员更好地了解大脑如何产生行为,也能够探索未来对于需求者的诊断和治疗方法。
https://www.jianshu.com/p/3aa810b35a5d
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。