将图像拆分为通道的优化问题
optimization issue with splitting an image into channels
这是我的代码,我的 "algorithm" 正在尝试拍摄拜耳图像或 RGB 图像,并将通道 G(即亮度(甚至灰度))分离到图像的不同通道中颜色,
拜耳模式示例
void Utilities::SeparateChannels(int* channelR, int* channelG, int* channelB, double*& gr, double*& r, double*& b, double*& 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)
{
//grbg
case 0:
for (int j = 0; j < _width; j++)
{
for (int i = 0; i < _height; i++)
{
if (i % 2 == 0 && j % 2 == 0)
{
gr[counter_GR] = channelG[i*_width+ j];
counter_GR++;
}
else if (i % 2 == 0 && j % 2 == 1)
{
r[counter_R] = channelG[i*_width+ j];
counter_R++;
}
else if (i % 2 == 1 && j % 2 == 0)
{
b[counter_B] =channelG[i*_width+ j];
counter_B++;
}
else if (i % 2 == 1 && j % 2 == 1)
{
gb[counter_GB] = channelG[i*_width+ j];
counter_GB++;
}
}
}
我 运行 70 张图像的分析器,我附上了我的结果。
你能建议一种优化我的代码的方法吗?
交换循环,首先遍历高度。然后你可以在第二个循环之前计算 i * _width 并计算这 1 次而不是 _width 次。
您在第一个 if
中测试 i%2==0
,然后在第二个 if
中再次测试它,然后在第三个 [=12] 中测试是否 i%2==1
=] 又在第四个。如果你嵌套了你的 if 语句那么你就不必继续测试,如果你知道 i%2 != 0
你可以推断它必须是 1,就像 j.
if(i%2==0){
if(j%2==0){
}else{
// j%2 is pretty likely to be 1
}
}else{
// i%2 is pretty likely to be 1
}
事实上,你可以走得更远...如果 j 是你的行计数器,它不会在任何行中一直变化,所以你可以在每一行的开头做一个测试然后执行根据您是在奇数行还是偶数行而不同的循环,而不测试每个像素的行索引。
整个算法可以简化为一个内部循环,它将输入数组的一部分去交织成 2 个单独的输出数组。 2 个输出数组每行都在变化,它们的选择取决于输入类型 (_colorOrder
)。
所以..首先将你的算法改成这样:
void Utilities::SeparateChannels(int* channelR, int* channelG, int* channelB, double*& gr, double*& r, double*& b, double*& 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;
double *split1, *split2;
switch (_colorOrder)
{
//grbg
case 0:
for (int i = 0; i < _height; i++)
{
if(i % 2 == 0)
{
split1 = gr + counter_GR;
split2 = r + counter_R;
counter_GR += _width / 2;
counter_R += _width / 2;
}
else
{
split1 = b + counter_B;
split2 = gb + counter_GB;
counter_B += _width / 2;
counter_GB += _width / 2;
}
int *channel = channelG + (i * _width);
// deinterleave(channel, split1, split2, _width);
}
现在您需要做的就是将 channel
去交错成 split1
和 split2
超过 _width
个元素。在优化的(ASM?)内联函数中执行此操作。
这是我的代码,我的 "algorithm" 正在尝试拍摄拜耳图像或 RGB 图像,并将通道 G(即亮度(甚至灰度))分离到图像的不同通道中颜色,
拜耳模式示例
void Utilities::SeparateChannels(int* channelR, int* channelG, int* channelB, double*& gr, double*& r, double*& b, double*& 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)
{
//grbg
case 0:
for (int j = 0; j < _width; j++)
{
for (int i = 0; i < _height; i++)
{
if (i % 2 == 0 && j % 2 == 0)
{
gr[counter_GR] = channelG[i*_width+ j];
counter_GR++;
}
else if (i % 2 == 0 && j % 2 == 1)
{
r[counter_R] = channelG[i*_width+ j];
counter_R++;
}
else if (i % 2 == 1 && j % 2 == 0)
{
b[counter_B] =channelG[i*_width+ j];
counter_B++;
}
else if (i % 2 == 1 && j % 2 == 1)
{
gb[counter_GB] = channelG[i*_width+ j];
counter_GB++;
}
}
}
我 运行 70 张图像的分析器,我附上了我的结果。 你能建议一种优化我的代码的方法吗?
交换循环,首先遍历高度。然后你可以在第二个循环之前计算 i * _width 并计算这 1 次而不是 _width 次。
您在第一个 if
中测试 i%2==0
,然后在第二个 if
中再次测试它,然后在第三个 [=12] 中测试是否 i%2==1
=] 又在第四个。如果你嵌套了你的 if 语句那么你就不必继续测试,如果你知道 i%2 != 0
你可以推断它必须是 1,就像 j.
if(i%2==0){
if(j%2==0){
}else{
// j%2 is pretty likely to be 1
}
}else{
// i%2 is pretty likely to be 1
}
事实上,你可以走得更远...如果 j 是你的行计数器,它不会在任何行中一直变化,所以你可以在每一行的开头做一个测试然后执行根据您是在奇数行还是偶数行而不同的循环,而不测试每个像素的行索引。
整个算法可以简化为一个内部循环,它将输入数组的一部分去交织成 2 个单独的输出数组。 2 个输出数组每行都在变化,它们的选择取决于输入类型 (_colorOrder
)。
所以..首先将你的算法改成这样:
void Utilities::SeparateChannels(int* channelR, int* channelG, int* channelB, double*& gr, double*& r, double*& b, double*& 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;
double *split1, *split2;
switch (_colorOrder)
{
//grbg
case 0:
for (int i = 0; i < _height; i++)
{
if(i % 2 == 0)
{
split1 = gr + counter_GR;
split2 = r + counter_R;
counter_GR += _width / 2;
counter_R += _width / 2;
}
else
{
split1 = b + counter_B;
split2 = gb + counter_GB;
counter_B += _width / 2;
counter_GB += _width / 2;
}
int *channel = channelG + (i * _width);
// deinterleave(channel, split1, split2, _width);
}
现在您需要做的就是将 channel
去交错成 split1
和 split2
超过 _width
个元素。在优化的(ASM?)内联函数中执行此操作。