【问题标题】:DCT of an image图像的 DCT
【发布时间】:2015-04-09 08:57:18
【问题描述】:

我使用 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

【问题讨论】:

  • 为什么它不起作用?
  • 诚实评论...如果您希望其他人查看您的代码,请避免使用变量名称,例如 h、w、b、v、u、Cu、Cv。当你编写它时,它们可能看起来很简单,但老实说,当我面对一个新代码并看到这个时,我什至懒得去阅读它。
  • @gdasamu 我已经使用 DCT 公式实现了。
  • 为什么不用matlab的dct()函数呢?
  • @articuno 我不能在我的程序中使用内置函数。

标签: matlab image-processing dct


【解决方案1】:

我假设您为 DCT 实现了以下公式:

我猜你需要将图像分成8x8 的块,并对每个块进行 DCT。

  1. 请评论您的代码!它可以帮助您和其他人更好地理解它!
  2. 您永远无法到达if u == 0if v == 0 中的部分,因为您在通过1:b 的for 循环中执行uv。根本问题是MATLAB从1开始索引,而DCT中的频率从0开始。我的提示:使用uv作为公式中的频率,而不是像索引,即for u=0:b-1并使用@索引时为 987654332@。
  3. xy 也是如此。
  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

【讨论】:

  • 非常感谢,我已经从原始图像中减去 128,因为我已经完成了电平转换,以便我可以执行 dct,因为它的值范围在(-128 到 127)之间。
  • 这是多余的工作。 +1。我不倾向于帮助这个 OP,因为他/她看起来像一个 give me teh coodz 类型的人。
猜你喜欢
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
  • 2012-06-08
  • 2011-10-29
  • 2015-09-20
  • 1970-01-01
相关资源
最近更新 更多