简体   繁体   中英

Mat constructor from user allocated data in OpenCV

I am trying to create a Mat object from some data I have allocated in memory using this constructor.

C++: Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)

I am fairly new to C++ so bear that in mind if I am making a rudimentary error somewhere. Basically what I am trying to do is display an image from a raw video file. To do this, I read the data from the file and allocated it in memory.

struct videoFrame{
    float frameTime;
    unsigned short int year, day, msec;
    unsigned char hour, min, sec;
    unsigned short int mFrame[SIZE];
};

...

//seek to first frame
vfs.seekg(2560, ios_base::beg);
int pos;
for(pos=0; pos<SIZE;pos++){
    vfs.read( (char*) &mVideoFrame1->mFrame[pos], sizeof(short));
}
Mat mImage1( Size(WIDTH, HEIGHT), CV_16UC1, mVideoFrame1->mFrame, HEIGHT * 2);
namedWindow("Frame 1", CV_WINDOW_AUTOSIZE);
imshow("Frame 1", mImage1);
waitKey(0);

I have been able to read data from the file... such as frame and video headerers . I think I may not be clear on how the constructor works. If someone could offer some insight that would be great. When I show the frame in the namedWindow it is all black.

By the way...

const int HEIGHT = 512;
const int WIDTH = 640;
const int SIZE = HEIGHT * WIDTH * 2;

the raw data in the first frame is 512x640 16bit unsigned little Endian byte order black and white.

step is the size of the image stride which is equal to or larger than sizeof(_PIXELTYPE) * Width . You don't specify your problem, but I note you wrongly have put step equal to 2*HEIGHT . Otherwise your constructor usage seems ok.

EDIT: of course just use auto step which calculates the default stride for you.

Found what was wrong... The data in the file is 16 bit unsigned, but the range for each pixel is only 12 bit. So that was the whole reason the window was showing up black.

OpenCV I suppose does not offer support for displaying 12bit unsigned data, so I had to convert it to 8bit unsigned for it to be displayed. And yes its much more efficient to read all pixel data in block, rather than a loop.

vfs.read( (char*) &mVideoFrame1->mFrame, sizeof(mVideoFrame1->mFrame));

Mat mImage1(HEIGHT, WIDTH, CV_16UC1, mVideoFrame1->mFrame, Mat::AUTO_STEP);
Mat mine(Size(640,512), CV_8UC1);
mImage1.convertTo(mine, CV_8UC1, 255.0/4095.0);
namedWindow("Frame 1", CV_WINDOW_AUTOSIZE);
imshow("Frame 1", mine);
waitKey(0);

So yeah, wasn't to hard lol

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM