我有一个平坦的字节RGB值数组,它们是R1 G1 B1 R2 G2 B2 R3 G3 B3 ... Rn Gn Bn 所以我的数据看起来像:

char imageData[WIDTH * HEIGHT * 3];

但我想将WIDTH * HEIGHT数组传递给现有的C库,该库需要这个数据的单个平面。 这将只是R值(或只是G,或只是B)的序列。

分配新数组并复制数据(duh)很容易。 但是图像非常大。 如果它不是一个C库,而是采用某种迭代接口来精细化“切片”遍历,那就太棒了。 但是我无法编辑我正在调用的代码......它需要一个普通的旧指针来指向顺序内存块。

但是我有对这个数组的写访问权限。 创建一个将其分类为彩色平面的例程是可行的。 我还需要一个可以反转的反向转换,但是根据定义,将它分类为平面的相同方法可以应用于取消它。

我能够(到位)将这个阵列转换为R1 R2 R3 ... Rn G1 G2 G3 ... Gn B1 B2 B3 ... Bn然后再返回? 任何非天真的算法?

===============>>#1 票数:1

本文“In-Shuffle的简单就地算法”描述了如何转置2 * N的矩阵并给出了如何在其他情况下进行的提示,因此3 * N也是可能的。 这个对其他问题的回答表明它确实是可能的。

或者使用将每个值写入其转置位置的算法,然后对该位置的值执行相同的操作,依此类推,直到连接循环。 在位向量中标记处理的值。 并继续,直到这个向量全是1。

这两种算法都不是缓存友好的。 可能一些巧妙使用PREFETCH指令可以改善这一点。

编辑:

C ++,RGB到单平面,未优化:

#include <iostream>
#include <bitset>
#include <vector>

enum {N = 8};

void transpose(std::vector<char>& a)
{
  std::bitset<3*N> b;

  for (int i = 1; i < 3*N; ++i)
  {
    if (b[i])
      continue;

    int ptr = i;
    int next;
    char nextVal = a[i];

    do {
      next = ptr/3 + N*(ptr%3);
      char prevVal = nextVal;
      nextVal = a[next];
      a[next] = prevVal;
      ptr = next;
      b[ptr] = true;
    }
    while (ptr != i);
  }
}

int main()
{
  std::vector<char> a(3*N);

  for (int i = 0; i != 3*N; ++i)
    a[i] = i;

  transpose(a);

  for (int i = 0; i != 3*N; ++i)
    std::cout << (int)a[i] << std::endl;

  return 0;
}

我的初衷是使用大小为WIDTH HEIGHT的位向量,这会产生WIDTH HEIGHT / 8的开销 但是总是有可能牺牲空间的速度。 位向量可以是大小WIDTH或HEIGHT或任何期望值,甚至是0.技巧是保持指向单元的指针,在此之前所有值都被转置。 位向量用于从该指针开始的单元格。 在全部为1之后,将其移动到下一个位置,然后执行除实际数据移动之外的所有算法步骤。 并且位向量已准备好继续转置。 该变体是O(N ^ 2)而不是O(N)。

EDIT2:

PREFITCH优化并不难实现:只需计算索引,调用PREFETCH,并将索引放入队列(ringbuffer),然后从队列中获取索引并移动数据。

EDIT3:

其他算法的概念,即O(1)大小,O(N * log(N))时间,是缓存友好的并且可能比“循环”算法更快(对于图像大小<1Gb):

  • 将N * 3矩阵拆分为几个3 * 3的char矩阵并转置它们
  • 将结果拆分为char [3]的3 * 3矩阵并转置它们
  • 矩阵大小小于数组大小时继续
  • 现在我们有最多3 * 2 * log3(N)的订购件。 加入他们。
  • 首先加入相同尺寸的件。 可以使用长度为4的非常简单的“循环”。
  • 用反向加入不等大小的碎片(反向(a),反向(b))

===============>>#2 票数:1

如果你只需要一架飞机,这似乎很容易。 如果你需要全部3,你可能会有更复杂的算法运气。

void PlanarizeR(char * imageData, int width, int height)
{
    char *in = imageData;
    int pixelCount = width * height;
    for (int i = 0;  i < pixelCount;  ++i, in+=3)
        std::swap(*in, imageData[i])
}

从高到低向后运行循环以反转过程应该不会太难。

===============>>#3 票数:0

char *imageData = malloc (WIDTH * HEIGHT * 3 * sizeof(char));

这个功能做这个R1 R2 R3 ... Rn G1 G2 G3 ... Gn B1 B2 B3 ... Bn ,,

