Point Pair Feature 原理及代码详解 OpenCV-PCL详解系列(一、原理解析)

Model Globally, Match Locally: Efficient and Robust 3D Object Recognition

全局建模,局部匹配:高效鲁棒的三维物体识别

省略介绍及相关叙述,直奔主题。

目标工作:点云目标识别,在给定场景中识别到模型点云

方法:采用PointPairFeature(点对特征)进行特征描述,采用投票思想确定物体位姿,运用聚类及平均值的方式来消减误差

PointPairFeature点对特征原理:

点对特征相对好理解,对于含有N个点的Model表面任意的点对 ( m i , m j ) , ( i = 1... n . . . N , j = 1... n . . . N ) \left(\mathbf{m}_i, \mathbf{m}_j\right),\left(\mathbf{i}=1...n...N, \mathbf{j}=1...n...N\right) (mi,mj)(i=1...n...N,j=1...n...N),共计 N ∗ ( N − 1 ) N*(N-1) N(N1)个点对。以Model上的一点对 ( m 1 , m 2 ) \left(\mathbf{m}_1, \mathbf{m}_2\right) (m1,m2),其PPF特征可由下公式表示:
F ( m 1 , m 2 ) = ( ∥ d ∥ 2 , ∠ ( n 1 , d ) , ∠ ( n 2 , d ) , ∠ ( n 1 , n 2 ) ) \mathbf{F}\left(\mathbf{m}_1, \mathbf{m}_2\right)=\left(\|\mathbf{d}\|_2, \angle\left(\mathbf{n}_1, \mathbf{d}\right), \angle\left(\mathbf{n}_2, \mathbf{d}\right), \angle\left(\mathbf{n}_1, \mathbf{n}_2\right)\right) F(m1,m2)=(d2,(n1,d),(n2,d),(n1,n2))一个点对特征由两点之间的距离、两点的法向Normal夹角,以及两点法线与两点连线的夹角。

点对特征
在OpenCV的拓展模块和PCL中均有对应的实现,OpenCV相对较坑,对于模型的保存及读取仅保留了对应的接口,并未进行实现,PCL也并未找到相关的模型保存及读取的接口(有找到的可以分享一下哈)
OpenCV代码位置:https://github.com/opencv/opencv_contrib/blob/4.x/modules/surface_matching/src/ppf_match_3d.cpp
PCL代码位置:https://github.com/PointCloudLibrary/pcl/blob/master/features/src/ppf.cpp

//OpenCV中计算PPF代码 ppf_match_3d.cpp 167-180行
void PPF3DDetector::computePPFFeatures(const Vec3d& p1, const Vec3d& n1,
                                       const Vec3d& p2, const Vec3d& n2,
                                       Vec4d& f)
{
  Vec3d d(p2 - p1);
  f[3] = cv::norm(d);
  if (f[3] <= EPS)
    return;
  d *= 1.0 / f[3];

  f[0] = TAngle3Normalized(n1, d);
  f[1] = TAngle3Normalized(n2, d);
  f[2] = TAngle3Normalized(n1, n2);
}

//对OpenCV中Train Model过程中对采样后的模型,逐一计算PPF特征 对源码进行部分删减
void PPF3DDetector::trainModel(const Mat &PC)
{
  for (int i=0; i<numRefPoints; i++)
  {
    const Vec3f p1(sampled.ptr<float>(i));
    const Vec3f n1(sampled.ptr<float>(i) + 3);
    for (int j=0; j<numRefPoints; j++)
    {
      // cannot compute the ppf with myself
      if (i!=j)
      {
        const Vec3f p2(sampled.ptr<float>(j));
        const Vec3f n2(sampled.ptr<float>(j) + 3);
        Vec4d f = Vec4d::all(0);
        computePPFFeatures(p1, n1, p2, n2, f);
      }
    }
  }
}

PCL代码:

bool
pcl::computePPFPairFeature (const Eigen::Vector4f &p1, const Eigen::Vector4f &n1,
                            const Eigen::Vector4f &p2, const Eigen::Vector4f &n2,
                            float &f1, float &f2, float &f3, float &f4)
{
  Eigen::Vector4f delta = p2 - p1;
  delta[3] = 0.0f;
  // f4 = ||delta||
  f4 = delta.norm ();

  delta /= f4;

  // f1 = n1 dot delta
  f1 = n1[0] * delta[0] + n1[1] * delta[1] + n1[2] * delta[2];
  // f2 = n2 dot delta
  f2 = n2[0] * delta[0] + n2[1] * delta[1] + n2[2] * delta[2];
  // f3 = n1 dot n2
  f3 = n1[0] * n2[0] + n1[1] * n2[1] + n1[2] * n2[2];

  return (true);
}

在看完代码后,相信对这个特征提取的流程已经十分熟悉,进行下一步骤。
对于模型表面的相似特征点对 ( m 1 , m 2 ) \left(\mathbf{m}_1, \mathbf{m}_2\right) (m1,m2) ( m 3 , m 4 ) \left(\mathbf{m}_3, \mathbf{m}_4\right) (m3,m4) ( m 5 , m 6 ) \left(\mathbf{m}_5, \mathbf{m}_6\right) (m5,m6),他们在构建HashTable的过程要投影到同一个位置,避免细小的差异便区别相似特征,采用 d a n g l e A n g l e S t e p \mathbf{d}_{angle}AngleStep dangleAngleStep d d i s t a n c e D i s t a n c e S t e p \mathbf{d}_{distance}DistanceStep ddistanceDistanceStep对PPF特征中的角度和距离进行区间划分,这样,相似的特征在投票的过程便可以落到相同的区域。
在这里插入图片描述

//OpenCV中对应代码 AngleStep DistanceStep
static KeyType hashPPF(const Vec4d& f, const double AngleStep, const double DistanceStep)
{
  Vec4i key(
      (int)(f[0] / AngleStep),
      (int)(f[1] / AngleStep),
      (int)(f[2] / AngleStep),
      (int)(f[3] / DistanceStep));
  KeyType hashKey[2] = {0, 0};  // hashMurmurx64() fills two values

  murmurHash(key.val, 4*sizeof(int), 42, &hashKey[0]);
  return hashKey[0];
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值