简体   繁体   English

为什么将cv :: Mat的列复制到向量中会失败?

[英]Why does copying a column of a cv::Mat into a vector fail?

Consider the following code sample. 请考虑以下代码示例。 Why does the line marked below trigger a breakpoint/exception at runtime? 为什么下面标记的行在运行时触发断点/异常?

int main() {
    Mat m1 = Mat::zeros(10, 1, CV_32FC1);
    Mat m2 = Mat::zeros(10, 3, CV_32FC1);

    vector<float> v1(m1); // works
    Mat m2sub = m2.col(0);
    Mat m2subClone = m2.col(0).clone();
    vector<float> v2(m2subClone); // works
    vector<float> v3(m2sub); // doesn't work
return 0;
}

It seems strange as what's being called is in mat.hpp: 在mat.hpp中调用的内容似乎很奇怪:

template<typename _Tp> inline Mat::operator std::vector<_Tp>() const {
    std::vector<_Tp> v;
    copyTo(v);
    return v; // <- breaks here
}

and copyTo seems to memcpy the data. 和copyTo似乎记忆数据。

It doesn't give a error message but I see in the stack trace that it breaks at the return statement, and then somewhere deep into an 'operator new' and 'ntdll.dll!RtlpAllocateHeap()'. 它没有给出错误消息,但我在堆栈跟踪中看到它在return语句处断开,然后深入到'operator new'和'ntdll.dll!RtlpAllocateHeap()'。

Strangely, in my full code, it breaks at a slightly different place: inside copyTo(v) at the memcpy, and throws a 'Access violation writing location 0x0000000001F43D4C.'. 奇怪的是,在我的完整代码中,它在一个稍微不同的地方中断:在memcpy的copyTo(v)内部,并抛出“访问冲突写入位置0x0000000001F43D4C。”。 My full code looks exactly like the one above, but the matrices are bigger. 我的完整代码看起来与上面的代码完全相同,但矩阵更大。

Edit: If in above example, I change the matrices to 编辑:如果在上面的示例中,我将矩阵更改为

    Mat m1 = Mat::zeros(5900, 1, CV_32FC1);
    Mat m2 = Mat::zeros(5900, 3, CV_32FC1);

the snippet fails at the same place than my full code, with the access violation error. 由于访问冲突错误,代码段在与完整代码相同的位置失败。

I have over 2GB RAM free, and the app is compiled as a 64-bit app, so it shouldn't be an 'out of memory' issue (?) 我有超过2GB的RAM免费,并且该应用程序被编译为64位应用程序,因此它不应该是“内存不足”问题(?)

I don't understand deeply the OpenCV Mat class, but I guess there is something shared by the columns in the matrices, so memcopying it might not be a good idea. 我不太了解OpenCV Mat类,但我想矩阵中的列有共享的东西,所以记住它可能不是一个好主意。 Checking the OpenCV documentation of the Mat::row method ( here , the Mat::col method has the same argument about a "shared header"), there is a note indicating that the following is not a good idea : 检查Mat :: row方法的OpenCV文档( 这里 ,Mat :: col方法有关于“共享头”的相同参数),有一个注释表明以下不是一个好主意

Mat A;
...
A.row(i) = A.row(j); // will not work

and that you should use the following instead: 并且你应该使用以下代码:

A.row(j).copyTo(A.row(i));

So, perhaps in your code you should have used this: 所以,也许在你的代码中你应该使用这个:

vector<float> v3;
m2sub.copyTo(v3);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM