2011-09-28 93 views
4

我正試圖在頻域中執行逆濾波和僞逆濾波。對OpenCV進行逆濾波 - 訪問DFT值並乘以DFT矩陣

但是我有麻煩訪問DFT係數,之後乘以DFT矩陣,因爲我得到複數,因此,實際上是兩個矩陣...

基本上逆濾波執行

F = G/H,

其中F是恢復的圖像,G是模糊圖像,H是模糊圖像的內核。

僞逆需要訪問H中的值,因爲如果值接近0,它應該被替換以避免恢復中的問題。爲此,我們必須改變爲H,使得:

H(U,V)= 1/H(U,V)如果H(U,V)>閾 和= 0否則

我有一個kernel1(h_1)以及imf(恢復)和img(模糊)圖像。下面是代碼:

// compute the DFTs of the kernel (DFT_B) and the blurred image (DBF_A) 
    cvDFT(dft_A, dft_A, CV_DXT_FORWARD, complexInput1->height); 
    cvDFT(dft_B, dft_B, CV_DXT_FORWARD, complexInput2->height); 

    // the first type is the inverse fitlering 
    if (type == 1) { 
     printf("...performing inverse filtering\n"); 
     // dividing the transforms 
     cvDiv(dft_A, dft_B, dft_C, 1); 
    } 
    // the second type is the pseudo-inverse filtering 
    else { 
     printf("...prepare kernel for pseudo-inverse filtering\n"); 
     // will try to access the real values in order to see if value is above a threshold 
     cvSplit(dft_B, image_Re1, image_Im1, 0, 0); 
     // pointers to access the data into the real and imaginary matrices 
     uchar * dRe1 = (uchar *)image_Re1->imageData; 
     uchar * dIm1 = (uchar *)image_Im1->imageData; 
     int width = image_Re1->width; 
     int height = image_Re1->height; 
     int step = image_Re1->widthStep; 
     image_Re2 = cvCreateImage(cvGetSize(image_Re1), IPL_DEPTH_32F, 1); 
     image_Im2 = cvCreateImage(cvGetSize(image_Im2), IPL_DEPTH_32F, 1); 
     // pointers to access the data into the real and imaginary matrices 
     // it will be the resulting pseudo-inverse filter 
     uchar * dRe2 = (uchar *)image_Re2->imageData; 
     uchar * dIm2 = (uchar *)image_Im2->imageData; 

     printf("...building kernel for pseudo-inverse filtering\n"); 
     for (i = 0; i < height; i++) { 
     for (j = 0; j < width; j++) { 
       // generate the 1/H(i,j) value 
     if (dRe1[i * step + j] > threshold) { 
      float realsq = dRe1[i * step + j]*dRe1[i * step + j]; 
      float imagsq = dIm1[i * step + j]*dIm1[i * step + j]; 

      dRe2[i * step + j] = dRe1[i * step + j]/(realsq + imagsq); 
      dIm2[i * step + j] = -1 * (dIm1[i * step + j]/(realsq + imagsq)); 
     } 
     else { 
      dRe2[i * step + j] = 0; 
      dIm2[i * step + j] = 0; 
     } 
     } 
     } 
     printf("...merging final kernel\n"); 
     cvMerge(image_Re2, image_Im2, 0, 0, dft_B); 
     printf("...performing pseudo-inverse filtering\n"); 
     cvMulSpectrums(dft_A, dft_B, dft_C, 1); 
    } 
    printf("...performing IDFT\n"); 
    cvDFT(dft_C, dft_H, CV_DXT_INV_SCALE, 1); 

    printf("...getting size\n"); 
    cvGetSubRect(dft_H, &tmp3, cvRect(0, 0, img->width, img->height)); 

    printf("......(%d, %d) - (%d, %d)\n", tmp3.cols, tmp3.rows, restored->width, restored->height); 

    cvSplit(&tmp3, image_Re1, image_Im1, 0, 0); 

    cvNamedWindow("re", 0); 
    cvShowImage("re", image_Re2); 
    cvWaitKey(0); 

    printf("...copying final image\n"); 
    // error is in the line below 
    cvCopy(image_Re1, imf, NULL); 

我對最後一行的錯誤:--- OpenCV的錯誤:斷言失敗(src.depth()== dst.depth()& & src.size()= = dst.size())在cvCopy中,文件/build/buildd/opencv-2.1.0/src/cxcore/cxcopy.cpp,行466

我知道它與尺寸或深度有關,但我不知道不知道如何控制。無論如何,我試圖顯示image_Re1,它是空的...

任何人都可以闡明它嗎?

+0

免費試用圖像空間和上面的代碼減少到仍表現出該問題的小例子 - 你更容易得到答案的方式。 –

+0

謝謝。我會盡力。 –

回答

2

好像你沒有初始化你的imf圖片! cvCopy需要一個初始化的矩陣做:

IplImage* imf= cvCreateImage(cvGetSize(image_Re1), IPL_DEPTH_32F, 1); 

第一,我認爲它會工作。

而且,你不要在這個代碼(cvReleaseImage(&image))