连接OpenCV Mat和单个值

时间:2017-05-29 10:49:06

标签: c++ opencv concatenation mat

我正在使用OpenCV 3.2。

假设我有一个3 x 1 Mat:

cv::Mat foo = (cv::Mat_<float>(3,1) << 0, 1, 2);

现在我想将单个值连接到foo,然后生成4 x 1 Mat。

一个简单的解决方案是:

cv::Mat bar = (cv::Mat_<float>(4,1) << foo.at<float>(0,0),
                                       foo.at<float>(1,0),
                                       foo.at<float>(2,0),
                                       3);

但是这个解决方案会过度解决问题维度。当然,我可以通过循环n x 1 Mat的所有值来推广它,从而产生n+1 x 1

我正在寻找的是一个更智能的解决方案,它利用OpenCV语法,并直接返回单列Mat和单个值的串联。

1 个答案:

答案 0 :(得分:2)

你很幸运。 cv::Mat提供

成员函数push_back
  

将元素添加到矩阵的底部

此外,

  

方法将一个或多个元素添加到矩阵的底部。它们模拟STL向量类的相应方法。 ...

由于您的Mat只有一列,您只需添加标量值,您只需确保该类型与Mat的数据类型匹配即可。在这种情况下,您可以直接添加float,但在添加之前,您需要明确地添加float

如果您的Mat有一行,并且想要添加一列,则会更复杂一些。您需要在push_back之前和之后使用reshape。但是,引用文档

  

不会复制任何数据。也就是说,这是O(1)操作。

如果你需要经常这样做,那么将它包装在内联函数中是微不足道的。

实施例

#include <iostream>
#include <opencv2/opencv.hpp>

int main()
{
    // Adding rows

    cv::Mat foo = (cv::Mat_<float>(3, 1) << 0, 1, 2);
    std::cout << foo << "\n";

    foo.push_back(3.0f);
    std::cout << foo << "\n";

    foo.push_back(static_cast<float>(4)); // Need to make sure the type matches!
    std::cout << foo << "\n";

    // -----

    // Adding columns

    cv::Mat bar = (cv::Mat_<float>(1, 3) << 0, 1, 2);
    std::cout << bar << "\n";

    // push_back needs to add a full row so reshapes are needed (but cheap)
    bar = bar.reshape(1, bar.cols);
    bar.push_back(3.0f);
    bar = bar.reshape(bar.rows);
    std::cout << bar << "\n";

    return 0;
}

控制台输出

[0;
 1;
 2]
[0;
 1;
 2;
 3]
[0;
 1;
 2;
 3;
 4]
[0, 1, 2]
[0, 1, 2, 3]