char *toRGB(char *imageData, int WIDTH, int HEIGHT){
    int len = WIDTH * HEIGHT;
    char *RGB = malloc (len * sizeof(char));
    int i, j = 0,flag = 0;

    for(i=0 ; i<=len ; i++, j+=3){
        if(j<len)
            RGB[i] = imageData[j];
        else{
            switch(flag){
                case 0: j=-2; flag=1; break;   // j=-2 the next iteration will start at j=1
                case 1: j=-1; break;   // j=-1 the next iteration will start at j=2
            }
        }
    }
    return RGB;
}

  ask by HostileFork translate from so

未解决问题?本站智能推荐:

1回复

在c中切割数组或结构的函数

我已经写了一个函数来切片c中的数组,但它返回我认为的地址。 我做了一次正确的工作,但我搞砸了某个地方,任何帮助将不胜感激。 〜 更新,切片数组工作正常,但我想结构到目前为止,我已编写以下代码。 我得到他跟随错误:从不兼容的指针类型分配[默认启用] ptr_A =&A; 〜
6回复

这种RGB到XYZ色彩空间转换算法有什么问题?

我的目标是将RGB像素转换为CIELab色彩空间,以便在CIELab中进行一些特殊的计算。 为此,我必须首先将RGB转换为XYZ,这是非常困难的部分。 我试图在Objective-C中实现这个算法(虽然大多使用普通的C),但结果是错误的。 我的代码基于easyrgb.com提供的伪
1回复

高效遍历二维数组中所有邻居对(2点团)的算法

我需要遍历彼此相邻的图像中的所有(无序)像素对,而无需重复。 我正在使用8点社区。 例如: 像素f的邻居在其周围的3x3正方形中。 因此,例如, g与f形成2点集团。 如果我要遍历图像的所有行和列,则此派系将被计数两次,一次是当f是中心像素,一次是g是中心像素。 其他集团也会发
2回复

图像比较算法

请考虑以下用例, 我有一个更大的图像,让我们称为主图像。 现在从其他地方,我得到一个小图像。 我想检查这个小图像是否是主图像的子集。 重点是,较小的图像可能具有不同的文件格式,较小的图像可能从相对不同的视图中捕获。 较小的图像可能具有不同的光强度。 在算法/计
1回复

YUY2比例尺算法

是否有人可以使用C / C ++中的YUY2压缩格式缩放例程,而无需中间转换为另一个颜色空间? 我不能使用IPP之类的任何库,因为它是嵌入式Linux系统... 理想情况下,此类函数应具有以下声明: bool YUY2_scale(uint8_t * in_buf,int in_w
1回复

将大块文本转换为图像的算法? (由图像边缘定义)[关闭]

我有大量的单词,希望以有趣的方式显示其统计信息。 我想打印每个单词,但是要在图像轮廓的边缘打断(由某种颜色指定),以便整体上所有的文本都形成图像。 我意识到没有一个例子就很难理解,因此可以从这张图片中看到我想要达到的目标,在这张图片中,《爱丽丝梦游仙境》的文字被打印出来,形成了爱丽丝和书
1回复

在dcraw的gamma_curve中实现的算法的名称是什么?

Dcraw包含以下用于处理图像颜色的算法: https : //gist.github.com/1047302 。 它是正式的(命名的)图像处理算法吗? 如果不是,我应该读什么才能理解其背后的原因?
3回复

是否已知CIEDE2000或CIE94 Delta-E色差计算算法的实现?

我需要计算两种颜色之间的Delta-E距离。 在CIELab颜色空间中使用两种颜色执行此操作的算法如下所示: 是否有已知的此算法的开源实现? 这并不难实现,但是从我上次尝试实现色彩空间转换算法开始,我不想在已经上路并经过测试的情况下重新开发轮子。 CIEDE2000也会更好,更
5回复

是否有一个好的库或算法可以帮助将平面图像快速转换为交错图像(C ++)?

我正在开发一个视频播放应用程序,它将逐帧显示包含原始平面图像数据的视频文件。 它包含的数据是8位rgb(目前没有alpha)。 此处的硬件仅接受交错的图像数据。 结果,我需要将平面图像数据转换为交错图像数据。 我要做的是在平面数据上记忆或记忆。 但是,在处理高清内容时,由于数据是原始数
3回复

在每个像素的8个邻接处计算最大像素灰度值的最快方法

我想在给定图像中每个像素的8个邻接处计算最大像素灰度值。 我正在使用下面的代码在C中实现它。 上面的代码按预期工作。 但是,这似乎很缓慢。 是否有提高速度的改进范围?