Ask Your Question
0

mat.reshape not working

asked 2016-03-24 02:46:02 -0600

Nbb gravatar image

updated 2016-03-24 03:47:51 -0600

Hello I have a matrix M 3x3

I use reshape(0,9) so the M.at(0,1) should be the 4th element but it becomes the 2nd element. Help please. If i am wrong then please tell me how do i convert a 2D matrix into a 1D column vector.

EDIT: I dunno how to show the code. Its too big

My matrix is 92 x 112. some of the data below.

-40 -39

-44

....

In matlab if i reshape it becomes

-40

-44

...

-39

-39 becomes the 93rd element. In opencv I reshape it becomes

-40

-39

....

-39 becomes the SECOND element and i dunno where the -44 goes to. I used M.reshape(0,92*112). Matlab is giving me the right answer

Here is the short piece of code that I have

        cout << Im.at<float>(0,0) << endl;
        cout << Im.at<float>(0,1) << endl;
        waitKey(0);

        // Reshape to column vector -- Wrong
        Mat temp;
        Im.reshape(0, 92*112).copyTo(temp);

        cout << temp.at<float>(0,0) << endl;
        cout << temp.at<float>(1,0) << endl;

What I am getting above is that the elements in (0,0) and (0,1) are equal to (0,0) and (1,0) after being reshaped. Im(0,1) should be equal to temp(113,0) or temp(93,0) but I am not getting such values. Is there another function to reshape a 2D Mat ?

EDIT: Okay it seems like my understanding of the reshape function was totally wrong. Thanks again berak. I had thought OpenCV would go 'down' the array but it seems like OpenCV would move from top left to bottom right

edit retag flag offensive close merge delete

Comments

please show us your code.

berak gravatar imageberak ( 2016-03-24 02:52:46 -0600 )edit

I have tried it and it works for small matrices but not big ones. is there another function that I can try

Nbb gravatar imageNbb ( 2016-03-24 03:04:04 -0600 )edit
  • "so the M.at(0,1) should be the 4th element" -- why do you think so ?
  • "but it becomes the 2nd element" -- that's correct for the 3x3 case, for the 1x9 case, you're out of bounds. c++ starts indexing from 0, matlab from 1.
berak gravatar imageberak ( 2016-03-24 03:04:41 -0600 )edit
1

be extra careful, when moving between opencv/c++ and matlab. again, there's a lot of assumptions:

  • opencv/c++ starts indexing from 0, matlab/fortan from 1
  • opencv Mat's are row-major (like in memory), matlab is col-major
  • if there are channels, they are interleaved in opencv, but consecutive in matlab
  • ... and lots more, that i can't remember
berak gravatar imageberak ( 2016-03-24 03:56:43 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2016-03-24 03:09:23 -0600

berak gravatar image

updated 2016-03-24 03:35:01 -0600

your reshape is correct, but then, you seem to have trouble with different indexing conventions between c++ in general, and matlab.

please, when in doubt, you should run a debug build, a lot of important assertions are suppressed in release.

here's some code to illustrate it:

Mat_<float> m(3,3); m << 1,2,3,4,5,6,7,8,9;    
cerr << m << endl;

[1, 2, 3;
 4, 5, 6;
 7, 8, 9]

cerr << m(0,1) << endl;
2

cerr << m(1,0) << endl;
4


Mat_<float> m2 = m.reshape(0,9);   
cerr << m2 << endl;
[1;
 2;
 3;
 4;
 5;
 6;
 7;
 8;
 9]

// out of bounds:
cerr << m2(0,1) << endl;

OpenCV Error: Assertion failed ((unsigned)i1 < (unsigned)size.p[1]) in cv::Mat_<float>::operator (), file E:\code\opencv\build\install\include\opencv2/core/mat.
inl.hpp, line 1602

// this would be the correct way for a 1d col-mat:
cerr << m2(1,0) << endl;
2

[edit:]

it seems, you want the transposed mat reshaped:

Mat mt = m.t();
cerr << mt << endl;
[1, 4, 7;
 2, 5, 8;
 3, 6, 9]

cerr << mt.reshape(0,9) << endl;
[1;
 4;
 7;
 2;
 5;
 8;
 3;
 6;
 9]
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-03-24 02:46:02 -0600

Seen: 2,080 times

Last updated: Mar 24 '16