我正在尝试使用cv::cvtColor将一个320x240的NV21图像转换为RGBA图像,而不需要分配新内存。
因此,我尝试了各种方法来实现这一目标。我知道cv::cvtColor调用cv::Mat.create(..)为输出Mat分配内存,并且我已经看到cv::Mat.create(...)仅在所请求的Mat的大小和类型与其当前值不同时才分配新内存。
鉴于这些情况,以下是:
//(1)
cv::Mat frame(height + height / 2, width, CV_8UC1, pointerToNV21Data);
//(2)
cv::cvtColor(frame, frame, cv::COLOR_YUV2RGBA_NV21);
分配一个新的连续内存区域,大小为320 * 240 * 4通道 = 307200
字节(之前是空闲内存),并且放弃之前分配的320 * 360 * 1通道 = 115200
字节。
当cv::cvtColor
内部调用cv::Mat.create(...)
时,会分配新的内存块,因为:
- 在
cv::cvtColor
之前,frame是一个尺寸为320x360、具有1个通道的cv::Mat
cv::cvtColor
要求它是一个尺寸为320x240、具有4个通道的cv::Mat
所以,我最乐观的解决方案是执行以下操作:
//allocate a byte buffer of 307200 bytes
uchar largeBuffer[307200];
//make sure the 115200 NV21 image bytes are written to the buffer
writeNV21DataToBuffer(largeBuffer);
//create cv::Mat that wraps "largeBuffer" as a NV21 image
cv::Mat frameNV21(height + height / 2, width, CV_8UC1, largeBuffer);
//create a second cv::Mat that wraps around the same "largeBuffer",
//but this time consider it as pointing to a RGBA image
cv::Mat frameRGBA(height, width, CV_8UC4, largeBuffer);
//call cv::cvtColor
cv::cvtColor(frameNV21, frameRGBA, cv::COLOR_YUV2RGBA_NV21);
通过这样做,确实没有分配新的内存。打印
frameNV21
、frameRGBA
在cv::cvtColor
之前和之后的cv::Mat.dataStart
& cv::Mat.dataStart
,证实了使用相同的内存区域,并且结果没有为新的内存分配空间。然而...转换本身并没有正确完成,当在屏幕上显示时,结果看起来像这样:
在这一点上,我已经没有主意了。我的最后一个方法本质上是错误的,还是没有办法实现这个目标?
cvtColor
函数,然后重新构建。我认为这可能是更简单的方法。 - Elvis Dukaj