0

How to convert Mat in 2d vector (vector of vector) in C++? I tried this, and got error in Mat.at function.

    vector<vector<double>> dctm(300, vector<double>(300,0));
    for (int i = 0; i < 300; i++) {
        for (int j = 0; j < 300; j++) {
            dctm[i][j] = img.at<double>(i, j);
        }
    }
la lluvia
  • 705
  • 3
  • 10
  • 20
  • Unhandled exception at 0x7690c41f in XY.exe: Microsoft C++ exception: cv::Exception at memory location 0x012aecb8.. – la lluvia Nov 19 '13 at 11:40
  • /mat.hpp:537: error: (-215) dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3) - 1))*4) & 15) == elemSize1() " std::basic_string,std::allocator > – la lluvia Nov 19 '13 at 11:41
  • Take a look here: http://stackoverflow.com/questions/14303073/using-matati-j-in-opencv-for-a-2-d-mat-object (think about using Vec3f instead of double...) – Adriano Repetti Nov 19 '13 at 11:42
  • 3
    what is the actual type() of your Mat ? i bet it's not double – berak Nov 19 '13 at 11:43
  • it's unsigned char, but i want to cast it to double – la lluvia Nov 19 '13 at 11:46
  • i put img.at and it works now, didn't know i can't cast it like that. Thanx for help! – la lluvia Nov 19 '13 at 11:51

2 Answers2

3

You can fill the vector by iterating over values and pushing them one by one, but in general this is not considered a good practice. Much better solution is to use range functions provided to you by stl. This is true not only for vector but for any other stl structure.

Cleaner (from stl point view) and faster solution should be like this:

for(int i=0; i<300; i++)
{
    Mat r = img.row(i);
    dctm.push_back(vector<double>(r.begin<unsigned char>(), r.end<unsigned char>()));
}
Michael Burdinov
  • 4,348
  • 1
  • 17
  • 28
2

Much faster way would be

vector<vector<double>> dctm(300, vector<double>(300,0));
for (int i = 0; i < 300; i++) {
    uchar *rowPtr = img.ptr<uchar>(i);
    for (int j = 0; j < 300; j++) {
        dctm[i][j] = *rowPtr[j];
    }
}

See How to scan images, lookup tables and time measurement with OpenCV

old-ufo
  • 2,799
  • 2
  • 28
  • 40