4

周波数領域で逆フィルタリングと疑似逆フィルタリングを実行しようとしています。

ただし、複素数を取得したため、実際には2つの行列を取得したため、DFT係数へのアクセスとDFT行列の乗算に問題があります...

基本的に逆フィルタリングは実行します

F = G / H、

ここで、Fは復元された画像、Gはぼやけた画像、Hは画像をぼやけさせたカーネルです。

疑似逆行列はHの値にアクセスする必要があります。これは、値が0に近い場合、復元の問題を回避するために値を置き換える必要があるためです。このために、次のようにHを変更する必要があります。

H(u、v)>しきい値の場合はH(u、v)= 1 / 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())in cvCopy、file / build /buildd/opencv-2.1.0/src/cxcore/cxcopy.cpp、行466

サイズや深さに関係があることは知っていますが、制御する方法がわかりません。とにかく、image_Re1を表示しようとしましたが、空です...

誰かがそれに光を当てることができますか?

4

1 に答える 1

2

IMFの画像を初期化していないようです! cvCopy初期化されたマトリックスが必要です:

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

最初に、私はそれがうまくいくと思います。

また、このコードでは画像スペースを解放しません(cvReleaseImage(&image))

于 2011-10-21T15:25:07.040 に答える