【问题标题】:PPF 3D Models Matching OpenCV C++匹配 OpenCV C++ 的 PPF 3D 模型
【发布时间】:2016-08-15 01:34:09
【问题描述】:


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

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

我一直在关注OpenCV tutorial ,但有几件事我连看documentation都看不懂:

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

我还读到 ICP 用于纠正任何姿势错误,但使用不带 ICP 的 PPF 可以得到可接受的结果。无论如何,我尝试使用 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 - 奇怪的结果。


【问题讨论】:

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


    【解决方案1】:

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

    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”异常也可能是因为这个。

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

    【讨论】:

    • 谢谢!当我问这个问题的时候我对计算机视觉不是很了解,现在我明白了一点,我发现我做错了很多事情......
    • 你能扩展一下“正确朝向相机”吗?我看到您在计算法线之前设置了视点(在计算法线的示例代码中),但是表面法线与相机视点有什么关系?
    • 好问题。检查“理论入门”部分的结尾:pointclouds.org/documentation/tutorials/normal_estimation.php
    • 好的,明白了,问题是法线是否确实是从对象向外定向的,对吧?我有使用 CloudCompare 采样的 CAD 模型(以及一些更进一步的手动魔术来获得可用模型,例如移除隐藏的东西),并且我直接从 STL 网格获得法线。在这种情况下,不需要任何观点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多