2014-12-12 15 views
0
 // Fourier transform of Image<Bgr,byte> orig object. 
     // output is matrix<float> with 2 channels. 

     private Matrix<float> fourier() 
    { 
     Image<Gray, float> image = orig.Convert<Gray, float>(); 
     IntPtr complexImage = CvInvoke.cvCreateImage(image.Size,Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_32F, 2); 

     CvInvoke.cvSetZero(complexImage); // Initialize all elements to Zero 
     CvInvoke.cvSetImageCOI(complexImage, 1); 
     CvInvoke.cvCopy(image, complexImage, IntPtr.Zero); 
     CvInvoke.cvSetImageCOI(complexImage, 0); 

     Matrix<float> dft = new Matrix<float>(image.Rows, image.Cols, 2); 
     CvInvoke.cvDFT(complexImage, dft, Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD, 0); 

     //The Real part of the Fourier Transform 
     Matrix<float> outReal = new Matrix<float>(image.Size); 
     //The imaginary part of the Fourier Transform 
     Matrix<float> outIm = new Matrix<float>(image.Size); 
     CvInvoke.cvSplit(dft, outReal, outIm, IntPtr.Zero, IntPtr.Zero); 
     return dft; 
    } 

    // butterworth filter with Do frequency and order n. 
    // Filter is returned as matrix<float> with 2 channels. 

    private Matrix<float> make_butterworth(int Do, int n) 
    { 
     Matrix<float> ff = fourier(); 
     Matrix<float> tmp = new Matrix<float>(ff.Rows, ff.Cols, 2); 

     Point center=new Point(tmp.Rows/2,tmp.Cols/2); 

     for (int i=0;i<orig.Rows;i++) 
      for (int j = 0; j < orig.Cols; j++) 
      { 
        int Duv= (int) (Math.Sqrt(Math.Pow(i-center.X,2) + Math.Pow(j-center.Y,2))); 
        tmp[i, j] = (float) (1/(1 + Math.Pow((Duv/Do), 2 * n))); 
      } 

     return tmp; 
    } 


    // The click event which will trigger fourier() and 
     make_butterworth() takes Do and n order input from user 
     and applies filter on orig image. 

    private void lowPassToolStripMenuItem2_Click(object sender, EventArgs e) 
    { 
     dialog_input d1 = new dialog_input("Enter values of Do and order n seperated by space:\n"); 
     d1.ShowDialog(); 
     string[] s = d1.t.Split(new char[] { ' ', ',' }); 
     int fc = Convert.ToInt32(s[0]); 
     int order = Convert.ToInt32(s[1]); 

     Matrix<float> filter= make_butterworth(fc, order); // 2 channels 
     Matrix<float> m = fourier(); // 2 channels 
     m._Mul(filter); 
     // filter * with fourier image. 
     CvInvoke.cvDFT(m,m,CV_DXT.CV_DXT_INVERSE, 0); 

     IntPtr cmplx = CvInvoke.cvCreateImage(m.Size, IPL_DEPTH.IPL_DEPTH_32F, 2); 
     CvInvoke.cvSetZero(cmplx); 
     CvInvoke.cvSetImageCOI(cmplx, 0); 
     CvInvoke.cvCopy(m, cmplx, IntPtr.Zero); 

     Bitmap bm = new Bitmap(m.Width, m.Height); 

     BitmapData bd = bm.LockBits(new Rectangle 
      (0, 0, bm.Width, bm.Height), 
      ImageLockMode.ReadWrite, 
      PixelFormat.Canonical); 

     bd.Scan0 = cmplx; 

     bm.UnlockBits(bd); 
     pictureBox2.Image = bm; 
     } 

Одна вещь, я беру fourier() как 2 канала вместо того, чтобы брать только настоящий канал. Я не уверен, что я ошибаюсь в этом отношении. Также поэтому я должен был фильтровать как 2 канала, где 2 канала используются для представления данных Gray и Alpha в обоих случаях.Фильтрация на изображении Фурье, а затем снятие его обратного звонка, чтобы получить изображение

Проблема возникает при инициализации объекта битмапдата из-за параметра pixelFormat.Canonical. Результат умножения матрицы Фурье и матрицы фильтра находится в матричном поплавке. Все, что я хочу сделать, это взять его IDFT и отобразить отфильтрованное изображение. Не уверен в PixelFormat. Любая помощь будет большой.

+0

комментарии в следующий раз пожалуйста! Недостаточно вашего кода, чтобы что-то сказать, разместите дополнительную информацию. Трубопровод БПФ: 1) load Изображение 2) создать фильтр 3) применить FFT для получения изображенияSpectrum (сложное изображение) 4) умножить спектр на фильтр (сложный результат) 5) применить результат IFFT по результату (реальное изображение) –

+0

, пожалуйста, проверьте правильность. благодаря – user3859323

ответ

0

Прочтите эту главу: opencv DFT tutorial, C code DFT и opencv DFT python это объясняет все, что вам нужно знать о DFT в opencv. О типах

1) Изображение Real

2) ДПФ (Image) результат в сложном изображении.

3) butterworth - это одноканальная матрица с одинаковым размером изображения.

4) чтобы фильтровать, умножьте каждый канал полученного DFT изображения на фильтр масляного фильтра. каждый канал должен быть разделен на несколько сегментов, мы имеем реальные и сложные части каждого пикселя, выделенные в одном канале в результате ДПФ. how filtering works

5) После фильтрации вы будете иметь сложный образ

6) Теперь вы можете применить IDFT, которые имеют в результате реальное изображение. В opencv вы можете получить как результат сложное изображение, но второй канал полностью нули, чтобы вы могли отказаться.

Посмотрите на: opencv C++ DFT