二維小波變換的源代碼

整理日:2015/4/6
源碼來源: Visual C++小波變換技術與工程實踐code

void CWvltTrans::DWT_Once ( short** spOriginData,
                            short** spTransData0,
                            short** spTransData1,
                            int nHeight,
                            int nHeight_H,
                            int nWidth,
                            int nWidth_H,
                            int layer,
                            float fRadius)
{
    int Trans_W,    // 圖像掃描線控制:橫座標
    int Trans_H,    // 圖像掃描線控制:縱座標
    int Trans_M,    // 圖像矩陣的橫座標
    int Trans_N;    // 圖像矩陣的縱座標
    short Trans_Coeff0;   // 小波變換系數
    signed short Trans_Coeff1;

    fRadius=1.414;    // 變換濾波係數

    // 本模塊完成變換系數的賦值採樣
    // 行變換,第一次(layer=1時)時nHeight即爲原始圖像的高度值
    for(Trans_H=0; Trans_H<nHeight; Trans_H++) // 行座標
    {
        if(layer == 1)
        {
            // layer=1時,nWidth_H爲原始圖像寬度值的一半
            for(Trans_N=0; Trans_N<nWidth_H; Trans_N++)
            {
                Trans_W=Trans_N<<1;// Trans_W=Trans_N*2;
                // 行採樣
                if (fRadius==2)
                {
                    spTransData0[Trans_H][Trans_N] = (spOriginData[Trans_H][Trans_W]);
                        spTransData0[Trans_H][nWidth_H+Trans_N] = (spOriginData[Trans_H][Trans_W+1]);
                }
                else
                {
                    spTransData0[Trans_H][Trans_N] = (spOriginData[Trans_H][Trans_W]-128);
                    spTransData0[Trans_H][nWidth_H+Trans_N] = (spOriginData[Trans_H][Trans_W+1]-128);
                }
            }
        }

        // 若變換層數大於1,則僅採樣低頻的小波係數
        if(layer > 1){
            for(Trans_N=0; Trans_N<nWidth_H; Trans_N++)
            {
                Trans_W=Trans_N<<1;
                spTransData0[Trans_H][Trans_N] = spTransData1[Trans_H][Trans_W];
                spTransData0[Trans_H][nWidth_H+Trans_N] = spTransData1[Trans_H][Trans_W+1];
            }
        }
    }

    for(Trans_H=0; Trans_H<nHeight; Trans_H++)
    {
        for(Trans_N=0; Trans_N<nWidth_H-1; Trans_N++)
        {
            // 奇偶數值和的一半
            Trans_Coeff1 = ((spTransData0[Trans_H][Trans_N]+spTransData0[Trans_H][Trans_N+1])>>1);
            // 邏輯非操做後數值加1
            Trans_Coeff1=~Trans_Coeff1+1;
            // 係數預測
            spTransData0[Trans_H][nWidth_H+Trans_N] = spTransData0[Trans_H][nWidth_H+Trans_N]+Trans_Coeff1;
        }

        // 完成一個偶係數的邊界處理
        Trans_Coeff1 = ((spTransData0[Trans_H][nWidth_H-1]+spTransData0[Trans_H][nWidth_H-2])>>1);
        Trans_Coeff1=~Trans_Coeff1+1;
        spTransData0[Trans_H][nWidth-1] = spTransData0[Trans_H][nWidth-1]+Trans_Coeff1;

        // 完成一個奇係數的邊界處理
        Trans_Coeff0 = ((spTransData0[Trans_H][nWidth_H]+spTransData0[Trans_H][nWidth_H+1])>>2);
        spTransData0[Trans_H][0] = spTransData0[Trans_H][0]+Trans_Coeff0;

        // 提高,整數到整數的變換
        for(Trans_N=1; Trans_N<nWidth_H; Trans_N++)
        {
            Trans_Coeff0 = ((spTransData0[Trans_H][nWidth_H+Trans_N]+spTransData0[Trans_H][nWidth_H+Trans_N-1])>>2);
            spTransData0[Trans_H][Trans_N] = spTransData0[Trans_H][Trans_N]+Trans_Coeff0;
        }
    }   // 水平方向的變換結束

    // 豎直方向的變換開始,數據源爲水平變換後的小波係數
    for(Trans_M=0; Trans_M<nHeight; Trans_M++)
    {
        for(Trans_N=0; Trans_N<nWidth_H; Trans_N++)
        {
            spTransData0[Trans_M][Trans_N]*=fRadius;
            spTransData0[Trans_M][Trans_N+nWidth_H]/=fRadius;
         }
    }

    // 行提高後的數據在spTransData0中,spTransData0中的數據天然奇偶有序
    for(Trans_N=0; Trans_N<nWidth_H; Trans_N++)
    {
        // 列變換
        for(Trans_M=0; Trans_M<nHeight_H; Trans_M++)
        {
            Trans_H =Trans_M<<1;

            // 頻帶LL部分
            spTransData1[Trans_M][Trans_N] = spTransData0[Trans_H][Trans_N];

            // 頻帶HL部分
            spTransData1[nHeight_H+Trans_M][Trans_N] = spTransData0[Trans_H+1][Trans_N];

            // 頻帶LH部分
            spTransData1[Trans_M][nWidth_H+Trans_N] = spTransData0[Trans_H][nWidth_H+Trans_N];

            // 頻帶HH部分
            spTransData1[nHeight_H+Trans_M][nWidth_H+Trans_N] = spTransData0[Trans_H+1][nWidth_H+Trans_N];
        }

        // 第一次提高奇數座標系數
        for(Trans_M=0; Trans_M<nHeight_H-1; Trans_M++)
        {
            // 豎直方向的變換
            Trans_Coeff1 = ((spTransData1[Trans_M][Trans_N]+spTransData1[Trans_M+1][Trans_N])>>1);
            Trans_Coeff1=~Trans_Coeff1+1;
            spTransData1[nHeight_H+Trans_M][Trans_N] = spTransData1[nHeight_H+Trans_M][Trans_N]+Trans_Coeff1;
            Trans_Coeff1 = ((spTransData1[Trans_M][nWidth_H+Trans_N]+spTransData1[Trans_M+1][nWidth_H+Trans_N])>>1);
            Trans_Coeff1=~Trans_Coeff1+1;
            spTransData1[nHeight_H+Trans_M][nWidth_H+Trans_N] = spTransData1[nHeight_H+Trans_M][nWidth_H+Trans_N]+Trans_Coeff1;
        }

        Trans_Coeff1 = ((spTransData1[nHeight_H-1][Trans_N]+spTransData1[nHeight_H-2][Trans_N])>>1);
        Trans_Coeff1=~Trans_Coeff1+1;
        spTransData1[nHeight-1][Trans_N] = spTransData1[nHeight-1][Trans_N]+Trans_Coeff1;
        Trans_Coeff1 = ((spTransData1[nHeight_H-1][nWidth_H+Trans_N]+spTransData1[nHeight_H-2][nWidth_H+Trans_N])>>1);
        Trans_Coeff1=~Trans_Coeff1+1;

        // 邊界處理
        spTransData1[nHeight-1][nWidth_H+Trans_N] = spTransData1[nHeight-1][nWidth_H+Trans_N]+Trans_Coeff1;
        Trans_Coeff0 = ((spTransData1[nHeight_H][Trans_N]+spTransData1[nHeight_H+1][Trans_N])>>2);
        spTransData1[0][Trans_N] = spTransData1[0][Trans_N]+Trans_Coeff0;
        Trans_Coeff0 = ((spTransData1[nHeight_H][nWidth_H+Trans_N]+spTransData1[nHeight_H+1][nWidth_H+Trans_N])>>2);

        // 邊界處理
        spTransData1[0][nWidth_H+Trans_N] = spTransData1[0][nWidth_H+Trans_N]+Trans_Coeff0;

        // 第一次提高偶數座標系數
        for(Trans_M=1; Trans_M<nHeight_H; Trans_M++)
        {
            Trans_Coeff0 = ((spTransData1[nHeight_H+Trans_M][Trans_N]+spTransData1[nHeight_H+Trans_M-1][Trans_N])>>2);
            spTransData1[Trans_M][Trans_N] = spTransData1[Trans_M][Trans_N]+Trans_Coeff0;
            Trans_Coeff0 = ((spTransData1[nHeight_H+Trans_M][nWidth_H+Trans_N]+spTransData1[nHeight_H+Trans_M-1][nWidth_H+Trans_N])>>2);
            spTransData1[Trans_M][nWidth_H+Trans_N] = spTransData1[Trans_M][nWidth_H+Trans_N]+Trans_Coeff0;
        }
    }

    // 存放小波係數,LL頻帶的係數進行幅值加強處理,其它高頻頻帶的係數則削弱其幅值
    for(Trans_N=0; Trans_N<nWidth; Trans_N++)
    {
        for(Trans_M=0; Trans_M<nHeight_H; Trans_M++)
        {
            spTransData1[Trans_M][Trans_N]*=fRadius;
            spTransData1[Trans_M+nHeight_H][Trans_N]/=fRadius;
        }
    }
}
相關文章
相關標籤/搜索