openCV Mat中的值在自定义类构造函数中设置后不会保留 我在C++ VisualStudio中编写了OpenCV应用程序,并且在一个包含一个垫子作为它的成员的自定义类中存在问题。我已经将有问题的代码简化为下面的示例,它仍然显示了这个问题
有问题的Mat被定义为私有成员,并在类构造函数中使用正确的值初始化。使用std::cout进行的测试表明,这些值确实是正确的。当我尝试在成员函数中使用这个Mat时,它的值是杂乱无章的。当然,我需要它们与构造函数中定义的相同 我假设这与Mat类的工作方式有关,因为这不会发生在int、float等常规类型上,。。。我在谷歌上搜索过,但找不到任何迹象表明为什么会发生这种情况。显然,我在构造函数中保存Mat的方法有问题,但我找不到有用的替代方法。std::cout显示的值看起来是随机的,但是*.at显示的所有值都是相同的(或相似的),这更像是某种溢出。不管怎样,这都是错误的 谢谢你的时间openCV Mat中的值在自定义类构造函数中设置后不会保留 我在C++ VisualStudio中编写了OpenCV应用程序,并且在一个包含一个垫子作为它的成员的自定义类中存在问题。我已经将有问题的代码简化为下面的示例,它仍然显示了这个问题,c++,opencv,C++,Opencv,有问题的Mat被定义为私有成员,并在类构造函数中使用正确的值初始化。使用std::cout进行的测试表明,这些值确实是正确的。当我尝试在成员函数中使用这个Mat时,它的值是杂乱无章的。当然,我需要它们与构造函数中定义的相同 我假设这与Mat类的工作方式有关,因为这不会发生在int、float等常规类型上,。。。我在谷歌上搜索过,但找不到任何迹象表明为什么会发生这种情况。显然,我在构造函数中保存Mat的方法有问题,但我找不到有用的替代方法。std::cout显示的值看起来是随机的,但是*.at显示
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
class test {
Mat stayStill;
int number;
public:
test(double value, int someNumber) {
number = someNumber;
double data[] = {
0, value, 0,
value, 0, value,
0, value, 0
};
stayStill = Mat(3, 3, CV_64FC1, data);
cout << endl << "number: " << number;
cout << endl << "stayStill as defined on init" << endl << stayStill;
}
void show() {
cout << endl << "stayStill as experienced in member function" << endl << stayStill << endl;
cout << endl << "and once more just to be sure:" << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << stayStill.at<double>(i, j) << " ";
}
cout << endl;
}
cout << endl << "size: " << stayStill.size();
cout << endl << "type: " << stayStill.type();
cout << endl << "number: " << number << endl;
}
};
int main() {
test a(3, 5);
a.show();
return 0;
}
OpenCV中的矩阵使用引用计数器技术。调用复制操作时,它们只复制指向源矩阵数据的指针,而不复制整个基础数据
stayStill = Mat(3, 3, CV_64FC1, data);
^^^
在上面的行中,创建了临时Mat-它保存数据
,然后staySill
获取指向此临时的指针,最后此指针悬空,因为在完整表达式结束时临时Mat被销毁
您可以引入新的命名Mat
实例:
Mat m(3, 3, CV_64FC1, data);
并通过copyTo
进行深度复制:
m.copyTo(stayStill);
Mat
的赋值运算符执行浅复制;因此,您的成员变量stayStill
将包含对临时对象的引用(稍后调用show
时,临时对象已超出范围)。这会产生未定义的行为
您可以使用Mat::copyTo()
进行深度复制。e、 g
Mat temp(3, 3, CV_64FC1, data);
temp.copyTo(stayStill);
正确,在本例中,临时对象是超出范围的
double data[]
对象。另一种修复方法是在创建Statystill时使用clone()
on,如下所示:Statystill=Mat(3,3,CV_64FC1,data).clone()代码>具有相同的效果。这就解决了它!感谢您花时间解释问题背后的原因。当然,由于指针的存在,会出现问题:)。
Mat temp(3, 3, CV_64FC1, data);
temp.copyTo(stayStill);