PPF 3D 模型匹配 OpenCV C++

Car*_*ile 2 c++ 3d opencv mesh computer-vision


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

  1. 读取 7 个模型文件并训练一个 PPF 3D 检测器;
  2. 读取场景文件并尝试与检测器匹配;
  3. 将结果存储在文件中(视觉检索)。

我正在关注OpenCV 教程,但有一些事情我什至阅读文档都不明白:

  1. detector.match()上存储结果姿势在现场的模型。但据我所知,姿势是模型的位置和方向,但我怎么知道是哪个模型呢?
  2. 当我打印第一个结果的姿势时,它给了我一个 4x4 的表格,上面有浮点值。我在哪里可以找到它们是什么意思?
  3. 仍然在姿势打印上,它给了我模型索引,起初,我认为这是我用来训练检测器的模型的编号。问题是:我使用了 7 个模型来训练检测器,第一个结果给了我"Pose to Model Index 12"。所以我认为这是模型描述索引,就像Drost (2012) 一样。但是如果真的是Model Description Index,我怎么知道这个索引属于哪个Model呢?
  4. 根据教程,使用transformPCPose并将其写入 PLY 文件会给出匹配的视觉结果,但文档说它返回一个 4x4 姿势矩阵,但我仍在打印它,它给了我一个奇怪的图像超过 16 个顶点,所以我不明白教程在做什么。如何像教程一样在文件上编写视觉结果?

我还读到 ICP 用于纠正任何姿势错误,但使用没有 ICP 的 PPF 给出了可接受的结果。无论如何,我尝试使用 ICP,但它总是给我“错误的参数错误”。

我使用的代码如下:

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

}
Run Code Online (Sandbox Code Playgroud)

模型之一,场景和结果:

图1 七种模型之一
图 1 - 七个模型之一。


图2 现场
图 2 - 场景。


图 3 奇怪的结果
图 3 - 奇怪的结果。


Tol*_*dal 5

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

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

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

2. 当我打印第一个结果的姿势时,它给了我一个 4x4 的表格,上面有浮点值。我在哪里可以找到它们是什么意思?

它是 [R|t] 的增广矩阵,带有额外的行 [0,0,0,1] 以进行均质化。

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

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

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

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

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