OpenCV矩阵和整数矩阵之间的转换

6

我正在尝试使用openCV读取视频帧,以cv::Mat的形式保存数据。然后我想使用另一段代码将这个视频帧传递给接受"int类型矩阵"的函数。我知道"cvMat"和"int类型矩阵"不兼容。也许我对opencv不太熟悉,但我是否可以进行任何形式的"cvMat"和"int mat"之间的转换,以便我可以将捕获的视频帧用于我的代码? 我所说的"int mat"可能不正确,但我的意思是:

cv::Mat videoFrame;
int inputData[600][400];

我希望能做类似以下的事情:

我想要做的是:

inputData = videoFrame;

谢谢你。
1个回答

6

快速的方法是共享内存:不需要复制。不过,如果你修改一个矩阵,另一个矩阵也会被修改(显而易见!)

int inputData[600][400];
cv::Mat videoFrame(600, 400, CV_32UC1, inputData);

请注意,对videoFrame进行任何更改其类型/大小的OpenCV调用都将分配一个新的内存块,其中结果将被存储。
如果您想要单独的数据矩阵,您可以使用memcpy-这是复制数据的最快方式。
memcpy((char*)inputData, (char*)videoFrame.data, 600*400*sizeof(int) );

这种方法的问题是根本不安全。如果 videoFrame 不是 int 类型怎么办?(很可能是 char 类型)如果它在内存中不是连续存储的呢?(这种情况可能发生)...

亲爱的Vasile,非常感谢您的回答。您提出的方法非常好,但我担心内存分配问题。正如您所提到的,这可能是不安全的,而且到目前为止我已经遇到了许多内存问题(不是针对这种情况)。那么是否还有另一个解决方案呢?我真的不希望我的代码因为内存问题再次死机。再次感谢您。 - E_learner
1
安全的方法是根本不使用inputData。查看您的算法,看看是否可以仅使用videoFrame。复制数据有时是糟糕编码的迹象。 - Sam
3
当直接处理 cv::Mat 的底层数据时,请注意 OpenCV 可能引入的任何填充,特别是在将其传递给其他期望连续数据的函数时。OpenCV 可以(默认会)在行之间引入额外的填充,以将它们对齐到 4(或8)字节边界上。虽然对于一个32位整数(和/或这样的圆行宽度),可能不会有任何填充,但这是一般情况下需要记住的事情。 - Christian Rau
注意不要混淆宽度和高度!在指定二维数组或cv::Mat的尺寸时,高度应该在宽度之前。因此,在@sammy的答案(以及原始问题)中,我们实际上处理的是一张400x600的图像,而不是600x400的图像。 - Efreeto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接