【问题标题】:A Memory buffer for multiple images多个图像的内存缓冲区
【发布时间】:2013-08-02 16:04:02
【问题描述】:

我在 PC 上接收来自两个摄像头的图像。流不是连续的,而是在事件检测时发生。因此,我必须在特定时间后收到大约 8-10 对图像。由于我必须处理图像,我想先将所有图像保存在一个大缓冲区中,然后再批量处理它们。将图像保存在两个大缓冲区(每个相机一个)中也是可以接受的。如何将这对图像保存在一个(或两个)大缓冲区中?我正在用 C 语言实现这个程序。

【问题讨论】:

  • 如果你是用 C 来实现这个程序,你为什么要标记你的问题 C++?
  • 信息不足。哪个操作系统?您使用的是哪个图像库。内存限制?
  • 我正在开发 UBUNTU。我只使用 C 函数通过 UDP 接收图像并保存它们(fwrite,我还没有集成任何图像处理)。顺便说一句,我有足够的内存来保存图像,直到它们被处理/保存。

标签: c image


【解决方案1】:

假设获取图片的API如下:

int ImageGet(
  char * pBuffer, 
  size_t * pSize); /* returns 0 on success or any other value if no image is available or on error */

您可以执行以下操作:

#include <stdlib.h>
#include <string.h>

...

#define IMAGESIZE_MAX (1024*1024) 

char * pBuffer = NULL;
char * pBufferCurrent = pBuffer;
int iResult = 0;
size_t size = IMAGESIZE_MAX;
size_t sizeTotal = 0;

do 
{
  char * pBufferCurrent = realloc (
    pBuffer, 
    sizeTotal + sizeof(size) + size);

  if (!pBufferCurrent)
  {
    break;
  }

  pBuffer = pBufferCurrent;

  pBufferCurrent += sizeTotal;

  if ((iResult = ImageGet (
    pBufferCurrent + sizeof(size), 
    &size))
  {
    break; 
  }

  memcpy (
    pBufferCurrent,
    &size, 
    sizeof(size));

  sizeTotal += (sizeof(size) + size);
} while (1);

...

这会按顺序存储您的数据:

[     size 1     ][  image data 1  ][     size 2     ][  image data 2  ]...
<-sizeof(size_t)-><-    size 1    -><-sizeof(size_t)-><-    size 2    ->

pBuffer指向的缓冲区中。


要从缓冲区pBuffer 中检索对描述图像 N 的数据的引用,您可以使用以下方法:

const char * BufferImageGetByIndex(
    const char * pBuffer,
    unsigned indexImage)
{
  for (unsigned indexImageCnt = 0;
    indexImageCnt < indexImage;
    ++ indexImageCnt)
  {
    pBuffer += sizeof(size_t) + *((size_t *) pBuffer);
  }

  return pBuffer;
}

然后要实际获取图像,您可以这样做:

...
/* Get a reference to the data decribing **fourth** image in the buffer filled by the example above. */
const char * pBufferImage4 = *BufferImageGetByIndex(pBuffer, 3);

/* Get the size ... */
size_t sizeImage4 = *((size_t *) pBufferImage4);
/* ... and a reference to the image data. */
const char * pImage4 = pBufferImage4 + sizeof(size_t);
...

【讨论】:

  • 一个小问题:不要将 IMAGESIZE_MAX 定义为需要在每次检查时针对最大值进行评估的乘法,只需将其作为答案 (1084576)。是的,它将被编译为一个简单的 10 位左移,但没有必要随意浪费指令。
  • 我想我可以把这个作为练习留给 OP ... ;-) - 不,老实说,我根本不记得结果,我太懒了启动计算器,甚至更懒得动脑筋了……我觉得现在 1024 字节对于图像缓冲区来说可能是不切实际的小@pg1989
  • 别担心,我非常了解这种感觉。
  • 顺便说一句:IMAGESIZE_MAX 只使用一次! :-) @pg1989
  • 任何值得加盐的编译器都不会看到 (1024*1024) 和 (1048576) 之间的区别。它将识别 (1024*1024) 是不变的并相应地对其进行优化。它不会浪费指令计算它永远。 (顺便说一下,1084576 != (1024*1024))
【解决方案2】:

假设您的图像都是标准大小和格式,您可以简单地 malloc() 一个缓冲区,该缓冲区将在事件检测时保存所有图像。如果您希望对图像进行任何分析,我建议您切换到 C++ 并使用 OpenCV 库。它们在开源图像库中几乎没有并行。

【讨论】:

  • 我使用单个缓冲区(无符号字符 * 缓冲区)通过 UDP 接收单个图像。问题是如何使用可以存储多个图像的缓冲区?
  • 让它成为更大的单个缓冲区?我真的很困惑你到底在问什么。您想知道在缓冲区中存储数据的最佳方式是什么?
猜你喜欢
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 2011-03-31
  • 1970-01-01
  • 2012-01-27
相关资源
最近更新 更多