android中的高斯模糊非常慢

时间:2013-07-02 20:25:32

标签: android image-processing blur gaussian

我正在尝试在Android中实现一个简单的高斯模糊,它的工作速度很慢:( 这是相关的代码:

double rSum = 0;
double gSum = 0;
double bSum = 0;
double weightSum = 0;

for(int y = 0; y < originalImage.height ; y++){
    for(int x = 0; x < originalImage.width ; x++){
        int newPixel;

        rSum = 0;
        gSum = 0;
        bSum = 0;
        weightSum = 1;

        for(int row = y-FRAME_OFFSET ; row <= y+FRAME_OFFSET ; row++){
            for(int col = x-FRAME_OFFSET ; col <= x+FRAME_OFFSET ; col++){
                if(originalImage.inBounds(col, row)){
                    double weight = weights[(x-col)*(x-col) + (y-row)*(y-row)];
                    weightSum += weight;

                    int pixel = originalImage.at(col, row);

                    int red =  (pixel >> 16) & 0xFF ;
                    int green = (pixel >> 8) & 0xFF ;
                    int blue = pixel & 0xFF ;

                    rSum += red * weight;
                    gSum += green * weight;
                    bSum += blue * weight;  

                }
            }
        }

        rSum /= weightSum;
        gSum /= weightSum;
        bSum /= weightSum;

        newPixel = Color.rgb((int)rSum, (int)gSum, (int)bSum);                  

        maskedImage.set(x, y, newPixel);
    }
}

如果我在帧FRAME_OFFSET(半径)为15时使用此算法,则在512x512图像上花费约3分钟(!),并且随着我增加偏移量,它会变得更糟。 我的猜测是,这是一个缓存问题,因为当我计算新像素时,我正在访问可能不在缓存中的不同行中的像素。

任何帮助/改进都将受到赞赏。

请注意,我需要自己实现此算法,而不是使用现有的实现。

感谢。

2 个答案:

答案 0 :(得分:1)

2D高斯模糊内核是线性可分的,这意味着它可以表示为两个一维内核的外(列 - 时 - 行)乘积,一个用于图像行,一个用于列。因此,对于M * N图像和ak * k内核,使用此属性的任何简单实现都应该是O(k * M * N),并且可以实现为两遍算法,每次传递执行一次卷积,首先沿着图像行,然后沿图像列。

在某些情况下,可以通过利用高斯核本身的某些属性来加速1D步骤,这允许仅使用整数运算递增地计算加权系数。这是我所知道的最快的实现 - 它可以很容易地移植到Android上的Java:http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html

答案 1 :(得分:0)

使用此lib:https://github.com/jrvansuita/GaussianBlur

像这样实施:

//Asynchronous with scaleDown and changing radius
GaussianBlur.with(context).size(300).radius(10).put(R.mipmap.your_image, imageView);