C++ 矩阵在任何运算符之后都是相同的
我有一个叫做BasePoint的类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
{
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 oncv::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>操作符。我现在没有主意,肯定还有别的东西,是吗