I'm suffered by using OpenCV Mat due to unexpected results.
There is an example code:
cv::Mat local_mat = cv::Mat::eye(cv::Size(1000, 1000), CV_8UC1);
qDebug() << "1. local_mat.data: " << local_mat.data;
cv::Mat sobel_img_ = cv::Mat::eye(cv::Size(1000, 1000), CV_8UC1);
qDebug() << "2. sobel_img_.data: " << sobel_img_.data;
sobel_img_ = local_mat; // copy address but no clone()
qDebug() << "3. sobel_img_.data: " << sobel_img_.data;
sobel_img_ = cv::Mat::eye(cv::Size(1000, 1000), CV_8UC1); // renew
qDebug() << "4. sobel_img_.data: " << sobel_img_.data;
- local_mat.data: 0x55aa19a53e40
- sobel_img_.data: 0x55aa19b480c0
- sobel_img_.data: 0x55aa19a53e40
- sobel_img_.data: 0x55aa19a53e40
1 and 2 should be different because I create new Mat(), so it is fine.
However, 3 and 4 are same even though I create new Mat() after copying the local_mat into sobel_mat.
I meet many problems like this when I use OpenCV Mat.
Could you explain why it happens and how can I solve this?
CodePudding user response:
Initializing of matrix is a form of matrix expression.
cv::Mat
has overloads of operator=
. One of them handles MatExpr as its argument:
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.
by bold font I emphasized what happens in your case. Already allocated memory is used to create identity matrix by cv::Eye
.
You can turn MatExpr
into cv::Mat
just by casting:
sobel_img_ = (cv::Mat)cv::Mat::eye(cv::Size(1000, 1000), CV_8UC1); // renew
then sobel_img
will refer to new allocated matrix.