SLAM从入门到放弃:SLAM十四讲第八章习题(1-3)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012348774/article/details/83900057

以下均为简单笔记,如有错误,请多多指教。

  1. 除了LK光流之外,还有哪些光流方法?它们各有什么特点?
    答:此答案转载于:https://blog.csdn.net/iloveayu/article/details/76728412。
    Barron等人对多种光流计算技术进行了总结,按照理论基础与数学方法的区别把它们分成四种:基于梯度的方法、基于匹配的方法、基于能量的方法、基于相位的方法。当然除了这些方法之外,现在也有非常多基于深度学习的方法,例如flownet
    1、基于梯度的方法
    基于梯度的方法又称为微分法,它是利用时变图像灰度(或其滤波形式)的时空微分(即时空梯度函数)来计算像素的速度矢量。由于计算简单和较好的结果,该方法得到了广泛应用和研究。典型的代表是Horn-Schunck的光流计算方法,该方法在光流基本约束方程的基础上附加了全局平滑假设,从而计算出光流场。基于此思想,大量的改进算法不断提出。Nagel采用有条件的平滑约束,即通过加权矩阵的控制对梯度进行不同平滑处理;Black和Anandan针对多运动的估计问题,提出了分段平滑的方法。虽然很多基于梯度的光流估计方法取得了较好的光流估计,但由于在计算光流时涉及到可调参数的人工选取、可靠性评价因子的选择困难,以及预处理对光流计算结果的影响,在应用光流对目标进行实时检测与自动跟踪时仍存在很多问题。
    2、基于匹配的方法
    基于匹配的光流计算方法包括基于特征和区域的两种。基于特征的方法不断地对目标主要特征进行定位和跟踪,对目标大的运动和亮度变化具有鲁棒性(robustness)。存在的问题是光流通常很稀疏,而且特征提取和精确匹配也十分困难。基于区域的方法先对类似的区域进行定位,然后通过相似区域的位移计算光流。这种方法在视频编码中得到了广泛的应用。然而,它计算的光流仍不稠密。另外,这两种方法估计亚像素精度的光流也有困难,计算量很大。在考虑光流精度和稠密性时,基于匹配的方法适用。
    3、基于能量的方法
    基于能量的方法首先要对输入图像序列进行时空滤波处理,这是一种时间和空间整合。对于均匀的流场,要获得正确的速度估计,这种时空整合是非常必要的。然而,这样做会降低光流估计的空间和时间分辨率。尤其是当时空整合区域包含几个运动成分(如运动边缘)时,估计精度将会恶化。此外,基于能量的光流技术还存在高计算负荷的问题。此方法涉及大量的滤波器,目前这些滤波器是主要的计算消费。然而,可以预期,随着相应硬件的发展,在不久的将来,滤波将不再是一个严重的限制因素,所有这些技术都可以在帧速下加以实现。
    4、基于相位的方法
    Fleet和Jepson首次从概念上提出了相位信息用于光流计算的问题。因为速度是根据带通滤波器输出的相位特性确定的,所以称为相位方法。他们根据与带通速度调谐滤波器输出中的等相位轮廓相垂直的瞬时运动来定义分速度。带通滤波器按照尺度、速度和定向来分离输入信号。
    基于相位的光流技术的综合性能是比较好的:速度估计比较精确且具有较高的空间分辨率,对图像序列的适用范围也比较宽。同时,这里仍有几个问题值得讨论:
    (1)与基于能量的光流技术一样,基于相位的模型既有一定的生物合理性,又有较高的计算复杂性;
    (2)尽管相位技术用两帧图像就可计算光流,但要获得足够的估计精度,就必须有一定的整合时间,这个延迟将会降低边缘处运动估计的时间分辨率;
    (3)Fleet和Jespon的方法对输入图像序列中的时间混叠比较敏感。
  1. 在本节程序的求图像梯度过程中,我们简单地求了 u + 1 u+1 u 1 u-1 的灰度之差除以 2 2 ,作为 u u 方向上的梯度值。这种做法有什么缺点?提示:对于距离较近的特征,变化应该较快;而距离较远的特征在图像中变化较慢,求梯度时能否利用此信息?
    答:个人看法,可能不是很完整。缺点主要有两个。第一个就如提示所示,距离较近的特征运动较快,不是十分符合光流中运动较小的假设,可能会使得光流跟踪失败;第二个问题就是,在图像的采集过程中必然存在噪声等等影响,简单的相减必然有大量的噪声,也会对光流产生干扰。

  2. 在稀疏直接法中,假设单个像素周围小块的光度也不变,是否可以提高算法健壮性?请编程实现。
    答:参照https://www.cnblogs.com/newneul/p/8571653.html的思路,如果假设周围小块的光度也不变,可以利用一个像素块的灰度值来代替当前一个像素的灰度值。整体而言代码的改变不大,主要是在ComputeError()中残差项的计算换成一个基于像素块的残差计算。

float sumValue = 0.0;
for(int i = x-PATCH_RADIUS ; i<= x+PATCH_RADIUS ; ++i)
{  
  for (int j = y-PATCH_RADIUS; j <= y+PATCH_RADIUS ; ++j)
  {
     sumValue += getPixelValue(i,j);
  }
}
sumValue /=( (2*PATCH_RADIUS +1)*(2*PATCH_RADIUS+1) );  //求得元素周围小块的平均灰度值
_error (0,0) = sumValue - _measurement;

不过感觉纯粹的求取平均值并不是特别合理,个人感觉比较合理方法是进行高斯加权,一般情况下这样会更加鲁邦。

float sigma;
float sumValue = 0.0;
float sumGauss = 0.0;
for(int i = x-PATCH_RADIUS ; i<= x+PATCH_RADIUS ; ++i)
{  
  for (int j = y-PATCH_RADIUS; j <= y+PATCH_RADIUS ; ++j)
  {
     float gaussValue = exp(-(i*i+j*j)/(2*sigma*sigma))/(2*3.1415926*sigma*sigma);
     sumValue += getPixelValue(i,j)*gaussValue ;
     sumGauss += gaussValue;
  }
}
sumValue /= sumGauss;
_error (0,0) = sumValue - _measurement;

猜你喜欢

转载自blog.csdn.net/u012348774/article/details/83900057
今日推荐