2012-11-01 3 views
1
내가 matlab에에서 DCT (이산 코사인 변환)를 구현하기 위해 노력하고있어

없이하지만 바로 다음 공식을 사용하여, 고속 푸리에 변환을 사용하지 않고 :이 비효율적 일 수있어 enter image description hereDCT 2D FFT

하지만이 방법을 나는 그것이 어떻게 작동하는지 알 것이다.

먼저 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를 사용하지 않고이를 해결하는 방법을 상상할 수는 없습니다.

감사합니다. 정말 감사드립니다.

+0

적어도 합계 함수에서 괄호에 (2 * b)를 넣을 수 있습니다. –

+0

당신 말이 맞아요, 그 점을 지적 해 주셔서 감사합니다 –

답변

0

이미 해결되었습니다.

내 결과는 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 

매우 효율적이지는 않지만 수식 구현입니다. 희망이 도움이

+0

그 안에 segmento가 무엇입니까? 왜 segmento가 정의되지 않았습니까? – Rocket

+0

8x8 픽셀의 블록이며 내 함수의 매개 변수이므로 정의되지 않았습니다. –