opencv 从缓冲区读取 jpeg 图像

Posted

技术标签:

【中文标题】opencv 从缓冲区读取 jpeg 图像【英文标题】:opencv read jpeg image from buffer 【发布时间】:2013-01-21 13:04:30 【问题描述】:

我有一个包含 jpeg 图像数据的 unsigned char* 缓冲区。我想使用 c++ 和 opencv 显示该图像。如果我这样做:

Mat img(Size(640, 480), CV_8UC3, data);
namedWindow("image", 1);
imShow("image", img);

我得到一堆嘈杂的像素。

我想这是因为数据是 jpeg(带有标题)。因为这行得通:

Mat imgbuf(Size(640, 480), CV_8UC3, data);
Mat img = imdecode(imgbuf, CV_LOAD_IMAGE_COLOR);

但是我不能使用 imdecode 函数,因为它来自基于 GTK 2 的 highgui.h,在我的项目中我使用 GTK 3。

那么,如何显示缓冲区数据?有没有办法在opencv中解码jpeg图像而不是imdecode,如果这是问题的话。我真的不想用 Qt 重建 opencv...

还有其他建议吗?

(使用 Linux)

【问题讨论】:

您不能使用libjpeg 进行解码并完成它吗?这有什么问题? @mmgp 我会尝试 libjpeg,只是想我可以在不包含另一个库的情况下做同样的事情。 如果没有libjpeg,opencv 不会加载 jpeg 图像,因此没有包含其他库。 哇,你的所作所为真的不行。在您的 Mat imgbuf(...) 行中,您读取 640x480x3 字段中的数据。由于 jpeg 是压缩的,因此 jpeg 确实可以轻松放入其中。所以其余的点然后用内存中的随机数据填充,这非常非常糟糕。之后,您加载 Mat,其中包括 JPEG 和一堆随机内存数据,并对其进行解码。相反,首先将您的 unsigned char 缓冲区放入与缓冲区大小完全相同的向量或 mat 中,然后将其输入 imdecode。 【参考方案1】:

我在网上看到很多关于这个问题的回答说你应该直接调用libjpeg并绕过OpenCV的imread()例程。

这不是必需的!您可以使用 imdecode() 从内存中解码原始图像缓冲区。这样做的方法不直观,并且没有足够的文档来帮助第一次尝试这样做的人。

如果您有原始文件数据的指针/大小(fread() 直接来自 .jpg、.png、.tif、文件等...

int    nSize = ...       // Size of buffer
uchar* pcBuffer = ...    // Raw buffer data


// Create a Size(1, nSize) Mat object of 8-bit, single-byte elements
Mat rawData( 1, nSize, CV_8UC1, (void*)pcBuffer );

Mat decodedImage  =  imdecode( rawData /*, flags */ );
if ( decodedImage.data == NULL )   

    // Error reading raw image data

就是这样!

希望这对将来的人有所帮助。

【讨论】:

它确实帮助了某人。请注意,您使用了“size”而不是“nsize”,并且可以直接从构造函数初始化 rawData。 这对我不起作用。从网络流中读取图像,保存到文件工作,但调用 imdecode 给我一个灰色窗口 cv::imshow("Window", decodedImage) @aCuria 这可能是因为你忘了把 cv2.waitKey(0) 放在 imshow() 之后 这是很久以前的,但我可以显示其他图像(从文件加载),所以我认为 waitKey 不是问题。 不需要(void*),并且在imdecode中设置所需的标志(cv::IMREAD_COLOR)应该可以解决问题。【参考方案2】:

我已使用libjpeg 使用“解压缩详细信息”下libjpeg API documentation 中描述的标准程序解压JPEG 图像。

解压数据后,您可以使用它来构造cv::Mat。请注意,解压后的图像是 RGB 格式,而 openCV 使用 BGR 格式,因此需要使用格式为 CV_RGB2BGRcvtColor() 操作。

【讨论】:

以上是关于opencv 从缓冲区读取 jpeg 图像的主要内容,如果未能解决你的问题,请参考以下文章

C++ + OpenCV = 访问冲突读取位置 0x02176000

使用libjpeg C ++ Library从JPEG图像中提取RGB

Python-Opencv 在内存缓冲区上写入 x264 视频

在opencv中读取视频文件的连续图像

OpenCV读写图像文件解析

java glReadpixels 到 OpenCV 垫