ДКП 2D без БПФ

Я пытаюсь реализовать DCT (дискретное косинусное преобразование) в Matlab, но без использования быстрого преобразования Фурье, просто используя следующую формулу: введите здесь описание изображения

Я знаю, что это может быть неэффективно, но таким образом я пойму, как это работает.

Сначала я разделил изображение в градациях серого на блоки 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. Вы знаете, что я делаю неправильно? Я знаю, что все эти вложенные циклы серьезно убивают производительность, но я не могу представить, как это решить без использования БПФ.

Любая помощь будет очень признательна, спасибо.


person Jorge Zapata    schedule 01.11.2012    source источник
comment
По крайней мере, вы можете поставить (2 * b) в скобки в функции суммирования.   -  person Aki Suihkonen    schedule 01.11.2012
comment
Вы правы, спасибо что заметили   -  person Jorge Zapata    schedule 01.11.2012


Ответы (1)


Уже решено!

Мои результаты отличаются от предварительно созданной функции Matlab dct2, потому что эта функция не учитывает деление на блоки 8x8, как я, поэтому матрицы не равны.

Я также внес небольшие изменения в свой код, я прочитал, что перед работой со значениями пикселей нужно вычесть 128 из каждого значения, чтобы работать в диапазоне [-128, 127]. Это мой код:

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

Не очень эффективно, но это реализация формулы. надеюсь, это поможет

person Jorge Zapata    schedule 03.11.2012
comment
Что в нем сегменто? Почему он говорит, что сегменто не определен? - person Rocket; 02.04.2013
comment
Это блок 8x8 пикселей, и он не является неопределенным, поскольку является параметром моей функции. - person Jorge Zapata; 03.04.2013