【问题标题】:Conversion of 3x1 or 1x3 cv::Mat to cv::Point3d?将 3x1 或 1x3 cv::Mat 转换为 cv::Point3d?
【发布时间】:2013-09-02 15:37:47
【问题描述】:

我正在处理一些代码,其中执行大量 3x3 矩阵乘法以及使用旋转矩阵等对 3d 点进行一些平移。我决定使用 OpenCV 核心功能进行数学运算。使用最近添加到 cv::Mat 类的构造函数将 cv::Point3d 直接转换为 3x1 cv::Mat 的可能性大大减少并简化了代码。

我现在想知道是否有一种简单的方法可以将 3x1 或 1x3 cv::Mat 转换为 cv::Point3d?我总是可以这样做:

cv::Mat mat(3,1,CV_64FC1);
cv::Point3d p (mat.at<double>(0,0), mat.at<double>(1,0), mat.at<double>(2,0));

cv::Mat mat(3,1,CV_64FC1);
const double *data = mat.ptr<double>(0);
cv::Point3d p (data[0], data[1], data[2]);

我非常担心性能(避免对at 方法的3 次调用)。

【问题讨论】:

    标签: c++ opencv matrix


    【解决方案1】:

    cv::Point3d 有一个构造函数,允许从cv::Mat 直接创建:

    cv::Mat mat(3,1,CV_64FC1);
    cv::Point3d p(mat);
    

    您可能没有考虑过的另一种可能性是使用cv::Matx 而不是cv::Mat 进行数学运算。我发现它更易于使用,并提供更多功能,例如 Point 类型的乘法而不需要转换:

    cv::Point3d p(1,2,3);
    cv::Matx33d m = cv::Matx33d::eye();
    cv::Point3d p2 = m * p;
    

    cv::Matx 也是静态分配的,而不是动态分配的(如 cv::Mat),以防您真的需要额外的一点性能。但是,正如所有与性能相关的建议一样:通过分析确保您正在优化的内容实际上是一个瓶颈。

    【讨论】:

    • 太棒了!我在 opencv core.hpp 头文件中寻找 Point_ 类的构造函数,例如:Point_(const Mat&amp; sz); 因为我没有找到它,所以我认为没有办法做到这一点。此外,我没有注意到Point_(const Vec&lt;_Tp, 2&gt;&amp; v); 的存在,Matx 的使用似乎对我的目的非常有用。非常感谢!
    • 确切地说,Point_&lt;T&gt;/Point3_&lt;T&gt; 没有采用cv::Mat 的构造函数,而是在cv::Mat 中有一个隐含的cast operator 将其转换为其他固定-大小类,如 VecMatxVec 被 Point 构造函数接受)
    • 我想知道为什么我们可以用矩阵转换cv::Point,而不是cv::Vec。在后一种情况下,我们需要先将cv::Vec 转换为cv::Point
    • @MaksymGanenko 这可能是一个疏忽。但是,cv::Vec 类型最常见的用途是多通道图像的元素访问,而不是作为数学结构。
    猜你喜欢
    • 1970-01-01
    • 2017-07-23
    • 2012-12-29
    • 2014-05-07
    • 2011-06-07
    • 2016-04-13
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多