ДКП изображения

Я работаю над функцией в Matlab, которая вычисляет DCT (дискретное косинусное преобразование) изображения. Я не знаю, что не работает в моем коде, который используется для сжатия изображений. Пожалуйста, помогите мне. Любые идеи, пожалуйста.

   clc;close all;clear all;
   image=('cameraman.tif');
    [h w] = size(image);
    image = double(image) - 128;
    b=8;
    block = zeros(b,b);

 image_t=zeros(size(image));
 for k=1:b:h
     for l=1:b:w
        image_t(k:k+b-1,l:l+b-1)= image(k:k+b-1,l:l+b-1);
        for u=1:b
            for v=1:b
                if u == 0
                    Cu = 1/sqrt(2);
                else
                    Cu = 1;
                end
                if v == 0
                    Cv = 1/sqrt(2);
                else
                    Cv = 1;
                end
                Res_sum=0;
                for x=1:b;
                    for y=1:b
                        Res_sum = Res_sum + ((image_t(x,y))*cos(((2*x)+1)*u*pi/(2*b))*cos(((2*y)+1)*v*pi/(2*b)));  
                    end
                end
                dct= (1/4)*Cu*Cv*Res_sum;
                block(u,v) = dct;

            end
        end
        image_comp(k:k+b-1,l:l+b-1)=block(u,v);
     end
 end
end

person P.Bisoyi    schedule 09.04.2015    source источник
comment
Почему тогда не работает?   -  person kkuilla    schedule 09.04.2015
comment
Честный комментарий... Если вы хотите, чтобы другие люди просмотрели ваш код, избегайте таких имен переменных, как h, w, b, v, u, Cu, Cv. Они могут показаться простыми, когда вы их пишете, но, честно говоря, когда я сталкиваюсь с новым кодом и вижу это, я даже не утруждаю себя чтением.   -  person Samuel Navarro Lou    schedule 09.04.2015
comment
@gdasamu я реализовал с помощью формулы DCT.   -  person P.Bisoyi    schedule 09.04.2015
comment
почему вы не используете функцию dct() Matlab?   -  person articuno    schedule 09.04.2015
comment
@articuno я не могу использовать встроенную функцию в своей программе.   -  person P.Bisoyi    schedule 09.04.2015
comment
@PrangyaBisoyi вы получаете сообщение об ошибке? или вы получаете неожиданные результаты?   -  person articuno    schedule 09.04.2015
comment
@articuno неожиданный результат.   -  person P.Bisoyi    schedule 09.04.2015


Ответы (1)


Я предполагаю, что вы реализуете следующую формулу для DCT:

dct

с участием

c(x)

И я предполагаю, что вам нужно разделить изображение на блоки 8x8 и выполнить DCT для каждого из этих блоков.

  1. Пожалуйста, прокомментируйте свой код! Это поможет вам и другим понять это намного лучше!
  2. Вы никогда не сможете добраться до части внутри if u == 0 или if v == 0, поскольку вы проходите через u и v в циклах for, которые проходят через 1:b. Основная проблема заключается в том, что MATLAB начинает индексирование с 1, а частоты в DCT начинаются с 0. Мой совет: используйте u и v как частоту, как в формуле, а не как индекс, т.е. for u=0:b-1 и используйте u+1 при индексировании.
  3. То же самое для x и y.
  4. image_t должен содержать только текущий блок (поэтому я переименовал его в current_block), а не все изображение. Это current_block = image(k:k+b-1,l:l+b-1);
  5. В строке dct= (1/4)*Cu*Cv*Res_sum; должно быть не 1/4, а 1/sqrt(2*N), где N — размер вашего блока (вы называете его b), таким образом, 1/sqrt(2*b). Для размера блока 8, как в вашем примере, это конечно 1/4.
  6. image — это имя функции MATLAB. Желательно не использовать его в качестве имени функции. Рассмотрите возможность его изменения, например. до input_image.
  7. Я не уверен, почему вы вычитаете 128 из входного изображения, пожалуйста, подумайте, почему вы это делаете.

Это приводит к коду ниже. Я не знаю, решит ли это все вашу проблему, но теперь вы должны быть намного ближе к этому ;-)

PS: подумайте о векторизации кода для повышения производительности.

function image_comp = dctII(input_image, b)
    [h, w] = size(input_image);
    input_image = double(input_image);
    block_dct = zeros(b);

    % Loop through all blocks
    for k=1:b:h
      for l=1:b:w

        % Save true image of block
        current_block = input_image(k:k+b-1,l:l+b-1);

        % Loop through all cos frequencies (u,v)
        for u=0:b-1
          for v=0:b-1
            if u == 0
                Cu = 1/sqrt(2);
            else
                Cu = 1;
            end
            if v == 0
                Cv = 1/sqrt(2);
            else
                Cv = 1;
            end

            Res_sum = 0;

            % Loop through all pixel values
            for x=0:b-1
              for y=0:b-1
                Res_sum = Res_sum + ((current_block(x+1,y+1))*cos(((2*x)+1)*u*pi/(2*b))*cos(((2*y)+1)*v*pi/(2*b)));  
              end
            end

            % Calculate DCT value at frequency (u,v)
            dct = 1/sqrt(2*b) * Cu * Cv * Res_sum;
            block_dct(u+1,v+1) = dct;
          end
        end

        image_comp(k:k+b-1,l:l+b-1) = block_dct(u+1,v+1);

      end
    end
end         % of function
person hbaderts    schedule 09.04.2015
comment
Большое спасибо, я вычел 128 из исходного изображения, так как я сделал сдвиг уровня, чтобы я мог выполнять dct, поскольку его значение находится в диапазоне от (-128 до 127). - person P.Bisoyi; 09.04.2015
comment
Это было больше работы, чем необходимо. +1. Я не склонен помогать этому ОП, так как он/она кажется человеком типа дай мне добро. - person rayryeng; 09.04.2015