将拜耳图像分离为颜色通道c ++

时间:2014-11-01 23:18:50

标签: c++ performance optimization

我有一张不同拜耳模式的原始图像。 这是我为了分离频道而实施的。 速度在这里非常重要,因为它将在数千个大图像上运行。

请您建议代码优化。 我知道%(modulo)不是很快我怎么能替换它呢?

感谢

void Utilities::SeparateChannels(int** _image, int*& gr, int*& r, int*& b, int*& gb,int _width, int _height, int _colorOrder)
{
    //swith case the color Order
    int counter_R = 0;
    int counter_GR = 0;
    int counter_GB = 0;
    int counter_B = 0;

    switch (_colorOrder)
    {
        //rggb
    case 0:

        for (int i = 0; i < _height; i++)
        {
            for (int j = 0; j < _width; j++)
            {
                if (i % 2 == 0 && j % 2 == 0)
                {
                    r[counter_R] = _image[i][j];
                    counter_R++;
                }
                else if (i % 2 == 0 && j % 2 == 1)
                {
                    gr[counter_GR] = _image[i][j];
                    counter_GR++;
                }
                else if (i % 2 == 1 && j % 2 == 0)
                {
                    gb[counter_GB] = _image[i][j];
                    counter_GB++;
                }
                else if (i % 2 == 1 && j % 2 == 1)
                {
                    b[counter_B] = _image[i][j];
                    counter_B++;
                }
            }
        }
        break;
    default:
        break;
    }    
}

2 个答案:

答案 0 :(得分:1)

可能值得考虑的一种可能性是将目标通道数据的数组设置为数组本身:

int *channels[] = {r, gr, gb, b};

同样,将计数器设置为数组:

int counters[4] = {0};

...那么你的代码可能就是这样的:

for (int i=0; i<_height; i++)
    for (int j=0; j<_width; j++) {
        channel = (i&1) << 1 + (j&1);
        int &counter = counters[channel];

        channels[channel][counter++] = image[i][j];
    }

基本思想是我们将ij的低位组合成一个我们可以用作通道地址的数字。然后我们使用该数字来索引该频道的频道和计数器。

您的编译器可能已经优化了现有代码,大致相当于此(或者甚至可能比这更好),但也有可能不是。

我通常不会期望有很多改进(至少在典型的台式电脑上)。我希望瓶颈是主内存的带宽,几乎与你编写循环的细节无关。

答案 1 :(得分:1)

您应该展开循环以在2x2块中处理。通过这种方式,您将始终了解奇偶校验,而无需对其进行测试。

                r[counter_R] = _image[i][j];
                counter_R++;

                gr[counter_GR] = _image[i][j+1];
                counter_GR++;

                gb[counter_GB] = _image[i+1][j];
                counter_GB++;

                b[counter_B] = _image[i+1][j+1];
                counter_B++;

(也适应循环参数。)