# The problem about the global variable of vector<cv::Mat> and temporary cv::Mat variable

 #include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

cv::Mat Right(Size(768,576),CV_8UC3);
cv::Mat Left(Size(768,576),CV_8UC3);

vector<Mat> mapx;
vector<Mat> mapy;

cv::VideoCapture capture1("test.avi");

void MapInit(const Mat &src)
{
Mat map_x(src.size(),CV_32FC1);
Mat map_y(src.size(),CV_32FC1);
for( int i = 0; i < src.rows; ++i)
{
for( int j = 0; j < src.cols; ++j)
{
map_x.at<float>(i, j) = j ;
map_y.at<float>(i, j) = src.rows - i ;
}
}
mapx.push_back(map_x);
mapy.push_back(map_y);
//Mat map_x1(src.size(),CV_32FC1);
//Mat map_y1(src.size(),CV_32FC1);
for( int i = 0; i < src.rows; ++i)
{
for( int j = 0; j < src.cols; ++j)
{
map_x.at<float>(i, j) = src.cols - j ;
map_y.at<float>(i, j) =  i ;
//map_x1.at<float>(i, j) = src.cols - j ;
//map_y1.at<float>(i, j) =  i ;
}
}
//mapx.push_back(map_x1);
//mapx.push_back(map_y1);
mapx.push_back(map_x);
mapy.push_back(map_y);
}

void mapPlane(const Mat &src)
{
remap(src,Left,mapx[0],mapy[0],0);
flip(Left,Left,0);
remap(src,Right,mapx[1],mapy[1],0);
//mapx[0] is the same as mapx[1];mapy[0] is the same as mapy[1] ???
flip(Right,Right,0);
}
void runCam()
{
namedWindow("test1",0);
namedWindow("test2",0);
for(;;)
{
cv::Mat image;
capture1 >> image;

if(image.empty())
exit(0) ;
cvtColor(image,image,CV_BGR2RGB);
if(mapx.empty() && mapy.empty())
MapInit(image);
mapPlane(image);
imshow("test1",Left);
imshow("test2",Right);
waitKey(20);
}
}

int main(int argc, char **argv)
{
if(!capture1.isOpened())
{
printf("open failed \n");
return -1;
}
runCam();
return 0;
}


As above, I create the temporary variable Mat map_x map_y in Function MapInit(),to my surprise, when I pushback the different map_x map_y into vector<mat> mapx,mapy in order,the element of vector<mat> are the same as the latest modified map_x map_y. Similarly, I write a section of code as following,the elements in the vector result are different,which is contradicted against the above example. I am so confused about that.

#include <iostream>
#include <vector>
using namespace std;

vector<int> result;

void fun()
{
int i = 0;
result.push_back(i);
i = 1;
result.push_back(i);
}
int main()
{
fun();
cout<<result[0]<<endl;
cout<<result[1]<<endl;
}

edit retag close merge delete

So you are saying that all the element in vector<mat> contains the same element copied multiple times? IMHO it is correct if you do it like that. The Mat object is not stored into the vector, but its reference is, so when you change the Mat object, the values at the address of the object are changed, so when calling mapx[i], you are reading from the address of map_x that has just changed. On the contrary if you do something like mapx.push_back(map_x.clone()), or mapx.push_back(cv::Map(map_x)), you'll get the result you want.