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
C++ 矩阵在任何运算符之后都是相同的_C++_Opencv - Fatal编程技术网

C++ 矩阵在任何运算符之后都是相同的

C++ 矩阵在任何运算符之后都是相同的,c++,opencv,C++,Opencv,我有一个叫做BasePoint的类 BasePoint { public: BasePoint(); //BasePoint(const BasePoint& bp); uint id; float avgVal; float varVal; float avgLas; float varLas; cv::Mat invariants;// Type : 32FC1 int status; }; 并具有该类的2个对

我有一个叫做BasePoint的类

BasePoint
{
public:
    BasePoint();
    //BasePoint(const BasePoint& bp);
    uint id;
    float avgVal;
    float varVal;
    float avgLas;
    float varLas;
    cv::Mat invariants;// Type : 32FC1
    int status;
};
并具有该类的2个对象:

BasePoint previousBasePoint;
BasePoint currentBasePoint;
在我执行的每个迭代中

const float norm_factor = 1.0;
currentBasePoint.invariants = totalInvariants / norm_factor; // Problem is here
currentBasePoint.id = image_counter;

if(previousBasePoint.id == 0)
{
     previousBasePoint = currentBasePoint;
     currentPlace->members.push_back(currentBasePoint);
     wholebasepoints.push_back(currentBasePoint);
}
else
{
     //some code here
}
代码的问题是,当我执行
totalInvariants/norm\u因子时
不再使用
totalInvariants
previousBasePoint
currentBasePoint
相同。然而,如果我不把它分开,一切都很好。这里有什么问题

编辑:

const float norm_factor = 1.0;
currentBasePoint.invariants = totalInvariants;
currentBasePoint.invariants = currenBasePoint.invariants / norm_factor

同样有效,但我仍然想知道您在
cv::Mat
上使用的
=
运算器的分区有什么问题,它使用浅拷贝操作。因此,它们都将具有相同的内存地址,您需要使用
cv::Mat
clone()
操作


您还需要重载
BasePoint的=运算符作为
previousBasePoint=currentBasePoint上的默认运算符
还将对您正在使用的
=
opeartor on
cv::Mat
上使用浅拷贝操作的内部
不变量进行浅拷贝。因此,它们都将具有相同的内存地址,您需要使用
cv::Mat
clone()
操作


您还需要重载
BasePoint的=运算符作为
previousBasePoint=currentBasePoint上的默认运算符
还将做内部
不变量的浅拷贝

我通过重载=运算符解决了这个问题

class A{
    public:
        cv::Mat matrix;
        A(){
            this->matrix = cv::Mat();
        }

        A(const A& otherA){
            std::cout << "Copy Called" << std::endl;
            this->matrix = otherA.matrix.clone();
        }

            void operator = (const A& otherA){
            std::cout << "Operator overlad called" << std::endl;
            this->matrix = otherA.matrix.clone();
        }
    };

    int main()
    {
        A a1,a2;
        cv::Mat anotherMat = cv::Mat::ones(3,3,CV_32FC1);
        a1.matrix = cv::Mat::zeros(3,3,CV_32FC1);
        //        a2 = a1;
        a2 = a1;
        std::cout << a2.matrix << std::endl;
        a1.matrix = anotherMat / 5; // Division, type MatExpr
        std::cout << a2.matrix << std::endl;

        return 0;
    }
运算符重载的输出[2]:

[0, 0, 0;   [0, 0, 0;
 0, 0, 0;    0, 0, 0;
 0, 0, 0]    0, 0, 0]
不带除法的输出[3]:

[0, 0, 0;   [0, 0, 0;
 0, 0, 0;    0, 0, 0;
 0, 0, 0]    0, 0, 0]
在OpenCV文档中:

C++:Mat&Mat::operator=(常量Mat&m)

C++:Mat&Mat::operator=(常量MatExpr&expr)

m–指定的右侧矩阵。矩阵赋值是一个O(1) 活动这意味着不复制数据,但共享数据 参考计数器(如果有)将递增。分配前 新数据,旧数据通过Mat::release()取消引用

expr–指定的矩阵表达式对象。与第一个相反 赋值操作的表单,第二个表单已经可以重用了 分配矩阵,如果其大小和类型适合矩阵 表达结果。它由实函数自动处理 矩阵表达式展开为。例如,C=A+B是 扩展为add(A、B、C),add()负责自动添加C 重新分配


所以这个问题发生了,因为
/
操作符返回
MatExpr
对象,它导致共享数据可以被其他矩阵重用。但是我希望输出[1]与输出[3]相同。

我通过重载=运算符解决了这个问题

class A{
    public:
        cv::Mat matrix;
        A(){
            this->matrix = cv::Mat();
        }

        A(const A& otherA){
            std::cout << "Copy Called" << std::endl;
            this->matrix = otherA.matrix.clone();
        }

            void operator = (const A& otherA){
            std::cout << "Operator overlad called" << std::endl;
            this->matrix = otherA.matrix.clone();
        }
    };

    int main()
    {
        A a1,a2;
        cv::Mat anotherMat = cv::Mat::ones(3,3,CV_32FC1);
        a1.matrix = cv::Mat::zeros(3,3,CV_32FC1);
        //        a2 = a1;
        a2 = a1;
        std::cout << a2.matrix << std::endl;
        a1.matrix = anotherMat / 5; // Division, type MatExpr
        std::cout << a2.matrix << std::endl;

        return 0;
    }
运算符重载的输出[2]:

[0, 0, 0;   [0, 0, 0;
 0, 0, 0;    0, 0, 0;
 0, 0, 0]    0, 0, 0]
不带除法的输出[3]:

[0, 0, 0;   [0, 0, 0;
 0, 0, 0;    0, 0, 0;
 0, 0, 0]    0, 0, 0]
在OpenCV文档中:

C++:Mat&Mat::operator=(常量Mat&m)

C++:Mat&Mat::operator=(常量MatExpr&expr)

m–指定的右侧矩阵。矩阵赋值是一个O(1) 活动这意味着不复制数据,但共享数据 参考计数器(如果有)将递增。分配前 新数据,旧数据通过Mat::release()取消引用

expr–指定的矩阵表达式对象。与第一个相反 赋值操作的表单,第二个表单已经可以重用了 分配矩阵,如果其大小和类型适合矩阵 表达式结果。它由实函数自动处理 矩阵表达式展开为。例如,C=A+B是 扩展为add(A、B、C),add()负责自动添加C 重新分配


所以这个问题发生了,因为
/
操作符返回
MatExpr
对象,它导致共享数据可以被其他矩阵重用。但是我希望输出[1]与输出[3]相同。

您的
cv::Mat
对象是如何初始化的?你能提供一个能让任何人重现你的问题吗?我还没有初始化它。previousBasePoint和currentBasePoint是另一个类中的2个对象
PlaceDetector::PlaceDetector(){private:BasePoint currentBasePoint BasePoint previousBasePoint;}
编辑部分中的代码不同,您正在对currenBasePoint进行除法,而不是对currentBasePoint的不变量成员进行除法(上面还有一个类型)。在原始代码中也有一个赋值previousBasePoint=currentBasePoint。如果由于复制构造函数或赋值运算符错误,您的id始终为0,那么您将始终将结果复制到previousBasePoint编辑的部分是错误的,我更正了它。我在代码b的其他部分的循环结束处更新previousBasePoint但是它给出了正确的答案,除非我不划分currentBasePoint.invariantsHow您的
cv::Mat
对象是否已初始化?您能否提供一个示例,以便任何人都可以重现您的问题?我尚未初始化它。previousBasePoint和currentBasePoint是另一个类中的两个对象
PlaceDetector::PlaceDetector(){private:BasePoint currentBasePoint BasePoint BasePoint previousBasePoint;}
您编辑的部分中的代码不相同,您正在对currenBasePoint进行除法,而不是对currentBasePoint的不变量成员(还有一个类型)。在原始代码中也有一个赋值previousBasePoint=currentBasePoint。如果由于复制构造函数或赋值运算符错误,您的id始终为0,那么您将始终将结果复制到previousBasePoint编辑的部分是错误的,我更正了它。我在代码b的其他部分的循环结束处更新previousBasePoint但是它给出了正确的答案,除非我不划分currentBasePoint。不变量但是如果没有
/norm\u factor
,操作符就不是问题。我还为
BasePoint
定义了复制指导器,它克隆不变量和重载
=/code>操作符。我现在没有主意,肯定还有别的东西,是吗