连接OpenCV的Mat和单个值

3
我将使用OpenCV 3.2进行翻译。
假设我有一个大小为3 x 1的Mat:
cv::Mat foo = (cv::Mat_<float>(3,1) << 0, 1, 2);

现在我想把一个单一的值连接到foo上,然后产生一个结果为4 x 1的矩阵。
一个简单的解决方案是:
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和单个值的连接。

https://dev59.com/wWox5IYBdhLWcg3w_ZR0 - huseyin tugrul buyukisik
@huseyintugrulbuyukisik 我已经看过这篇文章了,但是我不喜欢它,因为你必须将单个值添加到容器中才能使其与“hconcat”方法兼容。我正在寻找一种特定的语法,可以将Mat和单个值连接起来。 - Santiago Gil
1
push_back 是什么意思? - Dan Mašek
1
@DanMašek 你已经完成了工作,请写出来以获得一些分数 :-) - Mark Setchell
@MarkSetchell 好的,虽然我刚刚读了文档。但如果你坚持的话... ;) - Dan Mašek
1个回答

3
你很幸运。cv::Mat 提供了成员函数 push_back,它可以在矩阵底部添加元素。
此外,
方法可以向矩阵底部添加一个或多个元素。它们模拟了STL vector类的相应方法。...
由于你的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]

讲解得非常清晰!而且您还额外添加了列,做得非常用心。 - Mark Setchell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接