Example #1
0
TEST(CBuffer2D, FftShiftEven)
{
  auto original = std::make_shared<CBuffer2D>(4, 4);
  auto originalData = original->data();

  // generate test data
  for (int64_t i = 0; i < 16; ++i)
    originalData[i] = Complex(static_cast<Real>(i));

  auto shifted = original->fftShift();
  auto shiftedData = shifted.data();

  EXPECT_EQ(Complex(10.0), shiftedData[ 0]);
  EXPECT_EQ(Complex(11.0), shiftedData[ 1]);
  EXPECT_EQ(Complex( 8.0), shiftedData[ 2]);
  EXPECT_EQ(Complex( 9.0), shiftedData[ 3]);
  EXPECT_EQ(Complex(14.0), shiftedData[ 4]);
  EXPECT_EQ(Complex(15.0), shiftedData[ 5]);
  EXPECT_EQ(Complex(12.0), shiftedData[ 6]);
  EXPECT_EQ(Complex(13.0), shiftedData[ 7]);
  EXPECT_EQ(Complex( 2.0), shiftedData[ 8]);
  EXPECT_EQ(Complex( 3.0), shiftedData[ 9]);
  EXPECT_EQ(Complex( 0.0), shiftedData[10]);
  EXPECT_EQ(Complex( 1.0), shiftedData[11]);
  EXPECT_EQ(Complex( 6.0), shiftedData[12]);
  EXPECT_EQ(Complex( 7.0), shiftedData[13]);
  EXPECT_EQ(Complex( 4.0), shiftedData[14]);
  EXPECT_EQ(Complex( 5.0), shiftedData[15]);
}
TEST(TestFFTShift,Shift_2x2x1)
{
  const int N = 4;
  int data[N];
  for (int i = 0; i<N; i++)
    data[i] = i;
  
  IndType3 gridDims;
  gridDims.x = 2;
  gridDims.y = 2;
  gridDims.z = 1;

  IndType3 offset;
  offset.x = 1;
  offset.y = 1;
  offset.z = 1;

  int expected[] = {3,2,1,0};

  debugGrid(data,gridDims);

  fftShift(&data[0],N,gridDims,offset);
  
  for (int i=0; i<N;i++)
    EXPECT_EQ(expected[i],data[i]);

  printf("shifted: \n");
  debugGrid(data,gridDims);
}
TEST(TestFFTShift,Shift_4x4x2)
{
  const int N = 32;
  int data[N];
  for (int i = 0; i<N; i++)
    data[i] = i;
  
  IndType3 gridDims;
  gridDims.x = 4;
  gridDims.y = 4;
  gridDims.z = 2;

  IndType3 offset;
  offset.x = 2;
  offset.y = 2;
  offset.z = 1;

  int expected[] = {26,27,24,25,30,31,28,29,18,19,16,17,22,23,20,21,10,11,8,9,14,15,12,13,2,3,0,1,6,7,4,5};

  debugGrid(data,gridDims);

  fftShift(&data[0],N,gridDims,offset);
  
  for (int i=0; i<N;i++)
    EXPECT_EQ(expected[i],data[i]);

  printf("shifted: \n");
  debugGrid(data,gridDims);
}
Example #4
0
TEST(CBuffer2D, FftShiftOdd)
{
  auto original = std::make_unique<CBuffer2D>(3, 3);
  auto originalData = original->data();

  // generate test data
  for (int64_t i = 0; i < 9; ++i)
    originalData[i] = Complex(static_cast<Real>(i));

  auto shifted = original->fftShift();
  auto shiftedData = shifted.data();

  EXPECT_EQ(Complex(8.0), shiftedData[0]);
  EXPECT_EQ(Complex(6.0), shiftedData[1]);
  EXPECT_EQ(Complex(7.0), shiftedData[2]);
  EXPECT_EQ(Complex(2.0), shiftedData[3]);
  EXPECT_EQ(Complex(0.0), shiftedData[4]);
  EXPECT_EQ(Complex(1.0), shiftedData[5]);
  EXPECT_EQ(Complex(5.0), shiftedData[6]);
  EXPECT_EQ(Complex(3.0), shiftedData[7]);
  EXPECT_EQ(Complex(4.0), shiftedData[8]);
}
Example #5
0
int main(int argc, char *argv[])
{
    ProgramOptions options(argc, argv);
    options.showParameters();
    ReconParameters params = options.getReconParameters();

    // -------------- Load multi-channel data -----------------
    auto reconData = ReconData<float>::Create(params.samples, params.projections, options.isGPU());
    loadReconData(params, reconData.get());

    unsigned threads = std::min(reconData->channels(), omp_get_num_procs());

    QElapsedTimer timer0, timer;
    timer0.start();

    // -------------- Gridding -------------------------------
    timer.start();
    auto grid = GridLut<float>::Create(*reconData);

#ifdef BUILD_CUDA
    if (options.isGPU()) {
        dynamic_cast<cuGridLut<float> *>(grid.get())->setNumOfPartitions(25);
    }
#endif // BUILD_CUDA

    grid->setNumOfThreads(threads);
    grid->plan(params.rcxres, params.overgridding_factor, params.kernel_width, 512);
    auto imgData = grid->execute();
    std::cout << "Gridding total time " << timer.elapsed() << " ms" << std::endl;

    ImageData<float> imgMap;
    if (params.pils)
        imgMap = *imgData;

    auto filter = ImageFilter<float>::Create(*imgData);
    filter->setNumOfThreads(threads);

    // --------------- FFT ----------------------------------
    filter->fftPlan();
    
    timer.restart();
    filter->fftExecute();
    filter->fftShift();
    std::cout << "FFT total time " << timer.restart() << " ms" << std::endl;

    // -------------- Recon Methods -----------------------------------
    timer.restart();
    if (params.pils) {
        auto filterMap = ImageFilter<float>::Create(imgMap);
        std::cout << "\nRecon PILS... " << std::endl;
        filterMap->lowFilter(22);
        std::cout << "\nLow pass filtering | " << timer.restart() << " ms" << std::endl;

        std::cout << "\nFFT low res image... " << std::endl;
        filterMap->fftExecute();
        filterMap->fftShift();
        std::cout << "FFT total time " << timer.restart() << " ms" << std::endl;

        filterMap->normalize();

        std::cout << "\nSum of Square Field Map..." << std::flush;
        filter->SOS(imgMap, {params.rcxres, params.rcyres, params.rczres});
        std::cout << " | " << timer.elapsed() << " ms" << std::endl;
    }
    else
    {
        std::cout << "\nRecon SOS... " << std::flush;
        filter->SOS({params.rcxres, params.rcyres, params.rczres});
        std::cout << " | " << timer.elapsed() << " ms" << std::endl;
    }

    std::cout << "\nProgram total time excluding I/O: " << timer0.elapsed() / 1000.0 << " s" << std::endl;

    // -------------------------- Save Data ---------------------------
    QFile file(params.path + params.outFile);
    file.open(QIODevice::WriteOnly);
    for (const auto &data : *imgData->getChannelImage()) {
        auto value = std::abs(data);
        file.write((const char *)&value, sizeof(decltype(value)));
    }
    file.close();

    // -------------------------- Display Data -----------------------
    int n = 0;
    if (options.isDisplay())
    {
        QApplication app(argc, argv);
        for (int i = 0; i < imgData->channels(); i++)
        {
            auto data = imgData->getChannelImage(i);
            displayData(*data, imgData->imageSize(), QString("channel ") + QString::number(n++));
        }
        return app.exec();
    }
    else
        return 0;
}
Example #6
0
cv::Mat
WavefrontSensor::WavefrontSensing(const std::vector<cv::Mat>& d, const double& meanPowerNoise)
{
  unsigned int numberOfZernikes = 20;   //total number of zernikes to be considered
  int M = numberOfZernikes;
  int K = d.size();
  cv::Mat Q2;
  //We introduce here the lineal relationship between parameter phases of each optical path
  partlyKnownDifferencesInPhaseConstraints(M, K, Q2);
  std::vector<cv::Mat> Q2_v = {Q2, cv::Mat::zeros(Q2.size(), Q2.type())};
  cv::Mat LEC;   //Linear equality constraints
  cv::merge(Q2_v, LEC);   //Build also the complex version of Q2
  //process each patch independently
  cv::Mat dd;
  std::vector<cv::Mat> d_w;
  std::vector<Metric> mtrc_v;
  std::vector<std::pair<cv::Range,cv::Range> > rngs;
  unsigned int pixelsBetweenTiles = (int)(d.front().cols);
  
  unsigned int tileSize = 34;
  OpticalSetup tsettings( tileSize );
  std::shared_ptr<Zernike> zrnk = std::make_shared<Zernike>(tsettings.pupilRadiousPixels(), tileSize, numberOfZernikes);
  divideIntoTiles(d.front().size(), pixelsBetweenTiles, tileSize, rngs);
  //Random row selector: Pick incoherent measurements
  
  
  cv::Mat eye_nn = cv::Mat::eye(K*tileSize*tileSize, K*tileSize*tileSize, cv::DataType<double>::type);
  unsigned int a = 400; //number of incoheren measurements
  cv::Mat shuffle_eye;
  shuffleRows(eye_nn, shuffle_eye);
  
  //Split 'a' into rngs.size() pieces
  
  std::vector<cv::Mat> A_v = {shuffle_eye(cv::Range(0, a), cv::Range::all()), cv::Mat::zeros(a, K*tileSize*tileSize, cv::DataType<double>::type)};
  cv::Mat A;
  cv::merge(A_v, A);
  
  std::cout << "Number of anisoplanatic patches to annalize at once: " << rngs.size() << std::endl;
  
  for(auto rng_i : rngs)
  {
    cv::Mat d_col;
    //get ready dataset format
    std::vector<cv::Mat> D;
    std::vector<cv::Mat> d_col_v;
    for(cv::Mat di : d)
    {
      cv::Mat Di;
      cv::dft(di(rng_i.first, rng_i.second), Di, cv::DFT_COMPLEX_OUTPUT + cv::DFT_SCALE);
      fftShift(Di);
      D.push_back(Di);
      cv::Mat Di_t(Di.t());
      d_col_v.push_back(Di_t.reshape(0, Di_t.total() ));
    }
    cv::vconcat(d_col_v, d_col);
    cv::gemm(A, d_col, 1.0, cv::Mat(), 1.0, d_col);  //Picks rows randomly
    
    d_w.push_back( d_col );
    mtrc_v.push_back( Metric(D, zrnk, meanPowerNoise) );
  }
  cv::vconcat(d_w, dd);
  
  //-----------------------BY MEANS OF CONVEX OPTIMIZATION:
  //Objective function and gradient of the objective function
  if(false)
  {
  for(auto mtrc : mtrc_v)
  {
    std::function<double(cv::Mat)> func = std::bind(&Metric::objective, &mtrc, std::placeholders::_1);
    std::function<cv::Mat(cv::Mat)> dfunc = std::bind(&Metric::gradient, &mtrc, std::placeholders::_1);
    
    ConvexOptimization minimizationKit;
    cv::Mat x0_conv = cv::Mat::zeros(M*K, 1, cv::DataType<double>::type);   //reset starting point
    
    //Lambda function that turn minimize function + constraints problem into minimize function lower dimension problem
    auto F_constrained = [] (cv::Mat x, std::function<double(cv::Mat)> func, const cv::Mat& Q2) -> double
    {
      return func(Q2*x);
    };
    
    auto DF_constrained = [] (cv::Mat x, std::function<cv::Mat(cv::Mat)> dfunc, const cv::Mat& Q2) -> cv::Mat
    {
      return Q2.t() * dfunc(Q2*x);
    };
      
    std::function<double(cv::Mat)> f_constrained = std::bind(F_constrained, std::placeholders::_1, func, Q2);
    std::function<cv::Mat(cv::Mat)> df_constrained = std::bind(DF_constrained, std::placeholders::_1, dfunc, Q2);
    //Define a new starting point with lower dimensions after reduction with contraints
    cv::Mat p_constrained = Q2.t() * x0_conv;
    ConvexOptimization min;
    min.perform_BFGS(p_constrained, f_constrained, df_constrained);
    x0_conv = Q2 * p_constrained;   //Go back to original dimensional 

    std::cout << "mimumum: " << x0_conv.t() << std::endl;
  }
  std::cout << "END OF CONVEX OPTIMIZATION"  << std::endl;
  }

  
  //-----------------------BY MEANS OF SPARSE RECOVERY:
  //Create phase_div bias: only for the case of two diversity images!!
//  cv::Mat phase_div = cv::Mat::zeros(rngs.size()*M*K, 1, cv::DataType<double>::type);
//  phase_div.at<double>(M + 3, 0) = tsettings.k() * 3.141592/(2.0*std::sqrt(3.0));
  
  cv::Mat x0 = cv::Mat::zeros(rngs.size()*M*K, 1, cv::DataType<double>::type); //Starting point
  
  std::vector<double> gamma_v(M*K, 1.0);
  for(unsigned int count=0;count<600;++count)
  {
    std::vector<cv::Mat> x0_vvv;
    cv::split(x0, x0_vvv);
    x0_vvv.at(0).copyTo(x0);
    
    cv::Mat_<std::complex<double> > blockMatrix_M;
    std::vector<cv::Mat> De_v;
    for(unsigned int t=0; t < rngs.size(); ++t)
    {
      cv::Mat jacob_i;
      mtrc_v.at(t).jacobian( x0(cv::Range(t*M*K, (t*M*K) + (M*K)), cv::Range::all()), jacob_i );
      cv::gemm(A, jacob_i, 1.0, cv::Mat(), 1.0, jacob_i);   //Picks rows randomly
      cv::gemm(jacob_i, LEC, 1.0, cv::Mat(), 1.0, jacob_i);  //Apply constraints LECs
      cv::copyMakeBorder(blockMatrix_M, blockMatrix_M, 0, jacob_i.size().height, 0, jacob_i.size().width, cv::BORDER_CONSTANT, cv::Scalar(0.0, 0.0) );
      cv::Rect rect(cv::Point(t*jacob_i.size().width, t*jacob_i.size().height), jacob_i.size() );
      jacob_i.copyTo(blockMatrix_M( rect ));
      cv::Mat De_i;
      mtrc_v.at(t).phi( x0(cv::Range(t*M*K, (t*M*K) + (M*K)), cv::Range::all()), De_i );
      cv::gemm(A, De_i, 1.0, cv::Mat(), 1.0, De_i);   //Picks rows randomly
      De_v.push_back( De_i );
    }
    cv::Mat De;
    cv::vconcat(De_v, De);
    
    std::vector<cv::Mat> x0_v = {x0, cv::Mat::zeros(x0.size(), x0.type())};
    cv::merge(x0_v, x0);

    //Apply algorithm to get solution
    unsigned int blkLen = rngs.size();
    cv::Mat blockMatrix_M_r;
    reorderColumns(blockMatrix_M, M, blockMatrix_M_r);   //reorder columns so correlated data form a single block

    gamma_v = std::vector<double>(M*K, 1.0);
    //cv::Mat coeffs = perform_BSBL(blockMatrix_M_r, dd - De, NoiseLevel::Noiseless, gamma_v, blkLen);  //Noiseless, LittleNoise
    //cv::Mat coeffs = perform_SBL(blockMatrix_M_r, dd - De, NoiseLevel::Noiseless, gamma_v);  //Noiseless, LittleNoise
    cv::Mat coeffs = perform_projection(blockMatrix_M_r, dd - De);  //Noiseless, LittleNoise
    cv::Mat coeffs_r;
    reorderColumns(coeffs.t(), blockMatrix_M.cols/M, coeffs_r);
    
    cv::Mat coeffs_r_n(coeffs_r.t());
    
    //Undo constraints
    cv::Mat sol = cv::Mat::zeros(x0.size(), cv::DataType<std::complex<double> >::type);
    for(unsigned int t=0; t < rngs.size(); ++t)
    {
      cv::Mat sol_i;
      cv::gemm(LEC, coeffs_r_n(cv::Range(t*LEC.cols, (t*LEC.cols) + (LEC.cols)), cv::Range::all()), 1.0, cv::Mat(), 1.0, sol_i);
      sol_i.copyTo(sol(cv::Range(t*M*K, (t*M*K) + (M*K)), cv::Range::all()));
    }
    
    std::cout << "cv::norm(sol): " << cv::norm(sol) << std::endl;
    if(cv::norm(sol) < 1e-4 ) {std::cout << "Solution found" << std::endl; break;}
    x0 = x0 - sol;
    
    std::cout << "Solution number: " << count << std::endl;
    std::cout << "x0: " << x0.t() << std::endl;
  }
  
  return cv::Mat();  //mtrc.F();
}