【问题标题】:Mat copyTo from row to col doesn't work! Why?从行到列的 Mat copyTo 不起作用!为什么?
【发布时间】:2014-05-12 16:05:30
【问题描述】:

此答案说明如何将矩阵的一行复制到另一行:How to copy a row of a Mat to another Mat's column in OpenCv? 但是,如果我尝试将矩阵的一行复制到列向量,则程序会突然结束。 示例:

Mat A(640,480,CV_64F);
Mat B(480,1,CV_64F);
A.row(0).copyTo(B.col(0));

一种可能的解决方法是:

Mat A(640,480,CV_64F);
Mat B;
A.row(0).copyTo(B);
B = B.t();

但是如果A 是不同的类型,我如何在B 中输入CV_64F?数据类型是否也被复制?而且 - 最重要的是 - 为什么我需要这个解决方法?

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    copyTo() 函数只能在相同大小(宽度和高度)和相同类型的矩阵之间复制数据。因此,您不能直接使用它将矩阵行复制到矩阵列。通常 OpenCV 会重新分配目标矩阵,使其大小和类型与原始图像匹配,但调用 col() 函数会返回无法重新分配的常量临时对象。结果你的程序崩溃了。

    其实这个问题是可以解决的。您可以将行复制到列(如果它们具有相同数量的元素),并且可以在不同类型的矩阵之间复制数据。 Mat 为其数据提供了一个迭代器,这意味着您可以使用所有与迭代器一起工作的 C++ 函数。以 copy() 函数为例。

    Mat A(640, 480, CV_64F);
    Mat B(480, 1, CV_32S); // note that the type don't have to be the same
    Mat tmp = A.row(0); // no data is copied here. it is needed only because taking iterator to temporary object is really bad idea
    copy(tmp.begin<double>(), tmp.end<double>(), B.begin<int>());
    

    【讨论】:

    • 谢谢。您的解释帮助我理解了 Api。
    【解决方案2】:

    由于 API 不支持如下代码(仅转置行):

    A.row(0).t().copyTo( B.col(0) );
    

    解决方法是从该行创建一个临时矩阵,转置它,然后复制到您的目标矩阵

    Mat temp = A.row(0);
    temp = temp.t();
    temp.copyTo( B.col(0) );
    

    我宁愿做这样的事情:

    Mat A( 640, 480,CV_64F );
    Mat B( 1, 480, CV_64F );  /* rather than 480 x 1, make a 1 x 480 first */
    A.row(0).copyTo( B.row(0) );
    B = B.t(); /* transpose it afterwards */
    

    我认为这只是因为 API 还不支持它。

    【讨论】:

    • 感谢您的回复。帮助了我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多