/** * \file FFToperations.cpp * \brief operations involving FFT Copyright 2007-2010 IMP Inventors. All rights reserved. **/ #include "IMP/em2d/FFToperations.h" #include "IMP/em/Image.h" #include "IMP/em/SpiderReaderWriter.h" IMPEM2D_BEGIN_NAMESPACE // Forget about const in these functions. FFT1D and FFT2D when used with fftw3 // can not be const. void correlation2D(algebra::Matrix2D_d &m1, algebra::Matrix2D_d &m2, algebra::Matrix2D_d &corr) { IMP_LOG(IMP::VERBOSE,"Computing 2D correlation " < x1 = M1.data()[i]; std::complex x2 = M2.data()[i]; M2.data()[i] = x1*std::conj(x2); } IFFT2D ifft(M2,corr); ifft.execute(); // corr contains the correlation matrix matrix_to_image_interpretation(corr); } void correlation2D_no_preprocessing( algebra::Matrix2D_c &M1, algebra::Matrix2D_c &M2, algebra::Matrix2D_d &corr) { IMP_LOG(IMP::VERBOSE, "Computing 2D correlation with no preprocessing" << std::endl); IMP_USAGE_CHECK((M1.get_number_of_rows()==M2.get_number_of_rows()) && (M1.get_number_of_columns()==M2.get_number_of_columns()), "em2d::correlation2D_no_preprocessing: Matrices have different size."); algebra::Matrix2D_c CORR(M1.get_size(0),M1.get_size(1)); for(unsigned long i=0;i > &m, std::ostream &out) { for (int k = m.get_start(0);k <= m.get_finish(0);k++) { if (m.get_size(0) > 1) { std::cout << "Slice No. " << k << std::endl; } for (int j = m.get_start(1);j <= m.get_finish(1);j++) { for (int i = m.get_start(2);i <= m.get_finish(2);++i) { out << m(k,j,i) << ' '; } out << std::endl; } } } void Matrix2D_c_to_img(algebra::Matrix2D_c &M,String name) { em::SpiderImageReaderWriter srw; em::Image img; img.resize(M.get_size(0),M.get_size(1)); for(unsigned long i=0;i(i,j) = (-1) *m.at(i,j); } else { roiA.at(i,j) = m.at(i,j); } } } cv::Mat imag_temp(dftSize,m.type(),cv::Scalar::all(0.0)); // Merge and dft cv::Mat temp,TEMP; cv::Mat imgs[]= { real_temp,imag_temp }; cv::merge(imgs,2,temp); cv::dft(temp, TEMP,cv::DFT_COMPLEX_OUTPUT,m.rows); // Real and imaginary // recover real part from the first channel // both source and destination matrices must be allocateda int rows = temp.rows; int cols= temp.cols; cv::Mat TEMP_1st_channel(rows,cols,m.type()); // real cv::Mat TEMP_2nd_channel(rows,cols,m.type()); // imag cv::Mat output[] = { TEMP_1st_channel,TEMP_2nd_channel }; const int fromTo[] = { 0,0 , 1,1 };// see mixChannels help, continuous numbers cv::mixChannels(&TEMP,1,output,2, fromTo, 2); // resize the output arrays if needed real.create(m.rows,m.cols, m.type()); imag.create(m.rows,m.cols, m.type()); TEMP_1st_channel(cv::Rect(0, 0, real.cols,real.rows)).copyTo(real); TEMP_2nd_channel(cv::Rect(0, 0, imag.cols,imag.rows)).copyTo(imag); } void matrix_to_image_flip(cv::Mat &m) { int half_rows = m.rows/2; int half_columns = m.cols/2; int new_i,new_j; for (int i=0;i=half_rows) { new_i=i-half_rows; } else { new_i=i+half_rows; } new_j=j+half_columns; std::swap(m.at(i,j),m.at(new_i,new_j)); } } } IMPEM2D_END_NAMESPACE