天天看点

骨架提取算法-针对鱼类1、骨架提取2 标记点自动识别3 Github开源人体姿态识别项目OpenPose中文文档

https://www.cnblogs.com/denny402/p/5167414.html

1、骨架提取

骨架提取,也叫二值图像细化。这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示。

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​
           

生成一幅测试图像,上面有三个目标对象,分别进行骨架提取,结果如下:

骨架提取算法-针对鱼类1、骨架提取2 标记点自动识别3 Github开源人体姿态识别项目OpenPose中文文档

例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()
           
骨架提取算法-针对鱼类1、骨架提取2 标记点自动识别3 Github开源人体姿态识别项目OpenPose中文文档

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()
           
骨架提取算法-针对鱼类1、骨架提取2 标记点自动识别3 Github开源人体姿态识别项目OpenPose中文文档

2 标记点自动识别

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 表示,「这个方法可广泛用于动物模型系统,用来衡量有基因突变或药物治疗后动物的行为」。

骨架提取算法-针对鱼类1、骨架提取2 标记点自动识别3 Github开源人体姿态识别项目OpenPose中文文档

尽管论文预计会发表在 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 认为,这不仅能使研究人员更好地了解大脑如何产生行为,也能够探索未来对于需求者的诊断和治疗方法。

3 Github开源人体姿态识别项目OpenPose中文文档

https://www.jianshu.com/p/3aa810b35a5d