【问题标题】:Split channels from RGB array in C++ without OpenCV在没有 OpenCV 的 C++ 中从 RGB 数组中拆分通道
【发布时间】:2014-02-07 16:58:46
【问题描述】:

我在 C++ 中使用一组 unsigned char 表示图像中的像素。每个像素有 3 个通道 (R,G,B)。图像是线性表示的,有点像

RGBRGBRGBRGB.....

如何有效地将 R、G 和 B 拆分为单独的数组?

我试过了:

  for(int pos = 0; pos < srcWidth * srcHeight; pos++) {
      int rgbPos = pos * 3;
      splitChannels[0][pos] = rgbSrcData[rgbPos];
      splitChannels[1][pos] = rgbSrcData[rgbPos + 1];
      splitChannels[2][pos] = rgbSrcData[rgbPos + 2];
  }

但这出奇的慢。

谢谢!

【问题讨论】:

  • 您是否检查过这个循环需要多长时间才能运行,不包括任何其他代码?它看起来不应该很慢。另外,您有什么理由必须拆分它们吗?如果您需要特定的颜色,为什么不直接循环并使用 pos
  • 是的,它很慢。 3MP 图像大约需要 7 毫秒。我必须拆分它们才能调用另一个库。
  • 嗯,7*10^-3 秒 * 2 GigaHertz(例如)获得 1400 万次操作。 1400 万次操作听起来适合 3MP 图像。至少是正确的数量级。虽然,这是一个非常粗略的估计,我在这方面没有太多经验,所以我可能完全错了,但感觉很合理。
  • 也许有办法让它进入 SSE?移动字节似乎很慢。
  • 二维目标数组是以通道为主的顺序设置的,因此单个像素的三个颜色分量在内存中以 srcWidth*srcHeight 字节分隔,这可能会降低缓存效率。试试 splitChannels[lotsa_pixels][3]。

标签: c++ image optimization image-processing


【解决方案1】:

我的尝试:四乘四加载和存储字节。字节加扰会很繁琐,但可能会提高吞吐量。

// Load 4 interleaved pixels
unsigned int RGB0= ((int*)rgbSrcData)[i];
unsigned int RGB1= ((int*)rgbSrcData)[i + 1];
unsigned int RGB2= ((int*)rgbSrcData)[i + 2];

// Rearrange and store 4 unpacked pixels
((int*)splitChannels[0])[j]= 
    (RGB0 & 0xFF) | (RGB0 >> 24) | (RGB1 & 0xFF0000) | ((RGB2 & 0xFF00) << 16);
((int*)splitChannels[1])[j]= 
    ((RGB0 & 0xFF00) >> 8) | (RGB1 & 0xFF) | (RGB1 >> 24) | (RGB2 & 0xFF0000) >> 16;
((int*)splitChannels[2])[j]= 
    ((RGB0 & 0xFF0000) >> 16) | (RGB1 & 0xFF00) | ((RGB2 & 0xFF) >> 16) | (RGB2 & 0xFF000000);

(注意:未选中!)也可以使用仅移位版本。

SSE 解决方案会更复杂(步幅 3 与 2 的幂不兼容)。

【讨论】:

  • 谢谢,这是个好主意。我试过了,它快了大约 10%。所有的字节序都很难做到正确。
  • 酷!鉴于开销很大,我不确定这是否有效。即使代码有问题,计时测量也应该是指示性的。因此,可能值得从头开始编写代码并节省几个周期......
  • 我实际上不得不放弃它,有一些改进,但还不足以让它变得可行。很难做到正确。
  • 如果你想获得纯粹的性能,那么 MMX/SSSE3 指令 pshufbpunpckxxx 是你最好的朋友。一次加载 3 x 8/16 字节并进行置换。
【解决方案2】:

一个用来让它运行得更快的好技术是循环展开。 你可以在这里阅读:http://en.wikipedia.org/wiki/Loop_unwinding

【讨论】:

  • 它没有帮助。我猜编译器在启用 -O3 时已经这样做了?
  • 你的放松因素是什么?
  • 我没有提供一个因素,只是一个标志? -O3 我相信,但不确定有多少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
  • 2013-02-18
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
相关资源
最近更新 更多