我有一个具有不同拜耳模式的原始图像。这就是我为了分离通道而实现的。速度在这里非常重要,因为这将在成千上万的大图像上运行。
你能建议代码优化吗。我知道%(模)不是很快,例如,我该如何替换它?
感谢
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;
}
}
可能值得考虑的一种可能性是将目标通道数据的阵列设置为阵列本身:
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];
}
其基本思想是,我们将i
和j
的低位组合为一个数字,可以用作通道地址。然后,我们使用该数字来索引通道和该通道的计数器。
您的编译器可能已经在优化现有代码,使其与此代码大致等效(甚至可能比它产生的代码更好),但也有可能不是。
不过,我通常不会期望有太多的改进(至少在一台典型的台式电脑上)。我预计瓶颈是主内存的带宽,几乎与如何编写循环的细节无关。
您应该展开要在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++;
(同时调整回路参数。)