Ejemplo n.º 1
0
 inline
 std::vector<TObject> vectorFilter (const std::vector<TObject> &v, const std::vector<int> &indices)
 {
   // Check that indices are within the range of the vector size
   if (vectorMax(indices) > v.size()-1 || vectorMin(indices) < 0)
   {
     std::cout << "[utl::stdvec::vectorFilter] indices are outside vector size range (vector size:" 
               << v.size() << ", indices range: (" << vectorMax(indices) << ", " << vectorMin(indices) << "))\n";
     return std::vector<TObject>(0);
   }
   
   // Filter
   std::vector<TObject> v_filtered;
   for (std::vector<int>::const_iterator it = indices.begin(); it != indices.end(); it++)
     v_filtered.push_back(v[*it]);
  
   return v_filtered;
 }
Ejemplo n.º 2
0
    int shrinkWrap
    (
        float * const & rIntensity,
        const std::vector<unsigned> & rSize,
        unsigned rnCycles,
        float rTargetError,
        float rHioBeta,
        float rIntensityCutOffAutoCorel,
        float rIntensityCutOff,
        float rSigma0,
        float rSigmaChange,
        unsigned rnHioCycles
    )
    {
        if ( rSize.size() != 2 ) return 1;
        const unsigned & Ny = rSize[1];
        const unsigned & Nx = rSize[0];

        /* Evaluate input parameters and fill with default values if necessary */
        if ( rIntensity == NULL ) return 1;
        if ( rTargetError              <= 0 ) rTargetError              = 1e-5;
        if ( rnHioCycles               == 0 ) rnHioCycles               = 20;
        if ( rHioBeta                  <= 0 ) rHioBeta                  = 0.9;
        if ( rIntensityCutOffAutoCorel <= 0 ) rIntensityCutOffAutoCorel = 0.04;
        if ( rIntensityCutOff          <= 0 ) rIntensityCutOff          = 0.2;
        if ( rSigma0                   <= 0 ) rSigma0                   = 3.0;
        if ( rSigmaChange              <= 0 ) rSigmaChange              = 0.01;

        float sigma = rSigma0;

        /* calculate this (length of array) often needed value */
        unsigned nElements = 1;
        for ( unsigned i = 0; i < rSize.size(); ++i )
        {
            assert( rSize[i] > 0 );
            nElements *= rSize[i];
        }

        /* allocate needed memory so that HIO doesn't need to allocate and
         * deallocate on each call */
        fftwf_complex * const curData   = fftwf_alloc_complex( nElements );
        fftwf_complex * const gPrevious = fftwf_alloc_complex( nElements );
        auto const isMasked = new float[nElements];

        /* create fft plans G' to g' and g to G */
        auto toRealSpace = fftwf_plan_dft( rSize.size(),
            (int*) &rSize[0], curData, curData, FFTW_BACKWARD, FFTW_ESTIMATE );
        auto toFreqSpace = fftwf_plan_dft( rSize.size(),
            (int*) &rSize[0], gPrevious, curData, FFTW_FORWARD, FFTW_ESTIMATE );

        /* create first guess for mask from autocorrelation (fourier transform
         * of the intensity @see
         * https://en.wikipedia.org/wiki/Wiener%E2%80%93Khinchin_theorem */
        #pragma omp parallel for
        for ( unsigned i = 0; i < nElements; ++i )
        {
            curData[i][0] = rIntensity[i]; /* Re */
            curData[i][1] = 0;
        }
        fftwf_execute( toRealSpace );
        complexNormElementwise( isMasked, curData, nElements );
        /* fftShift is not necessary, but I introduced this, because for the
         * example it shifted the result to a better looking position ... */
        //fftShift( isMasked, Nx,Ny );
        libs::gaussianBlur( isMasked, Nx, Ny, sigma );

        #if DEBUG_SHRINKWRAPP_CPP == 1
            std::ofstream file;
            std::string fname = std::string("shrinkWrap-init-mask-blurred");
            file.open( ( fname + std::string(".dat") ).c_str() );
            for ( unsigned ix = 0; ix < rSize[0]; ++ix )
            {
                for ( unsigned iy = 0; iy < rSize[1]; ++iy )
                    file << std::setw(10) << isMasked[ iy*rSize[0] + ix ] << " ";
                file << "\n";
            }
            file.close();
            std::cout << "Written out " << fname << ".png\n";
        #endif

        /* apply threshold to make binary mask */
        {
            const auto absMax = vectorMax( isMasked, nElements );
            const float threshold = rIntensityCutOffAutoCorel * absMax;
            #pragma omp parallel for
            for ( unsigned i = 0; i < nElements; ++i )
                isMasked[i] = isMasked[i] < threshold ? 1 : 0;
        }

        #if DEBUG_SHRINKWRAPP_CPP == 1
            fname = std::string("shrinkWrap-init-mask");
            file.open( ( fname + std::string(".dat") ).c_str() );
            for ( unsigned ix = 0; ix < rSize[0]; ++ix )
            {
                for ( unsigned iy = 0; iy < rSize[1]; ++iy )
                    file << std::setw(10) << isMasked[ iy*rSize[0] + ix ] << " ";
                file << "\n";
            }
            file.close();
            std::cout << "Written out " << fname << ".png\n";
        #endif

        /* copy original image into fftw_complex array and add random phase */
        #pragma omp parallel for
        for ( unsigned i = 0; i < nElements; ++i )
        {
            curData[i][0] = rIntensity[i]; /* Re */
            curData[i][1] = 0;
        }

        /* in the first step the last value for g is to be approximated
         * by g'. The last value for g, called g_k is needed, because
         * g_{k+1} = g_k - hioBeta * g' ! This is inside the loop
         * because the fft is needed */
        #pragma omp parallel for
        for ( unsigned i = 0; i < nElements; ++i )
        {
            gPrevious[i][0] = curData[i][0];
            gPrevious[i][1] = curData[i][1];
        }

        /* repeatedly call HIO algorithm and change mask */
        for ( unsigned iCycleShrinkWrap = 0; iCycleShrinkWrap < rnCycles; ++iCycleShrinkWrap )
        {
            /************************** Update Mask ***************************/
            std::cout << "Update Mask with sigma=" << sigma << "\n";

            /* blur |g'| (normally g' should be real!, so |.| not necessary) */
            complexNormElementwise( isMasked, curData, nElements );
            libs::gaussianBlur( isMasked, Nx, Ny, sigma );
            const auto absMax = vectorMax( isMasked, nElements );
            /* apply threshold to make binary mask */
            const float threshold = rIntensityCutOff * absMax;
            #pragma omp parallel for
            for ( unsigned i = 0; i < nElements; ++i )
                isMasked[i] = isMasked[i] < threshold ? 1 : 0;

            /* update the blurring sigma */
            sigma = fmax( 1.5, ( 1 - rSigmaChange ) * sigma );

            for ( unsigned iHioCycle = 0; iHioCycle < rnHioCycles; ++iHioCycle )
            {
                /* apply domain constraints to g' to get g */
                #pragma omp parallel for
                for ( unsigned i = 0; i < nElements; ++i )
                {
                    if ( isMasked[i] == 1 or /* g' */ curData[i][0] < 0 )
                    {
                        gPrevious[i][0] -= rHioBeta * curData[i][0];
                        gPrevious[i][1] -= rHioBeta * curData[i][1];
                    }
                    else
                    {
                        gPrevious[i][0] = curData[i][0];
                        gPrevious[i][1] = curData[i][1];
                    }
                }

                /* Transform new guess g for f back into frequency space G' */
                fftwf_execute( toFreqSpace );

                /* Replace absolute of G' with measured absolute |F| */
                applyComplexModulus( curData, curData, rIntensity, nElements );

                fftwf_execute( toRealSpace );
            } // HIO loop

            /* check if we are done */
            const float currentError = imresh::libs::calculateHioError( curData /*g'*/, isMasked, nElements );
            std::cout << "[Error " << currentError << "/" << rTargetError << "] "
                      << "[Cycle " << iCycleShrinkWrap << "/" << rnCycles-1 << "]"
                      << "\n";
            if ( rTargetError > 0 && currentError < rTargetError )
                break;
            if ( iCycleShrinkWrap >= rnCycles )
                break;
        } // shrink wrap loop
        for ( unsigned i = 0; i < nElements; ++i )
            rIntensity[i] = curData[i][0];

        /* free buffers and plans */
        fftwf_destroy_plan( toFreqSpace );
        fftwf_destroy_plan( toRealSpace );
        fftwf_free( curData  );
        fftwf_free( gPrevious);
        delete[] isMasked;

        return 0;
    }