David
David

Reputation: 45

Moving my array to Mat and showing image with open CV

I am having problems using opencv to display an image. As my code is currently working, I have function that loads 78 images of size 710X710 of unsigned shorts into a single array. I have verified this works by writing the data to a file and reading it with imageJ. I am now trying to extract a single image frame from the array and load it into a Mat in order to perform some processing on it. Right now I have tried two ways to do this. The code will compile and run if I do not try to read the output, but if I cout<

My question would be, how do I extract the data from my large, 1-D array of 78images of size 710*710 into single Mat images. Or is there an more efficient way where I can load the images into a 3-D mat of dimensions 710X710X78 and operate on each 710X710 slice as needed?

int main(int argc, char *argv[])
{
    Mat OriginalMat, TestImage;

    long int VImageSize = 710*710;
    int NumberofPlanes = 78;
    int FrameNum = 150;

    unsigned short int *PlaneStack = new unsigned short int[NumberofPlanes*VImageSize];
    unsigned short int *testplane = new unsigned short int[VImageSize];

    /////Load PlaneStack/////
    Load_Vimage(PlaneStack, Path, NumberofPlanes); 

    //Here I try to extract a single plane image to the mat testplane, I try it two    different ways with the same results
    memcpy(testplane, &PlaneStack[710*710*40], VImageSize*sizeof(unsigned short int));
    //copy(&PlaneStack[VImageSize*40],&PlaneStack[VImageSize*41], testplane);

    // move single plane to a mat file
    OriginalMat = Mat(710,710,CV_8U, &testplane) ;
    //cout<<OriginalMat;

    namedWindow("Original");
    imshow("Original", OriginalMat);

}

Upvotes: 1

Views: 2360

Answers (1)

Bull
Bull

Reputation: 11941

The problem is you are using the constructor Mat::Mat(int rows, int cols, int type, void* data) with a pointer to 16 bit data (unsigned short int) but you are specifying the type CV_8U (8 bit). Therefore the first byte of your 16 bit pixel becomes the first pixel in OriginalMat, and the second byte of the first pixel becomes the second pixel in OriginalMat, etc.

You need to create a 16 bit Mat, then convert it to 8 bit if you want to display it, e.g.:

int main(int argc, char *argv[])
{
    long int VImageSize = 710*710;    
    int NumberofPlanes = 78;
    int FrameNum = 150;

    /////Load PlaneStack/////
    unsigned short int *PlaneStack = new unsigned short int[NumberofPlanes*VImageSize];      
    Load_Vimage(PlaneStack, Path, NumberofPlanes); 

    // Get a pointer to the plane we want to view
    unsigned short int *testplane = &PlaneStack[710*710*40];

    // "move" single plane to a mat file
    //  actually nothing gets moved, OriginalMat will just contain a pointer to your data.
    Mat OriginalMat(710,710,CV_16UC1, &testplane) ;

    double scale_factor = 1.0 / 256.0;
    Mat DisplayMat;
    OriginalMat.convertTo(DisplayMat, CV_8UC1, scale_factor);

    namedWindow("Original");
    imshow("Original", DisplayMat);
}

Upvotes: 2

Related Questions