基于深度图的位姿估计(2018至今)

1. 简介

1.1 人体姿态估计难点

  • 姿态的个体差异性:包括特殊体格、外观及特殊姿态等,以及在训练中未能涉及的范畴
  • 相机噪声:深度相机虽然能方便地采集场景深度,但由于成本,实现原理等方面的限制,成像仍会呈现不稳定的噪声,且深度的精度也与目标的距离相关
  • 遮挡:不可见部位的识别一直是姿态估计的难点,识别算法需借助人体的结构特征预测或恢复被遮挡的区域

1.1.1 随机森林模型

  • 训练输出
    • 随机森林模型
      • 深度
      • 森林规模
    • 每个节点使用的决策特征:点或线特征,而未使用面特征
      • 邻域像素间的深度比较
      • 深度梯度差
      • 表面凹凸性

1.2 Human Pose Estimation(HPE)关键元素

  • 网络结构
  • 损失函数

1.3 A2J详细网络结构

1.3.1 骨干网络(BackBone)

在这里插入图片描述

1.3.2 后处理(PostProcess)

在这里插入图片描述

2. A2J回归网络

  • 论文:A2J: Anchor-to-Joint Regression Network for 3D Articulated Pose Estimation from a Single Depth Image (2019)
  • 核心思想
    • 本着整体学习以增强泛化能力的精神,通过聚合多个anchor点的估计结果预测3D关节位置
  • 创新
    • 以一种简单的方式来使anchor point的概念在姿态估计任务上得以实现
  • 主要步骤
    • 人体分割(Human Segmentation),类似于human pose的Top-down思路
    • 密集的在图像上设立anchor point,每隔4个像素点(stride=4)就会设立一个anchor point
    • 最终的关节点预测将会通过这些anchor point去完成
    • 详细过程:每个锚点需要针对所有关节点预测一个图像坐标下的偏移量以及一个深度值,最终的关节点坐标将由所有锚点加权投票得出(权重是可学习的,图中红色的anchor point就是权重值比较大的点,我们称之为informative anchor point
  • 代码https://github.com/zhangboshen/A2J
  • 硬件平台:NVIDIA 1080Ti GPU
  • 主要特点
    • 基于anchor的回归网络,具有end-to-end的学习能力
    • 提出了一个“内容丰富的锚点(anchor)”方案,同时考虑了关节位置预测误差锚点空间布局
    • 为确保运行效率,采用了2D CNN,且没有反卷积层

2.1 历史总结

2.1.1 先进的非深度学习方案

  • 代表作
    • Real-time human pose recognition in parts from single depth images (2011,Jamie Shotton)
    • Depth-images-based pose estimation using regression forests and graphical models (2015, Li He)
  • 步骤
    • 第一步:提取人工设计的特征
    • 第二步:执行分类或回归
  • 不足
    • 人工设计特征表达能力不足

2.1.2 2D深度学习方案

  • 代表作
    • Deeppose: Human pose estimation via deep neural networks (2014, Alexander Toshev)
  • 特色
    • 深度学习对视觉模式特征具有很强的学习能力
    • 2D CNN在2D位姿估计中获得了巨大的成功
  • 步骤
    • 第一步:获得所有关节的热图(heatmap)集
    • 第二步:回归关节2D位姿
  • 不足
    • 热图设置无法适应不同的关节
    • 反卷积操作非常耗时
    • 部分基于encoder-decoder的方法无法进行end-to-end训练

2.1.3 3D深度学习方案

  • 核心思想
    • 为了充分利用深度图中的3D信息以提高性能,近来的研究倾向于3D深度学习
    • 此思路又分为两个研究方向:
      • 基于3D CNN
      • 基于point-set
2.1.3.1 基于3D-CNN
  • 代表作
    • 3D convolutional neural networks for efficient and robust hand pose estimation from single depth images (2017, Liuhao Ge)
    • Hand3d: Hand pose estimation using 3d neural network (2017, Xiaoming Deng)
    • V2V-PoseNet: Voxel-to-voxel prediction network for accurate 3d hand and human pose estimation from a single depth map (2018, Gyeongsik Moon)
  • 步骤
    • 将深度图像体素化为体积表示(例如,占用网格模型:[Voxnet: A 3d convolutional neural network for real-time object recognition (2017)])
    • 执行3D卷积或反卷积操作以提取3D视觉特征
  • 不足
    • 由于卷积参数众多,3D CNN训练较慢
    • 3D体素化操作需要较大的计算力和内存空间

2.1.3.2 基于point-set

  • 代表作
    • Pointnet: Deep learning on point sets for 3d classification and segmentation (2017, R Qi Charles)
    • Pointnet++: Deep hierarchical feature learning on point sets in a metric space (2017, Charles Ruizhongtai Qi)
  • 步骤
    • 把深度图转换成点云
    • 点云采样和KNN搜索
  • 不足
    • 运行效率低

2.1.4 A2J (2D深度学习)

  • 分组
    • A2J属于2D深度学习
  • 优点
    • 密集的锚点以整体方式捕获全局-局部空间上下文信息,而无需使用计算量大的反卷积层
    • 2D CNN用作骨干网络以提高运行效率

2.2 锚点到关节点(A2J)回归网络

2.2.1 A2J网络

在这里插入图片描述

符号定义
A A A所有锚点的集合
a a a锚点 a , 且 a ∈ A a, 且a \in A a,aA
J J J所有关节的集合
j j j关节 j , 且 j ∈ J j, 且 j \in J j,jJ
K K K关节的数量
S ( a ) S(a) S(a)锚点 a a a 的2D坐标位置
P j ( a ) P_j(a) Pj(a)锚点 a a a 对关节 j j j 的响应,即锚点 a a a 对关节 j j j 贡献的大小
O j ( a ) O_j(a) Oj(a)预测的从锚点 a a a 到关节 j j j 的平面内偏移 (2D坐标偏移)
D j ( a ) D_j(a) Dj(a)由锚点 a a a所预测关节 j j j 的深度值
  • 2D主干网络:
    • ResNet-50
  • 三个功能分支:
    • 平面内偏移量估计:预测 O j ( a ) O_j(a) Oj(a)
    • 深度估计:预测 D j ( a ) D_j(a) Dj(a)
    • 锚点提案:寻找信息量丰富的锚点(权重较大的点), 预测 P j ( a ) P_j(a) Pj(a);输出结果经过softmax之后直接乘在前面两支的输出结果上对anchor point投票进行权重赋值
  • 方案特点
    • Anchor proposal分支可学习,对于不同的关节点,Informative anchor point的分布是不一样的,因此,A2J具有针对不同关节点的自适应性
    • 网络中不包含Deconv层,这里区别于目前主流的Heatmap的做法,不需要上采样使得算法速度更快,结构更简单
    • End-to-end training,最终的loss来自于anchor point加权投票之后的预测输出以及GT之间的差异,不需要对GT进行任何形式的变换
    • 快:网络结构简单,前向推理的速度很快,在NVIDIA 1080Ti的实测速度超过100fps
  • 网络的最终输出
    • 对于每一个anchor point,都会输出对于每个关节的offset、depth以及置信度(即权重)

2.2.2 锚点选取方案

  • 锚点选取方案
    • 在输入深度图像中密集地选取锚点,其stride 为4个像素( S t = 4 S_t=4 St=4),以同时提取全局-局部空间信息,如下图所示
      在这里插入图片描述

2.2.3 计算关节位置

  • 需要计算关节以下两个位置:
    • 关节 j j j的平面内位置
    • 关节 j j j的深度值
  • 锚点用途
    • 本质上,每个锚点 a a a 都用作局部回归器,以通过平面内偏移预测分支 O j ( a ) O_j(a) Oj(a)深度估计分支 D j ( a ) D_j(a) Dj(a)预测所有关节的3D位置
    • 对于特定的关节,每个锚点的贡献是不同的,通过锚点提案分支获得对应的权重 P j ( a ) P_j(a) Pj(a)
  • 如何得到关节的3D位置?
    • 对于指定关节,最终通过整合所有锚点的输出来进行本关节的定位,以求得关节的3D位置
    • 关节 j j j 的平面内位置和深度值:通过所有锚点输出的加权平均值获得
  • 计算关节 j j j在平面内的位置和深度值
    { S ^ j = ∑ a ∈ A P ^ j ( a ) ( S ( a ) + O j ( a ) ) D ^ j = ∑ a ∈ A P ^ j ( a ) D j ( a ) ( 1 ) \begin{cases} \hat{S}_j = \sum_{a \in A} \hat{P}_j(a)( S(a) + O_j(a) ) \\ \hat{D}_j= \sum_{a \in A} \hat{P}_j(a) D_j(a) \end{cases} \quad \quad (1) {S^j=aAP^j(a)(S(a)+Oj(a))D^j=aAP^j(a)Dj(a)(1)
    • S ^ j \hat{S}_j S^j:关节 j j j 在平面内的估计值
    • D ^ j \hat{D}_j D^j:关节 j j j 的深度估计值
    • P ^ j ( a ) \hat{P}_j(a) P^j(a):是锚点 a a a 相对于关节 j j j的归一化权重,使用softmax进行计算而得
      P ^ j ( a ) = e P j ( a ) ∑ a ∈ A e P j ( a ) ( 2 ) \hat{P}_j(a) = \frac{e^{P_j(a)}}{\sum_{a \in A} e^{P_j(a)}} \quad \quad (2) P^j(a)=aAePj(a)ePj(a)(2)
      • P ^ j ( a ) > 0.02 \hat{P}_j(a) > 0.02 P^j(a)>0.02:则认为此锚点 a a a对关节 j j j来说,是一个信息丰富的锚点(informative anchor point)

2.2.4 平面内偏移 O j ( a ) O_j(a) Oj(a)和深度估计 D j ( a ) D_j(a) Dj(a)

  • O j ( a ) O_j(a) Oj(a)
    • 预测的2D偏移量,由神经网络输出
    • 尺寸:[5184, 15, 2]
    • 总共5184 (72x72) 个锚点,每一个锚点回归出每一个关节的偏移量
  • D j ( a ) D_j(a) Dj(a)
    • 预测的深度值,由神经网络输出
    • 尺寸:[5184, 15]
    • 总共5184 (72x72) 个锚点,每一个锚点回归出每一个关节的深度值在这里插入图片描述
  • 功能
    • 预测关节的3D位置
    • 平面内偏移估计:估计当前锚点 a a a与每个关节的偏移量 O j ( a ) O_j(a) Oj(a)
    • 深度估计:通过当前锚点 a a a预测每个关节的深度值
    • 由于具有不同属性,所以二者采用不同的网络分支
  • 网络结构
    • 输入回归主干网络输出的特征图(包含语义特征),输入深度图像的1/16下采样,即特征图上的一个点对应原深度图像上的16(4x4)个锚点
    • 网络层: 包含4个3x3的卷积层(带有BN和ReLU),提取丰富的局部信息,且尺寸不变(没有池化)
    • 输出:1个输出层,平面内偏移量估计输出 16 x K x 2 个channels,而深度估计输出 16 x K x 1个channels

2.2.5 计算锚点权重 P j ( a ) P_j(a) Pj(a)

  • P j ( a ) P_j(a) Pj(a)
    • 预测的权重,由神经网络输出
    • 尺寸:[5184, 15]
    • 总共5184 (72x72) 个锚点,每一个锚点回归出每一个关节的权重
  • 为计算关节的2D位置估计服务:
    • P j ( a ) P_j(a) Pj(a)升为[5184, 15,2],即把每个Anchor对每个关节的权重复制一份
    • 对于每一个关节,取所有Anchors的加权平均值 P j ( a ) ( S ( a ) + O j ( a ) ) P_j(a) (S(a) + O_j(a)) Pj(a)(S(a)+Oj(a)),即5184个这样的值相加
  • 为计算关节的深度估计服务:
    • 对于每一个关节,取所有Anchors的加权平均值 P j ( a ) D j ( a ) P_j(a) D_j(a) Pj(a)Dj(a),即5184个这样的值相加在这里插入图片描述
  • 功能
    • 为特定关节找到贡献大(informative) 的锚点,并分配对应的权重给它,即 P j ( a ) P_j(a) Pj(a)
  • 网络结构
    • 输入共用主干网络输出的特征图(包含语义特征),输入深度图像的1/16下采样,即特征图上的一个点对应原深度图像上的16(4x4)个锚点
    • 网络层: 包含4个3x3的卷积层(带有BN和ReLU),提取丰富的局部信息,且尺寸不变(没有池化)
    • 输出:1个输出层,包含 16 x K x 1个channels

2.2.6 骨干网

在这里插入图片描述

  • 网络结构
    • 骨干网为在ImageNet上预训练过的ResNet-50
    • common trunk:由block 0~3组成
    • regression trunk:由block4组成

2.3 锚点到关节点(A2J)学习过程

2.3.1 输入数据

  • Hand Pose:使用中心点从深度图像中裁剪手部区域
  • Body Pose:使用bounding box截取身体区域

2.3.2 算法描述

  • 符号说明
符号说明
T j i T_j^i Tji在截取之后的区域中,关节 j j j的像素2D真值坐标(GT)
T j d T_j^d Tjd关节 j j j的深度真值(GT)
Z j Z_j Zj关节 j j j的深度真值(GT)
  • T j i T_j^i Tji T j d T_j^d Tjd:具有可比性
  • T j d T_j^d Tjd Z j Z_j Zj的变换公式
    T j d = μ ( Z j − θ ) ( 3 ) T_j^d = \mu (Z_j - \theta) \quad \quad (3) Tjd=μ(Zjθ)(3)
    • μ \mu μ: Hand Pose μ = 1 \mu=1 μ=1Body Pose μ = 50 \mu=50 μ=50
    • θ \theta θ: Hand Pose θ \theta θ为中心点的深度,Body Pose θ = 0 ( 没 有 深 度 中 心 ) \theta=0(没有深度中心) θ=0()

2.3.3 输出数据

  • 测试时,其预测结果为世界坐标

2.3.4 监督训练的损失函数

2.3.4.1 关节位置估计损失
  • 每个锚点作为局部回归器以预测关节的3D位置,其损失函数为:
    l o s s 1 = α ∑ j ∈ J L τ 1 ( ∑ a ∈ A P ^ J ( a ) ( S ( a ) + O j ( a ) ) − T j i ) + ∑ j ∈ J L τ 2 ( ∑ a ∈ A P ^ j ( a ) D j ( a ) − T j d ) = α ∑ j ∈ J L τ 1 ( S ^ j − T j i ) + ∑ j ∈ J L τ 2 ( D ^ j − T j d ) ( 4 ) loss_1 = \alpha \sum_{j \in J} L_{\tau_1} (\sum_{a \in A} \hat{P}_J(a)(S(a) + O_j(a)) - T_j^i) +\\ \sum_{j \in J} L_{\tau_2} (\sum_{a \in A}\hat{P}_j(a)D_j(a) - T_j^d) \\ \quad = \alpha \sum_{j \in J} L_{\tau_1} (\hat {S}_j - T_j^i) + \sum_{j \in J} L_{\tau_2} (\hat{D}_j - T_j^d) \quad (4) loss1=αjJLτ1(aAP^J(a)(S(a)+Oj(a))Tji)+jJLτ2(aAP^j(a)Dj(a)Tjd)=αjJLτ1(S^jTji)+jJLτ2(D^jTjd)(4)
  • 物理含义
    • 预测值(2D位置和深度值)与真值的差异
  • α = 0.5 \alpha = 0.5 α=0.5:是平面内偏移量估计与深度估计的平衡参数
  • T j i 和 T j d T_j^i和T_j^d TjiTjd:分别是关节 j j j的平面内坐标真值和深度真值
  • L τ ( ⋅ ) L_{\tau}(\cdot) Lτ():是一个平滑函数 s m o o t h L 1 smooth_{L1} smoothL1
    L τ ( x ) = { 1 2 τ x 2 , f o r ∣ x ∣ < τ ∣ x ∣ − τ 2 , otherwise ( 5 ) L_{\tau}(x)= \begin{cases} \frac{1}{2 \tau} x^2, & for |x| < \tau \\ |x| - \frac{\tau}{2}, & \text {otherwise} \end{cases} \quad \quad (5) Lτ(x)={2τ1x2,x2τ,forx<τotherwise(5)
    • τ 1 = 1 \tau_1 = 1 τ1=1
    • τ 2 = 3 \tau_2 = 3 τ2=3:因为深度值的噪声比坐标位置的噪声大
2.3.4.2 信息锚点包围损失
  • 根据从多个不同视角观测关节点的原理倾向于关节附近信息量大的锚点
  • 信息锚点包围损失如下
    l o s s 2 = ∑ j ∈ J L τ 1 ( ∑ a ∈ A P ^ j ( a ) S ( a ) − T j i ) ( 6 ) loss_2 = \sum_{j \in J} L_{\tau_1} (\sum_{a \in A} \hat{P}_j(a) S(a) - T_j^i) \quad (6) loss2=jJLτ1(aAP^j(a)S(a)Tji)(6)
  • 物理含义
    • Informative anchor point的空间分布,希望最终的Informative anchor point可以从关节点的各个角度去观察预测
  • 功能
    • 实际是上是一个正则项,可以有效地缓解过拟合现象
  • 此损失函数的使用效果
    在这里插入图片描述

2.3.5 端到端训练

  • 以上两个损失函数联合端到端的训练过程,其公式如下:
    l o s s = λ l o s s 1 + l o s s 2 ( 7 ) loss = \lambda loss_1 + loss_2 \quad \quad (7) loss=λloss1+loss2(7)
    • λ = 3 \lambda =3 λ=3:权重因子用于平衡 l o s s 1 loss_1 loss1 l o s s 2 loss_2 loss2

2.4 实验

2.4.1 数据集

  • Hand Pose
Dataset训练样本数测试样本数真值数据关节数
HANDS 2017957K295K3D坐标21
NYU Hand Pose72K8.2K3D坐标36
ICVL Hand Pose22K1.5K3D坐标16
  • Body Pose
Dataset训练样本数测试样本数真值数据关节数
ITOP (Invariant-Top) Body Pose80K20K3D坐标15
K2HPD(Kinect2 Human Pose Dataset) Body Pose100K(共)2D坐标15

2.4.2 评价指标

  • Hand Pose
    • 3D距离误差
    • 成功率的百分比
  • Body Pose
    • 检测到的关节百分比 (PDJ:Percent of Detected Joints)
    • 平均精度均值(10cm规则)(mAP:mean Average Precision)

2.4.3 实现细节

  • 实现框架: PyTorch
  • 输出尺寸: 输入深度图像通过裁剪和缩放至固定分辨率(Hand: 176 x 176, Body: 288x288)
  • 数据增强:
    • 在平面和深度两个维度进行随机旋转随机缩放
    • 增加随机高斯噪声(以0.5的概率)
  • 优化器: Adam
  • 学习率: 0.00035,且权重衰减率为0.0001
  • Body训练epochs: 26

2.4.4 与先进方法的比较

  • V2V-PoseNet是A2J强有力的竞争者
方法模型数量推理速度
A2J1
V2V-PoseNet10
2.4.4.1 NYU Hand Pose数据集对比测试

在这里插入图片描述

2.4.4.2 ITOP Body Pose数据集对比测试

在这里插入图片描述

索引号时间名称
332011Jamie Shotton, Andrew Fitzgibbon, Mat Cook, Toby Sharp,Mark Finocchio, Richard Moore, Alex Kipman, and Andrew Blake. Real-time human pose recognition in parts from single depth images
502015Ho Yub Jung, Soochahn Lee, Yong Seok Heo, and Il Dong Yun. Random tree walk toward instantaneous 3d human pose estimation
52016Joao Carreira, Pulkit Agrawal, Katerina Fragkiadaki, and Jitendra Malik. Human pose estimation with iterative error feedback
202016Albert Haque, Boya Peng, Zelun Luo, Alexandre Alahi, Serena Yeung, and Li Fei-Fei. Towards viewpoint invariant 3d human pose estimation
412018Keze Wang, Liang Lin, Chuangjie Ren, Wei Zhang, and Wenxiu Sun. Convolutional memory blocks for depth data representation learning
182017Hengkai Guo, Guijin Wang, Xinghao Chen, and Cairong Zhang. Towards good practices for deep 3d hand pose estimation
262018Gyeongsik Moon, Ju Yong Chang, and Kyoung Mu Lee.V2V-PoseNet: Voxel-to-voxel prediction network for accurate 3d hand and human pose estimation from a single depth map
2.4.4.3 K2HPD Body Pose数据集对比测试
  • 2D深度学习数据集
  • Ground Truth:像素级的平面坐标
  • 网络:删除了深度估计分支
    在这里插入图片描述
索引号时间名称
22016Adrian Bulat and Georgios Tzimiropoulos. Human pose estimation via convolutional part heatmap regression
432016Shih-En Wei, Varun Ramakrishna, Takeo Kanade, and Yaser Sheikh.Convolutional pose machines
272016Alejandro Newell, Kaiyu Yang, and Jia Deng. Stacked hourglass networks for human pose estimation
422016Keze Wang, Shengfu Zhai, Hui Cheng, Xiaodan Liang, andLiang Lin. Human pose estimation from depth images via inference embedded multi-task learning
412018Keze Wang, Liang Lin, Chuangjie Ren, Wei Zhang, and Wenxiu Sun. Convolutional memory blocks for depth data representation learning

2.5 关键代码实现

2.5.1 生成Anchor模板

  • 在16x16的区域中生成16个Anchors
  • stride = 4
  • 示例代码
"""In 16x16 area, set 16 anchors coordinate with stride = 4"""
""" output shape (16,2) value: [[2,2], [2,6], [2,10], [2,14], ..., [14, 10], [14,14]]  """
def generate_anchors(P_h=None, P_w=None):
    if P_h is None:
        P_h = np.array([2,6,10,14])

    if P_w is None:
        P_w = np.array([2,6,10,14])

    num_anchors = len(P_h) * len(P_h)
    #print("num_anchors=", num_anchors)

    # initialize output anchors
    anchors = np.zeros((num_anchors, 2))
    k = 0
    for i in range(len(P_w)):
        for j in range(len(P_h)):
            anchors[k,1] = P_w[j]
            anchors[k,0] = P_h[i]
            k += 1  
    #print("anchors=\n", anchors)   
    #print("anchors.shape=", anchors.shape)
    return anchors   # anchors.shape=(16,2)      
  • 输出Anchors图像
    在这里插入图片描述

2.5.2 在整图中生成Anchors

  • 在288x288的全图中,复制Anchor模板 (18x18)次
  • stride=4
  • 示例代码
"""
  copy the input anchor to each 16x16 area  
  calcaulte the coordinate of all the anchors 
  extend the anchors in area 16x16 to all the image
  input parameters: shift:shape=[18, 18], stride=16, anchors=(16,2)
  output: ((5184, 2))  5184=72x72
  all_anchors[:32,:]= [[ 2.  2.] [ 2.  6.] [ 2. 10.] [ 2. 14.] 
                       [ 6.  2.] [ 6.  6.] [ 6. 10.] [ 6. 14.]
                       [10.  2.] [10.  6.] [10. 10.] [10. 14.]
                       [14.  2.] [14.  6.] [14. 10.] [14. 14.]
                       
                       [18.  2.] [18.  6.] [18. 10.] [18. 14.]
                       [22.  2.] [22.  6.] [22. 10.] [22. 14.]
                       [26.  2.] [26.  6.] [26. 10.] [26. 14.]
                       [30.  2.] [30.  6.] [30. 10.] [30. 14.]]
"""
def shift(shape, stride, anchors):
    ## calculate the start coordinate of each 16x16 area
    shift_h = np.arange(0, shape[0]) * stride  # shape=(18,) [0, 16, 32, ..., 272]
    shift_w = np.arange(0, shape[1]) * stride  # shape=(18,) [0, 16, 32, ..., 272]

    shift_h, shift_w = np.meshgrid(shift_h, shift_w)
    ## shift_h.shape=(18, 18) each row: [0  16  32  48  64  80  96 112 128 144 160 176 192 208 224 240 256 272]
    ## shift_w.shape=(18, 18) each col: [0  16  32  48  64  80  96 112 128 144 160 176 192 208 224 240 256 272]
    ## print("afer mesgrid: shift_h.shape={}, shift_w.shape={}".format(shift_h.shape, shift_w.shape)) # (18,18)
    ## print("shift_h={}, shift_w={}".format(shift_h, shift_w))
    
    ## shift_h.ravel().shape= (324,) tranfer to 1 dimension, and by row order
    shifts = np.vstack((shift_h.ravel(), shift_w.ravel())).transpose() 
    ## shifts.shape= (324, 2), shifts= [[  0   0],[ 16   0], ..., [272,0], [0,16], ..., [272,16], ..., [272,272]]

    # add A anchors (1, A, 2) to
    # cell K shifts (K, 1, 2) to get
    # shift anchors (K, A, 2)
    # reshape to (K*A, 4) shifted anchors
    A = anchors.shape[0]  # A=16, anchors.shape=(16, 2)
    K = shifts.shape[0]   # K=324, shifts.shape=(324, 2)

    ## 2D update to 3D
    ## anchors.reshape((1, A, 2)).shape= (1, 16, 2)    
    ## shifts.reshape((1, K, 2)).shape=(1, 324, 2)
    ## shifts.reshape((1, K, 2)).transpose((1, 0, 2)).shape= (324, 1, 2)
    all_anchors = (anchors.reshape((1, A, 2)) + shifts.reshape((1, K, 2)).transpose((1, 0, 2)))
    ## all_anchors.shape= (324, 16, 2)
    
    all_anchors = all_anchors.reshape((K * A, 2))
    ## all_anchors.shape= (5184, 2)
    return all_anchors
  • 输出Anchors图像

在这里插入图片描述

参考资料

  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值