IIR型高斯濾波的原理及實現


二、實現

GIMP中有IIR型高斯濾波的實現,代碼位於contrast-retinex.c中,讀者可自行查看。下面給出本人實現的核心代碼:

#include"stdafx.h"
typedef struct
{
    float B;
    float b[4];
} gauss_coefs;

//參數計算
void compute_coefs3(gauss_coefs *c,float sigma)
{
    float q, q2, q3;
    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 ((float) 1 - 0.26891 * sigma);
    }
    else
    {
        q = 0.1147705018520355224609375;
    }
    q2 = q * q;
    q3 = q * q2;
    c->b[0] = 1/(1.57825+(2.44413*q)+(1.4281 *q2)+(0.422205*q3));
    c->b[1] = (        (2.44413*q)+(2.85619*q2)+(1.26661 *q3)) *c->b[0];
    c->b[2] = (                   -((1.4281*q2)+(1.26661 *q3)))*c->b[0];
    c->b[3] = (                                 (0.422205*q3)) *c->b[0];
    c->B = 1.0-(c->b[1]+c->b[2]+c->b[3]);

}

//IIR型高斯濾波
//**************************************************************//
//參考文獻:Recursive implementation of the Gaussian filter
//Src:輸入圖像
//Dest:輸出圖像
//sigma:高斯標准差
//**************************************************************//
IS_RET  IIRGaussianFilter(TMatrix *Src,TMatrix *Dest,float sigma)
{
    int X,Y,Width=Src->Width,Height=Src->Height,Stride=Src->WidthStep,Channel=Src->Channel;
    gauss_coefs  c;
    compute_coefs3(&c,sigma);
    unsigned char *LinePS,*LinePD;
    float *Buff,*BPointer,*w1,*w2;    
    Buff=(float*)malloc(sizeof(float)*Height*Width);//緩存
    if(Buff==NULL){return IS_RET_ERR_OUTOFMEMORY;}
    for(int i=0;i<Channel;i++)
    {
        LinePS=Src->Data+i;
        LinePD=Dest->Data+i;
        //拷貝原圖至緩存Buff
        BPointer=Buff;
        for (Y=0;Y<Height;Y++)
        {
            for (X=0;X<Width;X++)
            {
                BPointer[0]=float(LinePS[0]);
                BPointer++;
                LinePS+=Channel;
            }
            LinePS+=Stride-Width*Channel;
        }
        //橫向濾波
        BPointer=Buff;
        w1=(float*)malloc(sizeof(float)*(Width+3));
        if(w1==NULL){return IS_RET_ERR_OUTOFMEMORY;}
        w2=(float*)malloc(sizeof(float)*(Width+3));
        if(w2==NULL){return IS_RET_ERR_OUTOFMEMORY;}
        for(Y=0;Y<Height;Y++)
        {
            //前向濾波
            w1[0]=w1[1]=w1[2]=BPointer[0];
            for(int n=3,i=0;i<Width;n++,i++)
            {
                w1[n]=c.B*BPointer[i]+(c.b[1]*w1[n-1]+c.b[2]*w1[n-2]+c.b[3]*w1[n-3]);
            }
            //后向濾波
            w2[Width]=w2[Width+1]=w2[Width+2]=w1[Width+2];
            for(int n=Width-1;n>=0;n--)
            {
                BPointer[n]=w2[n]=c.B*w1[n+3]+(c.b[1]*w2[n+1]+c.b[2]*w2[n+2]+c.b[3]*w2[n+3]);
            }
            BPointer+=Width;
        }

        //縱向濾波
        BPointer=Buff;
        w1=(float*)realloc(w1,sizeof(float)*(Height+3));
        if(w1==NULL){return IS_RET_ERR_OUTOFMEMORY;}
        w2=(float*)realloc(w2,sizeof(float)*(Height+3));
        if(w2==NULL){return IS_RET_ERR_OUTOFMEMORY;}
        for (X=0;X<Width;X++)
        {
            //前向濾波
            w1[0]=w1[1]=w1[2]=BPointer[0];
            for(int n=3,i=0;i<Height;n++,i++)
            {
                w1[n]=c.B*BPointer[i*Width]+(c.b[1]*w1[n-1]+c.b[2]*w1[n-2]+c.b[3]*w1[n-3]);
            }
            //后向濾波
            w2[Height]=w2[Height+1]=w2[Height+2]=w1[Height+2];
            for(int n=Height-1;n>=0;n--)
            {
                BPointer[n*Width]=w2[n]=c.B*w1[n+3]+(c.b[1]*w2[n+1]+c.b[2]*w2[n+2]+c.b[3]*w2[n+3]);
            }
            BPointer++;
        }
        //拷貝緩存至結果
        BPointer=Buff;
        for(Y=0;Y<Height;Y++)
        {
            for(X=0;X<Width;X++)
            {
                LinePD[0]=BPointer[0];
                if(BPointer[0]>255)LinePD[0]=255;
                if(BPointer[0]<0)LinePD[0]=0;    
                BPointer++;
                LinePD+=Channel;
            }
            LinePD+=Stride-Width*Channel;
        }
        free(w1);
        free(w2);
    }
    return IS_RET_OK;
}

實驗結果:對一幅1024*1024的彩色圖像,算法耗時175ms。

參考文獻

Young I T, Van Vliet L J. Recursive implementation of the Gaussian filter[J]. Signal processing, 1995, 44(2): 139-151.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM