5

I am implementing an image processing algorithm in C++ using openCV, in which the 1st step requires that the image be converted to a matrix. I know that when an image is loaded into openCV, it is already stored as a matrix. The image that I am using is of size 80 x 60, so I am assuming that the matrix it is stored in is of size 80 x 60. However, I would like to first be able to see this matrix and then be able to reshape it into a matrix with the same no. of pixels but as one long column instead. i.e. the 80 x 60 matrix would now become a 4800 x 1 matrix. I have tried researching textbooks and online but to no avail. This is my code so far. In any case, it is not working because I cannot cannot convert from 'IplImage *' to 'CvMat * but how else I am supposed to assign my pixel values to the matrix after creating it? Please, I would greatly appreciate if someone could help me with this code.

#include "cv.h"
#include "highgui.h"
#include "iostream"

using namespace std;
int main( int argc, char* argv ) {
IplImage* img0 = NULL;
CvMat* img0_mat = NULL ;
img0 = cvLoadImage("C:\\new\\walk mii.jpg");
if (!img0){
    return -1;}
img0_mat = cvCreateMat(80, 60, 1);
img0_mat = img0;
cout <<" matrix " << img0 << endl;

cvWaitKey(0);
return 0;
}
sue-ling
  • 399
  • 2
  • 11
  • 21
  • Just as an information: opencv does not store images in matrices in the sense of `int[][]`. Internally it uses just a single dimension, like `char[]`. – vsz Mar 12 '12 at 07:10

1 Answers1

1

You could call Mat::reshape(int cn, int rows=0):

The method makes a new matrix header for *this elements. The new matrix may have different size and/or different number of channels. Any combination is possible, as long as:

1) No extra elements is included into the new matrix and no elements are excluded. Consequently, the product

2) rows*cols*channels() must stay the same after the transformation.

No data is copied, i.e. this is O(1) operation. Consequently, if you change the number of rows, or the operation changes elements’ row indices in some other way, the matrix must be continuous. See Mat::isContinuous() .

...it looks like you're using an older version of the library though so you want cvReshape. Something like this should work:

#include "cv.h" 
#include "highgui.h" 
#include "iostream" 
using namespace std; 

int main( int argc, char* argv ) 
{ 
    IplImage* img0 = NULL; 
    CvMat* img0_mat = NULL ; 
    img0 = cvLoadImage("C:\\new\\walk mii.jpg"); 
    img0_mat = cvCreateMat(80, 60, 1); 

    CvMat row_header, *row;
    row = cvReshape( img0_mat, &row_header, 0, 1 );

    cout << " matrix " << row->tostring() << endl; 

    cvWaitKey(0); 
    return 0;
}
Jon Cage
  • 36,366
  • 38
  • 137
  • 215
  • This might be of interest too: http://stackoverflow.com/questions/7125452/how-am-i-supposed-to-use-cvreshape – Jon Cage Mar 09 '12 at 07:16
  • Thanks so much for your help Mr. Cage. Your code worked. However, the output was matrix 0032FC38. I hope I am not asking a silly question, but I am already frustrated so might as well. Wouldn't the number of rows supposed to be 4800? Also, how am I to get the pixel values of my img0 image into the img0_mat matrix which was created? – sue-ling Mar 09 '12 at 07:20
  • 0032FC38 would be the pointer address of row rather than the contents. If you read the cvReshape documentation it tells you that it doesn't assign more storage; it just gives a new way to access the data. – Jon Cage Mar 09 '12 at 10:58
  • If you want to print the contents, try this: http://stackoverflow.com/questions/7970988/print-out-the-values-of-a-mat-matrix-in-opencv-c (in your case you would want to do change `cout <<" matrix " << row << endl;` to `cout <<" matrix " << *row << endl;` to dereference the pointer). – Jon Cage Mar 09 '12 at 11:02
  • Thanks:) However, when I tried to build it, I got an error saying - no operator found which takes a right-hand operand of type 'CvMat' (or there is no acceptable conversion). Do you have any idea how to get around this? – sue-ling Mar 09 '12 at 14:09
  • Maybe it's just the more recent versions of opencv which include the necessary operators then? I'll update the example to print out the contents... – Jon Cage Mar 09 '12 at 15:46
  • A bit more digging reveals that cvMat has a tostring() function :-) Try the updated example above. – Jon Cage Mar 09 '12 at 15:55
  • Thank you very much sir:) the tostring() wasn't working but from your advice with the cvReshape and some other links, I was able to both see and reshape the matrix. God bless you and thanks again – sue-ling Mar 10 '12 at 17:14