PPF 3D模型匹配OpenCV C ++

时间:2016-04-21 17:23:49

标签: c++ opencv 3d computer-vision mesh


我正在开发一个应用程序:

  1. 读取7个模型文件并训练PPF 3D探测器;
  2. 读取场景文件并尝试与探测器匹配;
  3. 将结果存储在文件中(可视化检索)。
  4. 我关注的是OpenCV tutorial ,但有些事情我甚至不懂“{3}}:

    1. detector.match()结果上存储场景中模型的姿势。但据我了解,姿势是模型的位置和方向,但我怎么知道哪种模型?
    2. 当我打印第一个结果的姿势时,它会给我一个4x4表,上面有浮动值。我在哪里可以找到他们的意思?
    3. 仍然在姿势打印上,它给了我模型索引,起初,我认为那是我用来训练探测器的模型的数量。问题是:我使用了7个模型来训练探测器,第一个结果给了我"姿势到模型索引12" 。所以我认为它是documentation(2012)上的模型描述索引。但如果确实是模型描述索引,我怎么知道这个索引属于哪个模型?
    4. 根据教程,使用 transformPCPose 并将其写入PLY文件会给出匹配的直观结果,但 Drost表示它返回4x4姿势矩阵,但是我仍在打印它,它给了我一个超过16个顶点的奇怪图像,所以我不明白教程正在做什么。如何在教程中编写可视化结果?
    5. 我还读到ICP用于纠正任何姿势误差,但使用不带ICP的PPF可以得到可接受的结果。无论如何,我试图使用ICP,但它总是给我" Bad参数错误"。

      我使用的代码如下:

      void computer_vision_3d(string in_path)
      {
          Mat files_clouds[NUM_OF_FILES];                                 // > Stores the point cloud of all objects
          Mat scene_cloud;                                                // > Stores the scene point cloud
          ppf_match_3d::PPF3DDetector 
              detector(RELATIVE_SAMPLING_STEP, RELATIVE_DISTANCE_STEP);   // > Matches the model with the scene
          vector<Pose3DPtr> results;                                      // > Stores the results of the processing
      
              // ! Phase 1 - Train Model
          scene_cloud = loadPLYSimple(DEFAULT_SCENE_PATH.c_str(), PARAM_NORMALS);
          for(int i = 0; i < NUM_OF_FILES; i++)
          {   
                  // . Init Point Cloud
              string file_path = DEFAULT_OBJECT_PATH + to_string(i) + ".ply";
              files_clouds[i] = loadPLYSimple(file_path.c_str(), PARAM_NORMALS);
      
                  // . Train Model
              detector.trainModel(files_clouds[i]);
          }
      
              // ! Phase 2 - Detect from scene
          detector.match( scene_cloud, results, 
                      RELATIVE_SCENE_SAMPLE_STEP, RELATIVE_SCENE_DISTANCE);
      
              // ! Phase 3 - Results
          if(results.size() > 0)
          {
              Pose3DPtr result = results[0];
              result->printPose();
      
                  // ! Transforms the point cloud to the model pose
              for(int i = 0; i < NUM_OF_FILES; i++)
              {
                  Mat pct = transformPCPose(files_clouds[i], result->pose);
                  string f_name = "match" + to_string(i) + ".ply";
                  writePLY(pct, f_name.c_str());
              }
          }
      
      }
      

      其中一个模特,场景和结果:

      Figure 1 One of the seven models
      图1 - 七种型号中的一种。


      Figure 2 The scene
      图2 - 场景。


      Figure 3 The weird result
      图3 - 奇怪的结果。


1 个答案:

答案 0 :(得分:4)

作为该模块的作者,我想解答您的问题:

1。 detector.match()在结果上存储模型在场景上的姿势。但据我了解,姿势是模型的位置和方向,但我怎么知道哪个模型是什么?

只有一个型号。所以姿势是针对同一模型的不同假设

2。当我打印出第一个结果的姿势时,它会给我一个4x4表,上面有浮动值。我在哪里可以找到他们的意思?

它是[R | t]的增广矩阵,额外的行[0,0,0,1]可以均匀化。

3。仍然在姿势打印,它给我模型索引,起初,我认为这是我用来训练探测器的模型的数量。问题是:我使用了7个模型来训练探测器,第一个结果给了我“姿势到模型索引12”。所以我认为这是模型描述索引,因为它在Drost(2012)上。但如果确实是模型描述索引,我怎么知道这个索引属于哪个模型?

匹配模型点(对应关系)的ID而不是模型ID。正如我所说,不支持多种模型。

3。根据教程,使用transformPCPose并将其写入PLY文件将给出匹配的可视结果,但文档说它返回一个4x4姿势矩阵,但我仍然打印它,它给了我一个奇怪的图像与更多超过16个顶点,所以我不明白教程在做什么。如何在教程中编写可视化结果?

该函数使用给定姿势转换点云。如果您的姿势正确,它只会给出正确的结果。我不认为你的实施的姿势结果是正确的。 ICP中的“坏论证”例外也可能是因为这一点。

还有一点需要注意:始终确保模型和场景具有正确朝向相机的曲面法线。