矩阵在任何运算符之后都变得相同

Matrices become same after any operator

本文关键字:之后 任何 运算符      更新时间:2023-10-16

我有一个名为 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_factor;而不是使用totalInvariants时,previousBasePointcurrentBasePoint相同。但是,如果我不划分它,一切正常。这里可能有什么问题?

编辑:

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

也有效,但我仍然想知道该部门有什么问题

您正在使用=opeartorcv::Mat它使用浅拷贝操作。所以它们都会有相同的内存地址,你需要使用cv::Matclone()操作。

您还需要重载 =BasePoint的运算符作为默认运算符,previousBasePoint = currentBasePoint;也会做内部invariant的浅拷贝。

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

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;
}

无运算符重载的输出[1]:

[0, 0, 0;   [0.2, 0.2, 0.2;
0, 0, 0;    0.2, 0.2, 0.2;
0, 0, 0]    0.2, 0.2, 0.2]

运算符重载时的输出[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=(const Mat& m(

C++: Mat&Mat::operator=(const MatExpr& expr(

m – 分配的右侧矩阵。矩阵赋值为 O(1( 操作。这意味着不复制任何数据,但共享数据 并且引用计数器(如果有(将递增。分配之前 新数据,旧数据通过 Mat::release(( 取消引用。

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

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