2017-04-09 19 views
2
I이 문서에서 this OpenCV example에 기초한 스펙트럼 이미지 필터링을 구현하는 시도

및 여기서 편의상 복사 시프트된다 : I는 A (512 × 512)로서 레나 이미지 식별 필터를 사용 OpenCV의 DFT 기반의 컨볼 루션은

void convolveDFT(InputArray A, InputArray B, OutputArray C) 
{ 
    C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type()); 
    Size dftSize; 
    // calculate the size of DFT transform 
    dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1); 
    dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1); 

    // allocate temporary buffers and initialize them with 0's 
    Mat tempA(dftSize, A.type(), Scalar::all(0)); 
    Mat tempB(dftSize, B.type(), Scalar::all(0)); 

    // copy A and B to the top-left corners of tempA and tempB, respectively 
    Mat roiA(tempA, Rect(0,0,A.cols,A.rows)); 
    A.copyTo(roiA); 
    Mat roiB(tempB, Rect(0,0,B.cols,B.rows)); 
    B.copyTo(roiB); 

    // now transform the padded A & B in-place; 
    // use "nonzeroRows" hint for faster processing 
    dft(tempA, tempA, 0, A.rows); 
    dft(tempB, tempB, 0, B.rows); 

    // multiply the spectrums; 
    // the function handles packed spectrum representations well 
    mulSpectrums(tempA, tempB, tempA); 

    // transform the product back from the frequency domain. 
    // Even though all the result rows will be non-zero, 
    // you need only the first C.rows of them, and thus you 
    // pass nonzeroRows == C.rows 
    dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows); 

    // now copy the result back to C. 
    tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C); 
} 

(모든 항목은 가운데 하나를 제외하고 0으로 설정 됨) B (41x41).


Originalfiltered

하단 이미지의 오른쪽 부분이 잘린 것 같다. 또한 SO 포맷으로 인해 여기에서 볼 수는 없지만 필터링 된 이미지는 원본보다 작습니다 (함수의 첫 번째 줄 때문에).

filter2D 함수처럼 이미지를 필터링하도록 코드를 수정하려면 어떻게해야합니까? 따라서이 경우 결과는 원본 이미지가됩니다.

답변

1

컨볼 루션 결과의 크기는 호출의 인수와 마찬가지로 A.cols + B.cols - 1 by A.rows + B.rows - 1이어야합니다. 이것은 당신에게, 원래보다 약간 큰 모두 주위에 테두리를 포함하여 결과 이미지를 제공한다

C.create(A.rows + B.rows - 1, A.cols + B.cols - 1, A.type()); 

: 그래서, 완전 컨볼 루션 결과를 얻기 위해 예제의 첫 번째 줄에 변경해야 컨볼 루션의 꼬리에 해당합니다 (필터링이 위아래로 경사지는 곳).

filter2D은 출력이 원본과 같은 크기의 이미지로 제한되어 전체 회선을 반환하지 않으며 회선 꼬리를 제거합니다. 이를 위해 filter2D은 열을 따라 (B.cols - 1)/2의 시프트와 행을 따라 (B.rows - 1)/2의 시프트를 도입하는 선형 커널을 사용합니다. 필터링 된 이미지는 다음과 같이 추출 할 수 있습니다 :

C.create(A.rows, A.cols, A.type()); 
... 
tempA(Rect((B.cols-1)/2, (B.rows-1)/2, A.cols, A.rows).copyTo(C);