2

我正在尝试使用此构造函数从我在内存中分配的一些数据创建一个 Mat 对象。

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

我对 C++ 相当陌生,所以如果我在某处犯了基本错误,请记住这一点。基本上我想做的是显示来自原始视频文件的图像。为此,我从文件中读取数据并将其分配到内存中。

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);

我已经能够从文件中读取数据......例如视频标题。我想我可能不清楚构造函数是如何工作的。如果有人可以提供一些见解,那就太好了。当我在namedWindow中显示框架时,它全是黑色的。

顺便一提...

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

第一帧的原始数据是 512x640 16bit unsigned little Endian byte order black and white。

4

2 回答 2

2

发现问题了... 文件中的数据是 16 位无符号的,但每个像素的范围只有 12 位。所以这就是窗户显示为黑色的全部原因。

我想 OpenCV 不支持显示 12 位无符号数据,因此我必须将其转换为 8 位无符号数据才能显示。是的,它更有效地读取块中的所有像素数据,而不是循环。

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);

所以,是的,不是很难,哈哈

于 2013-04-28T03:33:44.447 回答
2

step是等于或大于 的图像步幅的大小sizeof(_PIXELTYPE) * Width。您没有具体说明您的问题,但我注意到您错误地将 step 设置为2*HEIGHT. 否则,您的构造函数使用似乎没问题。

编辑:当然只使用自动步来为您计算默认步幅。

于 2013-04-26T13:56:36.510 回答