将图像分割为通道的优化问题

时间:2015-07-08 11:02:28

标签: c++ image-processing optimization

enter image description here

这是我的代码,我的“算法”试图拍摄拜耳图像或RGB图像,并将通道G(即Luma(或甚至灰度)分离到不同的颜色通道中,

拜耳模式的一个例子

enter image description here

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张图片上运行了探查器,我附上了我的结果。 你能建议一种优化我的代码的方法吗?

3 个答案:

答案 0 :(得分:2)

交换循环,首先迭代高度。然后你可以在第二个循环之前计算i * _width并计算这1次而不是_width次。

答案 1 :(得分:1)

您在第一个i%2==0中测试if,然后在第二个if中再次测试,然后测试第三个i%2==1中是否if而在第四个。如果嵌套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 :(得分:1)

整个算法可以简化为内部循环,将输入数组的一部分解交错为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&amp; split2超过_width个元素。在优化的(ASM?)内联函数中执行此操作。