Reputation: 521
I have a class called 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;
};
and have 2 objects of this class:
BasePoint previousBasePoint;
BasePoint currentBasePoint;
In every iteration I perform
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
}
The problem with the code is that when I perform totalInvariants / norm_factor;
instead of using totalInvariants
, previousBasePoint
become same with currentBasePoint
. However, If I do not divide it everything works fine. What can be the problem here?
EDIT:
const float norm_factor = 1.0;
currentBasePoint.invariants = totalInvariants;
currentBasePoint.invariants = currenBasePoint.invariants / norm_factor
also works, but I am still wondering what is wrong with the division
Upvotes: 0
Views: 73
Reputation: 521
I solved the problem by overloading = operator.
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;
}
Output without operator overloading[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]
Output with operator overloading[2]:
[0, 0, 0; [0, 0, 0;
0, 0, 0; 0, 0, 0;
0, 0, 0] 0, 0, 0]
Output without division[3]:
[0, 0, 0; [0, 0, 0;
0, 0, 0; 0, 0, 0;
0, 0, 0] 0, 0, 0]
In OpenCV documentation:
C++: Mat& Mat::operator=(const Mat& m)
C++: Mat& Mat::operator=(const MatExpr& expr)
m – Assigned, right-hand-side matrix. Matrix assignment is an O(1) operation. This means that no data is copied but the data is shared and the reference counter, if any, is incremented. Before assigning new data, the old data is de-referenced via Mat::release() .
expr – Assigned matrix expression object. As opposite to the first form of the assignment operation, the second form can reuse already allocated matrix if it has the right size and type to fit the matrix expression result. It is automatically handled by the real function that the matrix expressions is expanded to. For example, C=A+B is expanded to add(A, B, C), and add() takes care of automatic C reallocation.
So this problem happens, since /
operator returns MatExpr
object and it causes that shared data can be reused by other matrix. But I expect that output[1] will be the same with output[3].
Upvotes: 1
Reputation: 621
You are using =
opeartor on cv::Mat
which uses a shallow copy operation. So all of them will have the same memory address, you need to use clone()
operation of cv::Mat
.
Also you need to overload = operator of BasePoint
as default operator on previousBasePoint = currentBasePoint;
will also do a shallow copy of the internal invariant
.
Upvotes: 3