人体三围测量

三围测量

针对A-Pose的人体重建模型,进行三围测量时,一般就是在所认为的对应高度,使用横截面与人体模型取交点,可以得到待测的模型轮廓点集合。大概如下图所示:
人体三围测量位置
对所得轮廓线求取其周长即为三围的测量值。

轮廓线

但是这个方法,很容易将手臂上的点,也包含在测量的轮廓中,以俯视角度观察时截面为三个独立的圈,如下图所示,此情况可以通过判断轮廓独立,闭合等条件,自动将两边的手臂轮廓滤除。
腰部轮廓线俯视图

轮廓线截断

但由于使用了特定的站立姿势,若双手张开的幅度较小,或待测人员穿着短袖时衣袖过宽,都会造成重建的模型在胸部与手臂有一定的黏连,其轮廓线就无法像上图一般界限清晰,如下图:
胸部轮廓
这种情况下,轮廓线因为部位边界黏连而连续分布,无法判别,只能使用其他的辅助信息,如横向的边界范围,对轮廓线进行截断。如何求截断范围,在这里不进行讨论。截断范围在上图用红线表示,截断后剩余的点集,在两侧就出现了较大的缺口。在计算轮廓线周长时,忽略对缺口的处理,相当于直接使用直线将缺口两端的点连接起来计算,造成了缺失,这样计算显然是不合适的。应当考虑缺口两端的轮廓线分布趋势,使用连续曲线进行拟合,以此符合对人体俯视轮廓的先验理解。
可以使用贝塞尔,或者B-spine(条样)曲线。

贝塞尔曲线

参考贝塞尔曲线实现介绍,使用二次贝塞尔曲线对缺失的轮廓线进行补齐。
二次贝塞尔

图中P0和P2点分别为缺口两端的点,利用缺口端点小范围内点求得端点趋势,亦可理解为曲线在端点处的切向,两射线相交于图中P1点。通过以上3点可以补齐曲线:
在这里插入图片描述
左侧效果如下图所示,红色点为补齐出的点。
在这里插入图片描述

周长计算

轮廓线的提取算法保证了以上蓝色点集合按照一定的顺序排列(顺时针方向)。若可保证补齐后的曲线也按照此顺序,则计算周长时,只需要将相邻两点之间的距离进行累加,并加入首尾两点间距离,就完成了闭合曲线的近似周长计算。
在这里插入图片描述

缺口端点

胸部轮廓线产生缺口的原因基本是因为手臂部分的混淆,从俯视角度可以很清晰的看到,截断后的轮廓线应该分为前胸与后背两部分。可简单使用垂直方向的阈值,可将轮廓线分为后半部分,前半部分。如此,取两部分点集的首尾点,作为缺口端点即可,用于计算、补齐曲线。
错误做法: 对前后两部分点集,在水平方向排序,取水平方向上两侧极值作为缺口端点用于后续计算。此做法未考虑一种特殊情况,如下图:
在这里插入图片描述

  • 右侧后背缺口端点找错了;
  • 这样排序后在计算周长时,右侧的几个点因为顺序问题,无法计算得蓝色轮廓线的长度,反而计算了黑色折线的长度,使得最终的测量结果明显不对。

轮廓点顺序

实际计算时,虽然轮廓点集输出时保证了顺时针的顺序排列,但由于并未保证点集的起点位置:
在这里插入图片描述
使得计算周长时,顺序也发生了问题。
因此,为确保周长的计算,算法要求补齐曲线所产生的点,也按照原有轮廓线的排列顺序进行排列。则最理想的排列方式为:后背点集–>右侧补齐点集–>前胸点集–>左侧补齐点集(–>后背点集)。
此做法希望保证轮廓线的起点正好为后背点集的起点,或者前胸点集的起点。
在这里插入图片描述
利用上述用于分割前胸,后背点集合的垂直方向的阈值,计算跳变点作为新的起点位置:

	// reorder the points
    int cross_idx = -1;
    for (int i = 0; i < num_convex; i++)
    {
        float d1 = convex_vertices.row(i)[2] - z_threshold;
        float d2 = convex_vertices.row((i + 1) % num_convex)[2] - z_threshold;
        if (d1 * d2 < 0)
        {
            cross_idx = i;
            break;
        }
    }
    std::vector<Vec3> tmp_pts;
    for (int i = 0; i < num_convex; i++)
        tmp_pts.push_back(convex_vertices.row((i + cross_idx + 1) % num_convex));

猜你喜欢

转载自blog.csdn.net/weixin_46363611/article/details/106157355