6Dpose估计的微调,让结果更精准
没讲,此处写一下借鉴的方法:
用输入的poes生成render图片和render mask图片,结合observed图片和obserbed mask图片输入到网络中,生成pose偏差,用这个偏差修改pose后再输入到网络中,再生成一个pose偏差,再修正输入,即得到最后微调的结果
很小的图片很难获取好的特征,所以要调高observed图片的分辨率。
根据输入的pose可以生成rendered图像和rendered mask,observed图像就是检测出来的bbox,根据这个也可以生成一个mask(要注意一点,得到这个ovserved mask之后要随机扩大十个元素,这样可以避免过拟合),然后将这四张图中的物体、mask截取出来,截取的时候要保证两个条件:
之后放大并线性插值到原图的大小(作者的是 480 × 640 480 \times 640 480×640)
缩放到原图大小就相当于让摄像机的中心发生了位移
我的理解是obserced和rendered用的是同一个中心,也就是model原点射影的中心,然后截取面积的时候按照跟原图一样的截取,长宽都要比observed图片的bbox大一些
找到一个合适的表达方式,既能得到好的效果,又能处理没见过的物体
先在 a Naive 坐标系下考虑:
假设当前的pose为 [ R s r c ∣ t s r c ] [R_{src}|t_{src}] [Rsrc∣tsrc],与真实值 [ R t g t ∣ t t g t ] [R_{tgt}|t_{tgt}] [Rtgt∣ttgt]之间的相对差值为 [ R Δ ∣ t Δ ] [R_{\Delta}|t_{\Delta}] [RΔ∣tΔ],则真实值为:
R t g t = R Δ R s r c , t t g t = R Δ t s r c + t Δ R_{tgt} = R_{\Delta}R_{src},\ \ t_{tgt} = R_{\Delta}t_{src} + t_{\Delta} Rtgt=RΔRsrc, ttgt=RΔtsrc+tΔ
R Δ t s r c R_{\Delta}t_{src} RΔtsrc表示旋转的差值,它不仅会对旋转产生影响,还会对位移产生影响
转动之后位置就变了,原本两个点之间的相对位置也变了,所以无法在不知旋转差值的情况下知道 t Δ t_{\Delta} tΔ
t t t是3D坐标系的,图中的对象的实际大小和图中的移动距离是相关,因此,如果想把图中的误匹配转换成位移偏移,那么就需要知道物体的实际大小,这样的话训练起来比较困难,而且没法对没见过的物体的进行预测
因为物体图像已经放大了,所以每次的像素都代表不同的空间大小,所以如果想用网络来预测3D空间偏差,那么必须每次都知道物体的实际大小,不同的物体经过不同的缩放,无法直接从剪切的图得到3D空间的偏移
或许可以在预测上下手?预测像素度量上的偏差?
哈哈哈哈哈哈哈哈哈,猜对了
所以此时得到初步结论:要做去耦操作,分开预测RT,R是不受缩放影响的,再想办法让T不受R影响
将旋转的中心从摄像机的原点移动到摄像机坐标系下的物体的中心,由当前的位姿来估计差值,这样旋转就不会影响位移了
是的
现在原点移动过去了,剩下坐标轴还没有确定,如何选择坐标轴?
不能选 b Model , b Model 的坐标轴是根据物体选择的,这样的话又面临提前知道每个物体的坐标轴的问题了,难点如上,所以最后选择建立跟摄像机坐标系平行的坐标轴 c Camera
设真实值和输入值分别为 t t g t = ( x t g t , y t g t , z t g t ) , t s r c = ( x s r c , y s r c , z s r c ) t_{tgt}=(x_{tgt},y_{tgt},z_{tgt}),t_{src}=(x_{src},y_{src},z_{src}) ttgt=(xtgt,ytgt,ztgt),tsrc=(xsrc,ysrc,zsrc),两点间直线距离 t Δ = ( Δ x , Δ y , Δ z ) = t t g t − t s r c t_{\Delta} = (\Delta_x,\Delta_y,\Delta_z) = t_{tgt} - t_{src} tΔ=(Δx,Δy,Δz)=ttgt−tsrc
但是还是扯到了度量的问题,在不知道真实尺度的情况下,依然不能直接从图中获取 t Δ t_{\Delta} tΔ,所以改成在像素上回归:
t Δ = ( v x , v y , v z ) t_{\Delta} = (v_x,v_y,v_z) tΔ=(vx,vy,vz)
其中 v x , v y v_x,v_y vx,vy表示物体应该沿着 x , y x,y x,y轴移动的像素数量, v z v_z vz是物体的尺度改变:
v x = f x ( x t g t / z t g t − x s r c / z s r c ) v y = f y ( y t g t / z t g t − y s r c / z s r c ) v z = l o g ( z s r c / z t g t ) v_x = f_x(x_{tgt} / z_{tgt} - x_{src} / z_{src}) \\ v_y = f_y(y_{tgt} / z_{tgt} - y_{src} / z_{src}) \\ v_z = log(z_{src} / z_{tgt}) vx=fx(xtgt/ztgt−xsrc/zsrc)vy=fy(ytgt/ztgt−ysrc/zsrc)vz=log(zsrc/ztgt)
其中 v x , v y v_x,v_y vx,vy很好理解,是到像素平面的转换
缩放变化 v z v_z vz被定义成比例,这样就跟物体的实际大小没有关系了,只与rendered距离和observed距离的比例有关,用对数处理,使当没有比例变化的时候,值为0
因为 f x , f y f_x,f_y fx,fy在特定的数据集里都是固定的,所以这里可以设为1
学到了
使用的 LINEMOD 数据集,里面有15个物体,13个用于训练。
所以每个物体共有12000个训练样本
observed图片和rendered图片,以及对应的两个mask组成一个八通道的tensor,输入到网络中
backbone:
使用的FlowNetSimple作为backbone来计算两个图片之间的光流
光流是啥,视频分析好像有,直接换成注意力机制不知可行不
作者还是了用VGG16来做backbone,发现效果很垃圾,然后有个直觉就是与光流相关的表示对于位姿匹配非常有用
或许要看看光流了
Flownet: Learning optical flow with convolutional networks 2015年的论文
直接看看最近还有没有搞光流的
位姿估计分支:
使用FNS的11层之后的特征作为输入,包含两个全连接层,每个的维度是256,然后接上两个额外的全连接层来预测3D旋转的四元数和3D位移
辅助分支:
训练的时候,还添加两个辅助分支,来规范化网络的特征表示,虽然没有让结果变得更好,但是增加了训练的稳定性。
稳定是指loss的变化吧,为什么?
在这个特征图后面的两个1x1卷积,分别是1通道(mask)和2通道(光流),然后用双线性差值的上采样方法还原到原图大小 ( 480 × 640 ) (480\times 640) (480×640)来计算loss
观测到的才是真实的,必然要让预测的mask很准,现在的mask已经挺准的了,那么用预测出来的rt生成mask,再利用分割网络预测出的mask,来做微调?
其他的方法是用mask来预测原来的位置,但用mask和model是得不到rt信息的,那么作者要如何根据render的mask和预测出来的mask来微调呢?
光流又有什么用呢?
mask有啥用呢?
到最后也没说有啥用,或许网络在做这个的反向传播的时候,增强了学习更细节的物体划分的能力,有利于pose估计?
初始化:
新的层的权重都是随机初始化的,除了用来处理输入的mask的卷积层和预测位移的全连接层,这两个是用0初始化
学习率:
初始的学习率是0.0001,共训练8个epoch,在epoch为4、6的时候除10
训练:
测试:
根据rendered位置来找
直接点方法就是旋转和位移单独计算,旋转用角距,位移用L2距离,但是分开的话平衡这两个又比较困难。
Geometric loss functions for camera pose regression with deep learning 提出用重投影误差作为损失函数,使用真实的位姿和估计的位姿,计算3D点的2D投影的平均距离
什么样的平均距离?每个点之间?
可以稍微看看这个论文怎么说的
作者改动了一下,命名为Point Matching Loss。
L p o s e ( p , p ^ ) = 1 n ∑ i = 1 n L 1 ( ( R x i + t ) − ( R ^ x i + t ^ ) ) L_{pose}(p,\hat{p}) = \frac{1}{n}\sum^n_{i=1}L_1((Rx_i + t) - (\hat{R}x_i + \hat{t})) Lpose(p,p^)=n1i=1∑nL1((Rxi+t)−(R^xi+t^))
其中 p = [ R ∣ t ] p=[R|t] p=[R∣t]是真实值, p ^ = [ R ^ ∣ t ^ ] \hat{p}=[\hat{R}|\hat{t}] p^=[R^∣t^]是估计值
x i x_i xi是在模型上随机选择的3D点, n n n是选择的点的总数(3000)
这个损失函数函数计算使用真实位姿和估计位姿得到的相机坐标系的点之间的平均 L 1 L_1 L1距离
光流loss是[ Flownet: Learning optical flow with convolutional networks ]中的 L f l o w L_{flow} Lflow
mask的loss是sigmoid 交叉熵loss
L = α L p o s e + β L f l o w + γ L m a s k L = \alpha L_{pose} + \beta L_{flow} + \gamma L_{mask} L=αLpose+βLflow+γLmask
其中 α = 0.1 , β = 0.25 , γ = 0.03 \alpha = 0.1,\beta=0.25,\gamma=0.03 α=0.1,β=0.25,γ=0.03
batch size是16
观测的mask随机扩大十个像素来避免过拟合
怎么扩大?全方位?可能是H or W随机算一个扩大吧
为什么这样能避免过拟合?
扩大之后的mask不仅有object,还有一些背景信息,如果一直只有物体,可能在物体身上发生过拟合,放到别的环境中可能效果很差
6D位姿估计有三个标准:
控制epoch的总数不变为32,迭代一次有32个epoch,迭代两次有16个epoch
结论:
实验证明,训练只迭代一次的话,测试的时候迭代多次也没有提升,甚至会下降;迭代两次和四次都有提升,效果最好的是训练迭代两次,此时测试四次迭代比两次有较小提升。
分析:
作者认为只有训练只迭代一次的效果很差的原因是,网络训练不够,训练2测试2比训练4测试4好不少,这说明网络想要学到微调的能力并不困难,不需要使用3,4次训练迭代。
为什么这个网络的想学习是通过迭代来进行的,epoch次数都一样,为什么对微调过的再微调,网络能学习的更好? 而不再利用网络的输出的情况就不好?
还是说网络一次性能做成的调整有限?比如一开始的差值是8,一次之后差值是6,再迭代一次差值是4,网络只有一次将差距缩小2的能力,而在训练的时候这么做网络才能学会6-4的能力,如果网络不做迭代只能学到8-6的能力,是这样吗?四次迭代结果不能更好,是因为已经很好了,还是网络的上限就是到4了?
但是这样也不能说明在其他数据集上也是这样,所以其他的实验也用的4次训练,4次测试
这点要注意
zoom列表示使用全部图片或者扩大bbox到原图尺寸,5,7行显示提高分辨率有巨大提升
shared:
所有的物体共同一个网络训练,最后生成pose的全连接层也公用
seq:
每种物体都是用独立的全连接
结论:
比较3,7行可以看到效果都不错,但是共享的明显更有效率
做实验的时候是否可以直接套用这个结论?
是不是说明主要的信息在FC256之前就已经确定的差不多了?
其他人的相似操作:
[ A scalable, accurate, robust to partial occlusion method for predicting the 3D poses of challenging objects without using depth ]其中每个对象都单独训练一个网络
结论:
比较1和7,多物体共享一个网络会更好,这也暗示在多种物体上训练能帮助网络学习用来匹配的更一般的表达
那如果用其他的类的训练模型作为预训练,不知会不会好一些?
或许训练数据少的时候可以这么做?
前面说的差不多了,移动中心到物体并建立于camera平行的坐标轴是最好的,而且之后这样能处理没见过的物体
作者的loss在6Dpose上效果很好
在使用这些方法的时候把bbox的中心看成物体的中心,通过最大化三维物体模型投影与边界框的重叠来估计物体的距离。
???难道要不断的试距离?还是说先跟据bbox大小确定个差不多的距离,然后再调整,找iou最大
和 其 他 S O T A 方 法 比 较 和其他SOTA方法比较 和其他SOTA方法比较
红色表示输入的pose,绿色表示微调的pose,图片内容来自[ ModelNet dataset ]
在这个数据集上训练了200个3D模型,然后用剩下的70个没见过的3D模型作为测试
训练的时候给每个模型生成了50张图片,epoch 4 次,发现效果不错
训练测试部分差不多看完了,其中render部分的具体操作还没看,之前没接触过,现在也没条件运行,等回学校再看看
render
update_batch
坐标轴原理