首页新闻找找看学习计划

快速高斯模糊 及 相关问题

0
[待解决问题]

经由厉害博主Imageshop的博文http://www.cnblogs.com/Imageshop/archive/2013/01/07/2849782.html提示,

我这里实现了高斯模糊函数,但是有一下几点问题向各位讨教探讨:

①这个函数处理速度没有Imageshop博主描述的速度快,如何提高效率。

②高斯模糊后感觉整幅图像会向右下角平移一定距离,没有详细研究过算法本身,这样是否为正常,有何解决方案,大家一起探讨。(反正我用高斯模糊后图像载进行USM锐化得到了我觉得很不理想的结果,原因应该就是这个平移造成的)

③高手帮看看我这个函数是否本身就有错

我做的工作很简单

①我将contrast-retinex.c中关于高斯模糊的代码全集中在一个函数中,使这个此函数更加独立。这样也减少了一些内存分配释放的次数

②纵向处理后将数据指针in和out直接对调处理,省去了在此不值一提的拷贝过程

③调用这个函数实现高斯模糊查看结果

现在将代码及结果贴出:

/****************************************
*    src        : 原始图像数据                *
*    dst        : 模糊后图像数据            *
*    width    : 图像宽                    *
*    height    : 图像高                    *
*    sigma    : 高斯参数                    *
*    chan    : 图像通道数                *
*****************************************/
void IMG_GaussBlur(unsigned char* src, unsigned char*& dst, int width, int height, float sigma, int chan)
{
    int    i            = 0;
    int    row            = 0;
    int    col            = 0;
    int    pos            = 0;
    int    channel        = 0;
    int    n            = 0;
    int    bufsize        = 0;        
    int size        = 0;
    int rowstride    = 0;
    int    channelsize = width*height;

    if (width>height)
    {
        bufsize = width+3;
    }
    else
    {
        bufsize = height+3;
    }    

    float* w1    = (float *) malloc (bufsize * sizeof (float));
    float *w2    = (float *) malloc (bufsize * sizeof (float));
    float *in    = (float *) malloc (channelsize * sizeof (float));
    float *out    = (float *) malloc (channelsize * sizeof (float));

//----------------计算高斯核---------------------------------------//
    //compute_coefs3(coef, sigma);    
    float  q    = 0; 
    float  q2, q3;
    double b[4] = {0};
    double B    = 0;
    int    N    = 3;

    if (sigma >= 2.5)
    {
        q = 0.98711 * sigma - 0.96330;
    }
    else if ((sigma >= 0.5) && (sigma < 2.5))
    {
        q = 3.97156 - 4.14554 * (float) sqrt ((double) 1 - 0.26891 * sigma);
    }
    else
    {
        q = 0.1147705018520355224609375;
    }

    q2 = q * q;
    q3 = q * q2;
    b[0] = (1.57825+(2.44413*q)+(1.4281 *q2)+(0.422205*q3));
    b[1] = (        (2.44413*q)+(2.85619*q2)+(1.26661 *q3));
    b[2] = (                   -((1.4281*q2)+(1.26661 *q3)));
    b[3] = (                                 (0.422205*q3));
    B = 1.0-((b[1]+b[2]+b[3])/b[0]);    
//----------------计算高斯核结束---------------------------------------//
    
    // 处理图像的多个通道
    for (channel = 0; channel < chan; channel++)
    {
        // 获取一个通道的所有像素值
        for (i = 0, pos = channel; i < channelsize ; i++, pos += chan)
        {
            /* 0-255 => 1-256 */
            in[i] = (float)(src[pos] + 1.0);
        }

        //纵向处理
        for (row=0 ;row < height; row++)
        {
            pos =  row * width;        
            //gausssmooth(in + pos, out + pos, width, 1, &coef);
            size        = width;
            rowstride    = 1;    
            bufsize        = size+3;
            size        -= 1;

            w1[0] = (in + pos)[0];
            w1[1] = (in + pos)[0];
            w1[2] = (in + pos)[0];

            for ( i = 0 , n=3; i <= size ; i++, n++)
            {
                w1[n] = (float)(B*(in + pos)[i*rowstride] +
                    ((b[1]*w1[n-1] +
                    b[2]*w1[n-2] +
                    b[3]*w1[n-3] ) / b[0]));
            }

            /** backward pass */
            w2[size+1]= w1[size+3];
            w2[size+2]= w1[size+3];
            w2[size+3]= w1[size+3];
            for (i = size, n = i; i >= 0; i--, n--)
            {
                w2[n]= (out + pos)[i * rowstride] = (float)(B*w1[n] +
                    ((b[1]*w2[n+1] +
                    b[2]*w2[n+2] +
                    b[3]*w2[n+3] ) / b[0]));
            }    
        }

        //下面的横向处理直接将数据 out 与 in 对调 省去memcpy
        //memcpy(in,  out, channelsize * sizeof(float));
        //memset(out, 0  , channelsize * sizeof(float));

        //横向处理
        for (col=0; col < width; col++)
        {                
            //gausssmooth(out + col, in + col, height, width, &coef);            
            size        = height;
            rowstride    = width;    
            bufsize        = size+3;
            size        -= 1;

            w1[0] = (out + col)[0];
            w1[1] = (out + col)[0];
            w1[2] = (out + col)[0];
            for ( i = 0 , n=3; i <= size ; i++, n++)
            {
                w1[n] = (float)(B*(out + col)[i*rowstride] +
                    ((b[1]*w1[n-1] +
                    b[2]*w1[n-2] +
                    b[3]*w1[n-3] ) / b[0]));
            }
            
            w2[size+1]= w1[size+3];
            w2[size+2]= w1[size+3];
            w2[size+3]= w1[size+3];
            for (i = size, n = i; i >= 0; i--, n--)
            {
                w2[n]= (in + col)[i * rowstride] = (float)(B*w1[n] +
                    ((b[1]*w2[n+1] +
                    b[2]*w2[n+2] +
                    b[3]*w2[n+3] ) / b[0]));
            }                
        }

        //拷贝结果到函数输出指针
        for (i = 0, pos = channel; i < channelsize ; i++, pos += chan)
        {            
            dst[pos] = in[i]-1;
        }
    }

    free (w1);
    free (w2);
    free (in);
    free (out);
}
View Code

调用方法:

Mat src = imread(".\test.jpg");
Mat dst = imread(".\test.jpg");
IMG_GaussBlur(src.data, dst.data, src.cols, src.rows,  2.0, 3); 
//保存或显示结果,略...

执行结果:

sigma=2.0

379   x 513     耗时   61ms

 

sigma=5.0

2304 x 1728  耗时   1870ms

utopiaT的主页 utopiaT | 菜鸟二级 | 园豆:202
提问于:2013-09-06 16:42
< >
分享
所有回答(1)
0

博问可以贴代码,点击编辑器中倒数第2个按钮

dudu | 园豆:38703 (高人七级) | 2013-09-06 16:45

谢谢!已调整。

支持(0) 反对(0) utopiaT | 园豆:202 (菜鸟二级) | 2013-09-06 16:51
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册