2011-09-28 1 views
4

J'essaye d'effectuer un filtrage inverse et pseudo-inverse dans le domaine fréquentiel.Filtrage inverse sur OpenCV - accès aux valeurs DFT et multiplication des matrices DFT

Cependant, je ne parviens pas à accéder à des coefficients DFT et à multiplier les matrices DFT après, depuis que je suis des nombres complexes et, par conséquent, en fait deux matrices ...

Fondamentalement, le filtrage inverse effectue

F = G/Où 0 est l'image restaurée, G est l'image floue et H est le noyau qui a brouillé l'image. Le pseudo-inverse doit accéder aux valeurs de H, car si la valeur est proche de 0, il doit être remplacé pour éviter des problèmes dans la restauration. Pour cela, il faut modifier le H de telle sorte que:

H (u, v) = 1/H (u, v) si H (u, v)> seuil et = 0 sinon

I ont un kernel1 (h_1) et les images imf (restaurées) et img (floues). Voici le code:

// 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); 

J'ai une erreur sur la dernière ligne: --- OpenCV Erreur: Assertion a échoué (src.depth() == dst.depth() & & src.size() = = dst.size()) dans cvCopy, fichier /build/buildd/opencv-2.1.0/src/cxcore/cxcopy.cpp, ligne 466

Je sais que cela a à voir avec la taille ou la profondeur, mais je ne sais pas Je ne sais pas comment contrôler. Quoi qu'il en soit, j'ai essayé de montrer l'image_Re1 et il est vide ...

Quelqu'un peut-il nous éclairer?

+0

Essayez et réduire le code ci-dessus à un exemple minimal qui présente encore le problème - vous êtes beaucoup plus de chances d'obtenir une réponse de cette façon. –

+0

Merci. J'essaierai. –

Répondre

2

On dirait que vous n'avez pas initialisé votre image imf! cvCopy a besoin d'une matrice initialisées faire un:

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

premier et je pense que ça va marcher.

En outre, vous ne dispensent pas l'espace d'image dans ce code (cvReleaseImage(&image))

Questions connexes