2

Matlab で DCT (離散コサイン変換) を実装しようとしていますが、高速フーリエ変換を使用せずに、次の式を使用するだけです: ここに画像の説明を入力

これは非効率的である可能性があることはわかっていますが、この方法でどのように機能するかがわかります。

まず、グレースケール イメージを 8x8 ブロックに分割し、次に各ブロックに数式を適用します。

for i=1:8:h
    for j=1:8:w
        dctMatrix(i:(i-1)+block,j:(j-1)+block) = dctII(img(i:(i-1)+block,j:(j-1)+block), block);
    end
end

私のdctII関数は次のようになります。

   function [newB] = dctII(segmento, b)
    [h w] = size(segmento);
    segmento = double(segmento);
    newB = zeros(b,b);
    for u=0:h-1
        for v=0:w-1
            if u == 0
                Cu = 1/sqrt(2);
            else
                Cu = 1;
            end
            if v == 0
                Cv = 1/sqrt(2);
            else
                Cv = 1;
            end
            sumRes = summation(segmento,u,v,b);
            dct = (1/4)*Cu*Cv*sumRes;
            segmento(u+1,v+1) = dct;
        end
    end
    newB = segmento;
end

また、読みやすくするために合計関数も作成しました (少なくとも私にとっては)。

function [sum] = summation(segmento,u,v,b)
    [h w] = size(segmento);
    sum = 0;
    for x=0:h-1
        for y=0:w-1
            sum = sum + (double(segmento(x+1,y+1))*cos((((2*x)+1)*u*pi)/(2*b))*cos((((2*y)+1)*v*pi)/(2*b)));
        end
    end
end

問題は、私のアルゴリズムの結果が、Matlab のビルド済み関数dct2の結果とは大きく異なることです。たぶん、DCTアルゴリズムをまったく理解していませんでした。私が間違っていることを知っていますか?これらすべてのネストされたループがパフォーマンスを大幅に低下させることは知っていますが、FFTを使用せずにこれを解決する方法を想像できません。

どんな助けでも本当に感謝します、ありがとう。

4

1 に答える 1

1

もう解決!

私の結果は、Matlab のビルド済み関数 dct2 とは異なります。その関数は、私のように 8x8 のブロック除算を考慮していないため、行列が等しくないからです。

また、コードにわずかな変更を加えました。ピクセル値を操作する前に、[-128、127] の範囲内で操作するには、各値から 128 を減算する必要があることを読みました。これは私のコードです:

function [newB] = dctII(segmento, b)
    [h w] = size(segmento);
    segmento = double(segmento) - 128;
    newB = zeros(b,b);
    for u=0:h-1
        for v=0:w-1
            if u == 0
                Cu = 1/sqrt(2);
            else
                Cu = 1;
            end
            if v == 0
                Cv = 1/sqrt(2);
            else
                Cv = 1;
            end
            sumRes = summation(segmento,u,v,b);
            dct = (1/4)*Cu*Cv*sumRes;
            newB(u+1,v+1) = dct;
        end
    end
end

function [sum] = summation(segmento,u,v,b)
    [h w] = size(segmento);
    sum = 0;
    for x=0:h-1
        for y=0:w-1
            sum = sum + (double(segmento(x+1,y+1))*cos(((2*x)+1)*u*pi/(2*b))*cos(((2*y)+1)*v*pi/(2*b)));
        end
    end
end

あまり効率的ではありませんが、式の実装です。それが役立つことを願っています

于 2012-11-03T01:46:03.340 に答える