Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
openCV Mat中的值在自定义类构造函数中设置后不会保留 我在C++ VisualStudio中编写了OpenCV应用程序,并且在一个包含一个垫子作为它的成员的自定义类中存在问题。我已经将有问题的代码简化为下面的示例,它仍然显示了这个问题_C++_Opencv - Fatal编程技术网

openCV Mat中的值在自定义类构造函数中设置后不会保留 我在C++ VisualStudio中编写了OpenCV应用程序,并且在一个包含一个垫子作为它的成员的自定义类中存在问题。我已经将有问题的代码简化为下面的示例,它仍然显示了这个问题

openCV Mat中的值在自定义类构造函数中设置后不会保留 我在C++ VisualStudio中编写了OpenCV应用程序,并且在一个包含一个垫子作为它的成员的自定义类中存在问题。我已经将有问题的代码简化为下面的示例,它仍然显示了这个问题,c++,opencv,C++,Opencv,有问题的Mat被定义为私有成员,并在类构造函数中使用正确的值初始化。使用std::cout进行的测试表明,这些值确实是正确的。当我尝试在成员函数中使用这个Mat时,它的值是杂乱无章的。当然,我需要它们与构造函数中定义的相同 我假设这与Mat类的工作方式有关,因为这不会发生在int、float等常规类型上,。。。我在谷歌上搜索过,但找不到任何迹象表明为什么会发生这种情况。显然,我在构造函数中保存Mat的方法有问题,但我找不到有用的替代方法。std::cout显示的值看起来是随机的,但是*.at显示

有问题的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);