匹配 OpenCV C++ 的 PPF 3D 模型

PPF 3D Models Matching OpenCV C++


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

  1. 读取 7 个模型文件并训练 PPF 3D 检测器;
  2. 读取一个场景文件并尝试与检测器匹配;
  3. 将结果存储在文件中(视觉检索)。
我正在关注 OpenCV tutorial , but there are a few things that I didn't understand even reading the documentation
  1. detector.match() 存储在 结果 姿势 模特在现场。但是据我了解,一个pose就是模型的位置和方向,但是我怎么知道是哪个模型呢?
  2. 当我打印第一个结果的姿势时,它给了我一个带有浮点值的 4x4 table。我在哪里可以找到它们的含义?
  3. 仍在姿势打印时,它给了我 模型索引 ,起初,我以为那是我用来训练检测器的模型的编号。问题是:我使用了 7 个模型来训练检测器,第一个结果给了我 "Pose to Model Index 12"。所以我认为这是 Drost(2012) 上的模型描述索引。但是如果真的是Model Description Index,我怎么知道这个索引属于哪个Model呢?
  4. 根据教程,使用 transformPCPose 并将其写入 PLY 文件将给出匹配的视觉结果,但是 documentation 说它 returns 一个 4x4 姿势矩阵,但我仍在打印它,它给了我一个超过 16 个顶点的奇怪图像,所以我不明白教程在做什么。我怎样才能像教程那样在文件上写下视觉结果?

我还读到 ICP 用于纠正任何姿势错误,但是使用没有 ICP 的 PPF 会得到 acceptable 结果。无论如何,我尝试使用 ICP,但它总是给我“Bad argument error”。

我使用的代码如下:

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());
        }
    }

}

其中一个模型、场景和结果:


图 1 - 七个模型之一。



图2-场景.



图 3 - 奇怪的结果。


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

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

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

2。当我打印第一个结果的姿势时,它给了我一个带有浮点值的 4x4 table。我在哪里可以找到它们的含义?

是[R|t]的增广矩阵,多出[0,0,0,1]行进行均化。

3。仍然是姿势打印,它给了我模型索引,起初,我以为那是我用来训练检测器的模型的编号。问题是:我用了 7 个模型来训练检测器,第一个结果给了我 "Pose to Model Index 12"。所以我认为这是 Drost(2012) 上的模型描述索引。但是如果真的是Model Description Index,我怎么知道这个index是属于哪个Model呢?

是匹配模型点(对应)的ID,不是模型id。正如我所说,不支持多个模型。

3。根据教程,使用 transformPCPose 并将其写入 PLY 文件会给出匹配的视觉结果,但文档说它 returns 一个 4x4 姿势矩阵,但我仍在打印它,它给了我一个超过 16 个顶点的奇怪图像,所以我不明白教程在做什么。我怎样才能像教程那样把视觉结果写在文件上?

该函数转换具有给定姿势的点云。如果您的姿势正确,它只会给出正确的结果。我认为您实施的 pose 结果不正确。 ICP中的"Bad argument"例外也可能是因为这个。

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