Esempio n. 1
0
static int pix_abs8_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
                         ptrdiff_t stride, int h)
{
    int s = 0, i;

    for (i = 0; i < h; i++) {
        s    += abs(pix1[0] - avg2(pix2[0], pix2[1]));
        s    += abs(pix1[1] - avg2(pix2[1], pix2[2]));
        s    += abs(pix1[2] - avg2(pix2[2], pix2[3]));
        s    += abs(pix1[3] - avg2(pix2[3], pix2[4]));
        s    += abs(pix1[4] - avg2(pix2[4], pix2[5]));
        s    += abs(pix1[5] - avg2(pix2[5], pix2[6]));
        s    += abs(pix1[6] - avg2(pix2[6], pix2[7]));
        s    += abs(pix1[7] - avg2(pix2[7], pix2[8]));
        pix1 += stride;
        pix2 += stride;
    }
    return s;
}
Esempio n. 2
0
/****************************************************************************//**
 *
 *
 *******************************************************************************/
int main(int argc, char *argv[]) {

    typedef double TFLOAT;

    if (argc<5 || argc>8) {
        std::cerr << "Usage: " << (argc?argv[0]:"average") << " CONFIG_FILE FTEMPLATES FPARTICLES [LOGFILE] [DO_FSC] [WEDGE_THRESHOLD]"               "\n"
                     "compiled at " __DATE__ " " __TIME__ " from " __FILE__                                                         "\n"
                     "  CONFIG_FILE     : filename of the parallel correlation program."                                                 "\n"
                     "  FTEMPLATES      : filename of the textfile with the names of the templates."                                     "\n"
                     "  FPARTICLES      : filename of the textfile with the names of the particles."                                     "\n"
                     "  ANGLES          : filename of the textfile with the angles."                                                     "\n"
                     "  LOGFILE         : optional parameter for the log file. '-' for STDOUT."                                          "\n"
                     "  DO_FSC          : optional parameter to decide whether to compute the FSC (yes or no)."                          "\n"
                     "  WEDGE_THRESHOLD : Voxels of the averaged wedge are set to zero if they are SMALLER then WEDGE_THRESHOLD% of the number of particles (default 0 == no cutoff)."  << std::endl;
        return -1;
    }

    double use_threshold = 0.005;
    if (argc >= 8) {
        try {
            use_threshold = boost::lexical_cast<double>(argv[7]);
        } catch (boost::bad_lexical_cast &) {
            throw std::invalid_argument("The WEDGE_THRESHOLD must be a floating point number.");
        }
        if (use_threshold > 1 && use_threshold <= 100) {
            use_threshold = use_threshold/100.;
        }
        if (use_threshold > 1 || use_threshold <= 0) {
            throw std::invalid_argument("WEDGE_THRESHOLD must be either a prozentual value ]1, 100] or relative between ]0.0, 1.0].");
        }
    }

    bool do_fourier_shell = true;
    if (argc >= 7) {
        std::string p(argv[6]);
        std::transform(p.begin(), p.end(), p.begin(), &toupper);
        if (p=="YES" || p=="1" || p=="FSC" || p=="TRUE") {
            do_fourier_shell = true;
        } else if (p=="NO" || p=="0" || p=="FALSE") {
            do_fourier_shell = false;
        } else {
            std::cerr << "Argument 6 (do_fsc) must be either \"yes\" or \"no\"." << std::endl;
            return -2;
        }
    }


    std::size_t itemplate, iparticle, ntemplates, nparticles, i;

    std::vector<std::string> ftemplates, fparticles;
    std::vector<boost::shared_ptr<tom::Volume<double> > > angles;
    std::vector<helper::triple<double, double, double> > anglesv;
    std::vector<boost::shared_ptr<tom::WedgeDescriptor<TFLOAT> > > wedge_templates, wedge_particles;
    std::vector<tom::cc_peak<TFLOAT> > peak_list;
    tom::corr::ConfigDataServer c;
    std::string outputdir;

    std::stringstream clog;
    std::auto_ptr<std::ofstream> f;
    std::auto_ptr<helper::ostream_swapper> stream_swapper;
    clog.precision(20);
    clog << "# start " << (argc>0?argv[0]:"average") << " at " << helper::now2str() << " (compiled at " __DATE__ " " __TIME__ ")." << std::endl;

    // Parse the input files.
    clog << "# parse configuration (" << argv[1] << ")" << std::endl;
    c.read_from_conf(argv[1]);
    clog << "# parse filelist for templates (" << argv[2] << ")" << std::endl;
    tom::corr::parse_filelist(argv[2], ftemplates, wedge_templates, 1);
    ntemplates = ftemplates.size();
    clog << "#   " << ntemplates << " templates read.\n"
            "# parse filelist for particles (" << argv[3] << ")" << std::endl;
    tom::corr::parse_filelist(argv[3], fparticles, wedge_particles, 1);
    nparticles = fparticles.size();
    clog << "#   " << nparticles << " particles read.\n"
            "# parse the list of angles (" << argv[4] << ")" << std::endl;
    tom::corr::parse_angleslist(argv[4], ntemplates, nparticles, angles);
    clog << "# parse peak list (" << c.peakfilename << ")" << std::endl;
    tom::corr::parse_peaklist(c.peakfilename, peak_list, anglesv, ntemplates, nparticles);

    clog << "#\n# use a threshold for the wedge of " << use_threshold << "\n# (values in the summed wedge are set to zero if they are smaller then the relative threshold compared to the number of particles).\n" << std::endl;

    tom::avg::filename_generator f_gen(c.outputdir);


    // open the logfile.
    {
        std::ostream *use_log = &std::clog;

        std::string logfilename(argc>=6 ? argv[5] : "-");
        if (logfilename != "-") {
            f.reset(new std::ofstream(logfilename.c_str(), std::ios::out | std::ios::trunc));
            if (!f->good()) {
                f.reset(NULL);
                clog << "# ERROR: could not open log-file \"" << logfilename << "\" for writing. Use CERR instead." << std::endl;
            } else {
                use_log = f.get();
            }
        }
        *use_log << clog.rdbuf() << std::flush;
        clog.clear();
        stream_swapper.reset(new helper::ostream_swapper(clog, *use_log));
    }



    // Find out, which particles average to which template.
    std::vector<std::vector<std::size_t> > use_particles(ntemplates), use_particles1(ntemplates), use_particles2(ntemplates), use_particles3(ntemplates);
    for (iparticle=0; iparticle<nparticles; iparticle++) {
        std::size_t max_index = ntemplates;
        double max_ccvalue = - std::numeric_limits<double>::infinity();
        for (itemplate=0; itemplate<ntemplates; itemplate++) {
            i = itemplate * nparticles + iparticle;

            if (angles[i].get()) {
                assert(angles[i]->getSizeX()==3 && angles[i]->getSizeZ()==1);

                if (peak_list[i].angle_idx < 0) {
                    clog << "# WARNING: no peak found for template #" << itemplate << ", particle #" << iparticle << "." << std::endl;
                    continue;
                } else {
                    if (static_cast<std::size_t>(peak_list[i].angle_idx) >= angles[i]->getSizeY()) {
                        clog << "# WARNING: peak-index for template #" << itemplate << ", particle #" << iparticle << " is larger then the entire angle-list (" << peak_list[i].angle_idx << " vs. " << angles[i]->getSizeY() << "). Using peak from file." << std::endl;
                    } else {
                        boost::tuples::tuple<double &, double &, double &> a = boost::tuples::tie(angles[i]->get(0, peak_list[i].angle_idx, 0), angles[i]->get(0, peak_list[i].angle_idx, 0), angles[i]->get(0, peak_list[i].angle_idx, 0));
                        if (fabs(a.get<0>()-anglesv[i].x)>1e-7 || fabs(a.get<0>()-anglesv[i].x)>1e-7 || fabs(a.get<0>()-anglesv[i].x)>1e-7) {
                            clog << "# WARNING: peak-index for template #" << itemplate << ", particle #" << iparticle << " differs from angles list and peakfile: (" << a.get<0>() << " vs. " << anglesv[i].x << "; " << a.get<0>() << " vs. " << anglesv[i].x << "; " << a.get<0>() << " vs. " << anglesv[i].x << "). Take from peak-file." << std::endl;
                        }
                    }
                }
            } else {
                if (peak_list[i].angle_idx >= 0) {
                    clog << "# WARNING: peak-index for template #" << itemplate << ", particle #" << iparticle << " given, but the angles list is empty. Using peak from file." << std::endl;
                } else {
                    // everything is fine.
                    continue;
                }
            }
            const double shiftx = - peak_list[i].x;
            const double shifty = - peak_list[i].y;
            const double shiftz = - peak_list[i].z;
            if (fabs(shiftx) > c.volsize/2 || fabs(shifty) > c.volsize/2 || fabs(shiftz) > c.volsize/2) {
                clog << "# WARNING: the shift of template #" << itemplate << ", particle #" << iparticle << " is too large for the volume of size " << c.volsize << " (" << shiftx << "," << shifty << "," << shiftz << ")." << std::endl;
                continue;
            }

            if (max_index==ntemplates || max_ccvalue<peak_list[i].val) {
                max_ccvalue = peak_list[i].val;
                max_index = itemplate;
            }
        }
        if (max_index != ntemplates) {
            use_particles[max_index].push_back(iparticle);
        }
    }

    // Split the list of particles in two sets for the FSC.
    if (do_fourier_shell) {
        for (itemplate=0; itemplate<ntemplates; itemplate++) {
            std::size_t size = use_particles[itemplate].size();
            if (size >= 2) {
                const std::vector<std::size_t> &v_ = use_particles [itemplate];
                std::vector<std::size_t> &v1 = use_particles1[itemplate];
                std::vector<std::size_t> &v2 = use_particles2[itemplate];
                std::vector<std::size_t> &v3 = use_particles3[itemplate];
                v1.resize(0);
                v2.resize(0);
                v3.resize(0);
                if (size%2) {
                    size--;
                    v3.push_back(v_[size]);
                }
                v1.reserve(size/2);
                v2.reserve(size/2);
                for (iparticle=0; iparticle<size; iparticle+=2) { v1.push_back(v_[iparticle]); }
                for (iparticle=1; iparticle<size; iparticle+=2) { v2.push_back(v_[iparticle]); }
            }
        }
    } else {
        clog << "# don't compute the Fourier Shell Correlation." << std::endl;
    }


    // Init the spheremask
    std::auto_ptr<const tom::Volume<TFLOAT> > mask_sphere;
    if (c.sphere_mask_inner_radius>0 || c.sphere_mask_sigma>0) {
        tom::Volume<TFLOAT> *p;
        mask_sphere.reset(p = new tom::Volume<TFLOAT>(c.volsize, c.volsize, c.volsize, NULL,NULL));
        tom::init_spheremask(*p, c.sphere_mask_inner_radius, c.sphere_mask_sigma, c.sphere_mask_cutoff_radius);
    }



    tom::Volume<TFLOAT> avg(c.volsize, c.volsize, c.volsize, tom::fftw::fftw_malloc<TFLOAT>(), tom::fftw::fftw_free<TFLOAT>());
    tom::Volume<TFLOAT> avgwedge(c.volsize, c.volsize, c.volsize, NULL,NULL);
    tom::Volume<TFLOAT> avgwedge_half(avgwedge, NULL, c.volsize, c.volsize, c.volsize/2+1, avgwedge.getStrideX(), avgwedge.getStrideY(), avgwedge.getStrideZ());
    tom::Volume<TFLOAT> avgwedge_sqrtn(c.volsize, c.volsize, c.volsize, NULL,NULL);
    tom::Volume<TFLOAT> avgwedge_sqrtn_half(avgwedge_sqrtn, NULL, c.volsize, c.volsize, c.volsize/2+1, avgwedge.getStrideX(), avgwedge.getStrideY(), avgwedge.getStrideZ());
    tom::Volume<TFLOAT> avg2(c.volsize, c.volsize, c.volsize, NULL,NULL);
    tom::Volume<TFLOAT> avgwedge2(c.volsize, c.volsize, c.volsize, NULL,NULL);
    tom::Volume<TFLOAT> avgwedge2_half(avgwedge2, NULL, c.volsize, c.volsize, c.volsize/2+1, avgwedge2.getStrideX(), avgwedge2.getStrideY(), avgwedge2.getStrideZ());
    tom::Volume<std::complex<TFLOAT> > avg_ft(c.volsize, c.volsize, c.volsize/2+1, tom::fftw::fftw_malloc<TFLOAT>(), tom::fftw::fftw_free<TFLOAT>());
    tom::Volume<std::complex<TFLOAT> > avg_ft2(c.volsize, c.volsize, c.volsize/2+1, tom::fftw::fftw_malloc<TFLOAT>(), tom::fftw::fftw_free<TFLOAT>());

    tom::fftw::Plan<TFLOAT> plan_fwd(avg2, avg_ft, c.fftw_flag | FFTW_DESTROY_INPUT);
    tom::fftw::Plan<TFLOAT> plan_bwd(avg_ft, avg2, c.fftw_flag | FFTW_DESTROY_INPUT);

    std::auto_ptr<tom::Volume<TFLOAT> > vtemplate;
    tom::Volume<std::complex<TFLOAT> > vtemplate_ft(c.volsize, c.volsize, c.volsize/2+1, tom::fftw::fftw_malloc<TFLOAT>(), tom::fftw::fftw_free<TFLOAT>());
    tom::fftw::Plan<TFLOAT> plan_vtemplate(avg, vtemplate_ft, c.fftw_flag | FFTW_DESTROY_INPUT);


    // Volumes for the fourier shell correlation.
    std::auto_ptr<tom::Volume<TFLOAT> > FSC_v, FSC_w2;
    std::auto_ptr<tom::Volume<std::complex<TFLOAT> > > FSC_f1, FSC_f2, FSC_f1_half, FSC_f2_half;
    std::auto_ptr<tom::fftw::Plan<TFLOAT> > FSC_plan1, FSC_plan2;
    if (do_fourier_shell) {
        FSC_v.reset(        new tom::Volume<TFLOAT>(c.volsize, c.volsize, c.volsize, tom::fftw::fftw_malloc<TFLOAT>(), tom::fftw::fftw_free<TFLOAT>()));
        FSC_f1.reset(       new tom::Volume<std::complex<TFLOAT> >(c.volsize, c.volsize, c.volsize, tom::fftw::fftw_malloc<TFLOAT>(), tom::fftw::fftw_free<TFLOAT>()));
        FSC_f2.reset(       new tom::Volume<std::complex<TFLOAT> >(c.volsize, c.volsize, c.volsize, tom::fftw::fftw_malloc<TFLOAT>(), tom::fftw::fftw_free<TFLOAT>()));
        FSC_f1_half.reset(  new tom::Volume<std::complex<TFLOAT> >(*FSC_f1, NULL, c.volsize, c.volsize, c.volsize/2+1, FSC_f1->getStrideX(), FSC_f1->getStrideY(), FSC_f1->getStrideZ()));
        FSC_f2_half.reset(  new tom::Volume<std::complex<TFLOAT> >(*FSC_f2, NULL, c.volsize, c.volsize, c.volsize/2+1, FSC_f2->getStrideX(), FSC_f2->getStrideY(), FSC_f2->getStrideZ()));
        FSC_plan1.reset(    new tom::fftw::Plan<TFLOAT>(*FSC_v, *FSC_f1_half, c.fftw_flag | FFTW_DESTROY_INPUT));
        FSC_plan2.reset(    new tom::fftw::Plan<TFLOAT>(*FSC_v, *FSC_f2_half, c.fftw_flag | FFTW_DESTROY_INPUT));
        FSC_w2.reset(       new tom::Volume<TFLOAT>(c.volsize, c.volsize, c.volsize/2+1, tom::fftw::fftw_malloc<TFLOAT>(), tom::fftw::fftw_free<TFLOAT>()));
    }


    double mean, variance;

    std::vector<std::size_t>::const_iterator culvit; // Const Unsigned Long Vector ITerator

    std::vector<tom::avg::st_average_result> av(ntemplates);

    double threshold = 1;

    // Now compute the average, the FSC, the CC and save it to file.
    for (itemplate=0; itemplate<ntemplates; itemplate++) {
        const std::vector<std::size_t> &v_ = use_particles [itemplate];
        const std::vector<std::size_t> &v1 = use_particles1[itemplate];
        const std::vector<std::size_t> &v2 = use_particles2[itemplate];
        const std::vector<std::size_t> &v3 = use_particles3[itemplate];

        threshold = v_.size()*use_threshold; // cut off.

        assert(std::set<std::size_t>(v_.begin(), v_.end()).size() == v_.size() &&
               (!do_fourier_shell || (v_.size()<2 || v_.size()==(v1.size()+v2.size()+v3.size()))));

        if (v_.empty()) {
            continue;
        }

        tom::avg::st_average_result &ar = av[itemplate];
        ar.use_idx = v_;

        // Read the original template from file.
        try {
            tom::Volume<TFLOAT> *p;
            tom::read_from_em(p, ftemplates[itemplate], NULL,NULL,NULL, NULL, NULL,NULL);
            vtemplate.reset(p);
        } catch (std::exception &e) {
            std::stringstream ss;
            ss << "# The template #" << itemplate << " (" << ftemplates[itemplate] << ") does not exist.";
            if (c.force_files_exist) {
                clog << ss.str() << " ABORT";
                throw;
            }
            clog << ss << " SKIP CC correlation.";
            vtemplate.reset(NULL);
        }
        if (vtemplate.get()) {
            // normalise it and compute its fourier transformation.
            vtemplate->stat(mean, variance, false);
            vtemplate->shift_scale<TFLOAT>(-mean, 1./sqrt(variance));
            avg.setValues(*vtemplate);
            plan_vtemplate.execute(avg, vtemplate_ft);
        }


        // Average the particles.

        if (!v1.empty() && v1.size()==v2.size()) {
            assert(do_fourier_shell);
            tom::avg::average(c.volsize, fparticles, wedge_particles, v1, itemplate, mask_sphere.get(), peak_list, anglesv, c.force_files_exist, &clog, avg, avgwedge_half);
            tom::avg::average(c.volsize, fparticles, wedge_particles, v2, itemplate, mask_sphere.get(), peak_list, anglesv, c.force_files_exist, &clog, avg2, avgwedge2_half);

            std::vector<double> res;
            std::size_t n_shells = c.volsize/2;

            FSC_w2->setValues(avgwedge_half);
            tom::element_wise_set_below_threshold<TFLOAT>(*FSC_w2, threshold*v1.size()/static_cast<double>(v_.size()), 0);
            tom::avg::apply_avgwedge(avg, *FSC_w2, mask_sphere.get(), c.fftw_flag, *FSC_v);
            //FSC_v->setValues(avg);
            //FSC_v->write_to_em("FSC_v1.em", NULL);
            FSC_plan1->execute(*FSC_v, *FSC_f1_half);

            FSC_w2->setValues(avgwedge2_half);
            tom::element_wise_set_below_threshold<TFLOAT>(*FSC_w2, threshold*v2.size()/static_cast<double>(v_.size()), 0);
            tom::avg::apply_avgwedge(avg2, *FSC_w2, mask_sphere.get(), c.fftw_flag, *FSC_v);
            //FSC_v->setValues(avg2);
            //FSC_v->write_to_em("FSC_v2.em", NULL);
            FSC_plan2->execute(*FSC_v, *FSC_f2_half);

            tom::fourier_shell_correlation(*FSC_f1_half, false, *FSC_f2_half, false, c.volsize, n_shells, res);

            ar.fsc.resize(n_shells);
            for (std::size_t i=0; i<n_shells; i++) {
                ar.fsc[i].first  = res[i+n_shells*1];
                ar.fsc[i].second = res[i+n_shells*7];
            }

            //tom::Volume<double>(&res[0], n_shells, 11, 1, 0,0,0, false, NULL).write_to_em("FSC_cc.em", NULL);

            tom::element_wise_add<TFLOAT, TFLOAT>(avg, avg2);
            tom::element_wise_add<TFLOAT, TFLOAT>(avgwedge_half, avgwedge2_half);
            if (!v3.empty()) {
                // Add the missing partivle to the average.
                tom::avg::average(c.volsize, fparticles, wedge_particles, v3, itemplate, mask_sphere.get(), peak_list, anglesv, c.force_files_exist, &clog, avg2, avgwedge2_half);
                tom::element_wise_add<TFLOAT, TFLOAT>(avg, avg2);
                tom::element_wise_add<TFLOAT, TFLOAT>(avgwedge_half, avgwedge2_half);
            }
        } else {
            tom::avg::average(c.volsize, fparticles, wedge_particles, v_, itemplate, mask_sphere.get(), peak_list, anglesv, c.force_files_exist, &clog, avg, avgwedge_half);
        }

        ////////////////////////////////////////////////////////////////////////
        // Save the average volume (the pure sum): avg_s
        avg.write_to_em(f_gen.get_avg_s(itemplate), NULL);
        tom::hermitian_symmetry_to_full(avgwedge);
        tom::fftshift(avgwedge, avgwedge2, true);
        avgwedge2.write_to_em(f_gen.get_avgwedge_s(itemplate), NULL);
        if (vtemplate.get()) {
            // Compute the correlation with the original template.
            avg.stat(mean, variance, false);
            if (variance) {
                avg2.setValues(avg); // make a copy for normalising.
                avg2.shift_scale<TFLOAT>(-mean, 1./sqrt(variance));
                plan_fwd.execute(avg2, avg_ft);
                tom::element_wise_conj_multiply<std::complex<TFLOAT>, std::complex<TFLOAT> >(avg_ft, vtemplate_ft);
                plan_bwd.execute(avg_ft, avg2);
                ar.ccval_s.reset(new double((avg2.get(0,0,0)/avg2.numel())/avg2.numel()));
            }
        }
        ////////////////////////////////////////////////////////////////////////

        // Set values below threshold in volume to 0
        tom::element_wise_set_below_threshold<TFLOAT>(avgwedge_half, threshold, 0);
        tom::hermitian_symmetry_to_full(avgwedge);

        avg2.setValues(avg);
        plan_fwd.execute(avg2, avg_ft);
        avg_ft2.setValues(avg_ft);

        ////////////////////////////////////////////////////////////////////////
        // Compute the average with frequencies weighted by N
        set_where_binary_mask_not_set<std::complex<TFLOAT>, TFLOAT>(avg_ft, avgwedge_half, 0);
        avg_ft.get(0,0,0) = 0;
        plan_bwd.execute(avg_ft, avg2);
        if (mask_sphere.get()) {
            tom::norm_mask<TFLOAT, TFLOAT, double>(avg2, *mask_sphere, tom::norm::NORM_STDDEV_1, NULL, true);
        } else {
            if ((variance=avg2.variance_mean_free(false))) {
                avg2.shift_scale<TFLOAT>(0, 1./sqrt(variance));
            }
        }
        avg2.write_to_em(f_gen.get_avg_n(itemplate), NULL);
        tom::fftshift(avgwedge, avgwedge2, true);
        avgwedge2.write_to_em(f_gen.get_avgwedge_n(itemplate), NULL);
        if (vtemplate.get()) {
            // Compute the correlation with the original template.
            avg2.stat(mean, variance, false);
            if (variance) {
                avg2.shift_scale<TFLOAT>(-mean, 1./sqrt(variance));
                plan_fwd.execute(avg2, avg_ft);
                tom::element_wise_conj_multiply<std::complex<TFLOAT>, std::complex<TFLOAT> >(avg_ft, vtemplate_ft);
                plan_bwd.execute(avg_ft, avg2);
                ar.ccval_n.reset(new double((avg2.get(0,0,0)/avg2.numel())/avg2.numel()));
            }
        }
        ////////////////////////////////////////////////////////////////////////

        ////////////////////////////////////////////////////////////////////////
        // Compute the average with frequencies weighted by sqrt(N)
        avgwedge_sqrtn_half.setValues(avgwedge_half);
        tom::element_wise_operation(avgwedge_sqrtn_half, &tom::math::sqrt<TFLOAT>);
        avg_ft.setValues(avg_ft2);
        tom::element_wise_div<std::complex<TFLOAT>, TFLOAT>(avg_ft, avgwedge_sqrtn_half, std::complex<TFLOAT>(0,0));
        avg_ft.get(0,0,0) = 0;
        plan_bwd.execute(avg_ft, avg2);
        if (mask_sphere.get()) {
            tom::norm_mask<TFLOAT, TFLOAT, double>(avg2, *mask_sphere, tom::norm::NORM_STDDEV_1, NULL, true);
        } else {
            if ((variance=avg2.variance_mean_free(false))) {
                avg2.shift_scale<TFLOAT>(0, 1./sqrt(variance));
            }
        }
        avg2.write_to_em(f_gen.get_avg_sqrtn(itemplate), NULL);
        tom::hermitian_symmetry_to_full(avgwedge_sqrtn);
        tom::fftshift(avgwedge_sqrtn, avgwedge2, true);
        avgwedge2.write_to_em(f_gen.get_avgwedge_sqrtn(itemplate), NULL);
        if (vtemplate.get()) {
            // Compute the correlation with the original template.
            avg2.stat(mean, variance, false);
            if (variance) {
                avg2.shift_scale<TFLOAT>(-mean, 1./sqrt(variance));
                plan_fwd.execute(avg2, avg_ft);
                tom::element_wise_conj_multiply<std::complex<TFLOAT>, std::complex<TFLOAT> >(avg_ft, vtemplate_ft);
                plan_bwd.execute(avg_ft, avg2);
                ar.ccval_sqrtn.reset(new double((avg2.get(0,0,0)/avg2.numel())/avg2.numel()));
            }
        }
        ////////////////////////////////////////////////////////////////////////

        ////////////////////////////////////////////////////////////////////////
        // Compute the average with frequencies weighted by 1
        avgwedge2_half.setValues(avgwedge_half);
        avg_ft.setValues(avg_ft2);
        tom::element_wise_div<std::complex<TFLOAT>, TFLOAT>(avg_ft, avgwedge2_half, std::complex<TFLOAT>(0,0));
        avg_ft.get(0,0,0) = 0;
        plan_bwd.execute(avg_ft, avg2);
        if (mask_sphere.get()) {
            tom::norm_mask<TFLOAT, TFLOAT, double>(avg2, *mask_sphere, tom::norm::NORM_STDDEV_1, NULL, true);
        } else {
            if ((variance=avg2.variance_mean_free(false))) {
                avg2.shift_scale<TFLOAT>(0, 1./sqrt(variance));
            }
        }
        avg2.write_to_em(f_gen.get_avg_1(itemplate), NULL);
        tom::make_binary(avgwedge2);
        tom::hermitian_symmetry_to_full(avgwedge2);
        tom::fftshift(avgwedge2, avgwedge, true);
        avgwedge.write_to_em(f_gen.get_avgwedge_1(itemplate), NULL);
        if (vtemplate.get()) {
            // Compute the correlation with the original template.
            avg2.stat(mean, variance, false);
            if (variance) {
                avg2.shift_scale<TFLOAT>(-mean, 1./sqrt(variance));
                plan_fwd.execute(avg2, avg_ft);
                tom::element_wise_conj_multiply<std::complex<TFLOAT>, std::complex<TFLOAT> >(avg_ft, vtemplate_ft);
                plan_bwd.execute(avg_ft, avg2);
                ar.ccval_1.reset(new double((avg2.get(0,0,0)/avg2.numel())/avg2.numel()));
            }
        }
        ////////////////////////////////////////////////////////////////////////

    }

    tom::avg::write_average_to_log(clog, ftemplates, fparticles, av, c.outputdir);

    clog << "# finished at " << helper::now2str() << std::endl;

    return 0;
}
Esempio n. 3
0
static int pix_abs16_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
                          ptrdiff_t stride, int h)
{
    int s = 0, i;
    uint8_t *pix3 = pix2 + stride;

    for (i = 0; i < h; i++) {
        s    += abs(pix1[0]  - avg2(pix2[0],  pix3[0]));
        s    += abs(pix1[1]  - avg2(pix2[1],  pix3[1]));
        s    += abs(pix1[2]  - avg2(pix2[2],  pix3[2]));
        s    += abs(pix1[3]  - avg2(pix2[3],  pix3[3]));
        s    += abs(pix1[4]  - avg2(pix2[4],  pix3[4]));
        s    += abs(pix1[5]  - avg2(pix2[5],  pix3[5]));
        s    += abs(pix1[6]  - avg2(pix2[6],  pix3[6]));
        s    += abs(pix1[7]  - avg2(pix2[7],  pix3[7]));
        s    += abs(pix1[8]  - avg2(pix2[8],  pix3[8]));
        s    += abs(pix1[9]  - avg2(pix2[9],  pix3[9]));
        s    += abs(pix1[10] - avg2(pix2[10], pix3[10]));
        s    += abs(pix1[11] - avg2(pix2[11], pix3[11]));
        s    += abs(pix1[12] - avg2(pix2[12], pix3[12]));
        s    += abs(pix1[13] - avg2(pix2[13], pix3[13]));
        s    += abs(pix1[14] - avg2(pix2[14], pix3[14]));
        s    += abs(pix1[15] - avg2(pix2[15], pix3[15]));
        pix1 += stride;
        pix2 += stride;
        pix3 += stride;
    }
    return s;
}
void Calib::computeProjectionMatrix()
{
    std::cout << "1111111111***********************************************************************************\n";
//    for(int i = 0;i < imagePoints.size();i++)
//    {
//        std::cout<<" imagePoints[i]= "<< imagePoints[i]<<std::endl;
//        std::cout<<" objectPoints[i]= "<< objectPoints[i]<<std::endl;
//    }

    if (objectPoints.size() != imagePoints.size())
        return;

    int n = objectPoints.size();

    Eigen::Vector2d avg2;
    Eigen::Vector3d avg3;

    for (unsigned int i = 0; i < n; i++)
    {
        avg2 += imagePoints[i];
        avg3 += objectPoints[i];
        std::cout << i << " " << objectPoints[i](0) << " " << objectPoints[i](1) << " " << objectPoints[i](2) << std::endl;
    }
    avg2 = avg2 / n;
    avg3 = avg3 / n;

    std::cout << "avg2 = " << avg2 << std::endl;
    std::cout << "avg3 = " << avg3 << std::endl;

    /* *******************************************************************************
  *  Data normalization
  *  Translates and normalises a set of 2D homogeneous points so that their centroid is at the origin and their mean distance from the origin is sqrt(2).
  */
    float meandist2 = 0;
    float meandist3 = 0;

    imagePoints_t.resize(n);
    objectPoints_t.resize(n);

    for (unsigned int i = 0; i < n; i++)
    {
        imagePoints_t[i] = imagePoints[i] - avg2;
        objectPoints_t[i] = objectPoints[i] - avg3;
//        std::cout << "1 imagePoints_t[i] = " << imagePoints_t[i] << std::endl;
//        std::cout << "1 objectPoints_t[i] = " << objectPoints_t[i] << std::endl;

        meandist2 += sqrt(imagePoints_t[i](0) * imagePoints_t[i](0) + imagePoints_t[i](1) * imagePoints_t[i](1));
        meandist3 += sqrt(objectPoints_t[i](0) * objectPoints_t[i](0) + objectPoints_t[i](1) * objectPoints_t[i](1)
                          + objectPoints_t[i](2) * objectPoints_t[i](2));
    }
    meandist2 /= n;
    meandist3 /= n;

    std::cout << "meandist2 = " << meandist2 << std::endl;
    std::cout << "meandist3 = " << meandist3 << std::endl;

    float scale2 = sqrt(2) / meandist2;
    float scale3 = sqrt(3) / meandist3;


    std::cout << "2222222222222***********************************************************************************\n";
    for (unsigned int i = 0; i < n; i++)
    {
        imagePoints_t[i] = scale2 * imagePoints_t[i];
        objectPoints_t[i] = scale3 * objectPoints_t[i];

//        std::cout << "imagePoints_t[i] = " << imagePoints_t[i] << std::endl;
//        std::cout << "objectPoints_t[i] = " << objectPoints_t[i] << std::endl;

    }

    //    std::cout<<avg3<<std::endl;
    /* *******************************************************************************
  * Similarity transformation T1 to normalize the image points,
  * and a second similarity transformation T2 to normalize the space points.
  * Page 181 in Multiple_View_Geometry_in_Computer_Vision__2nd_Edition
  */
    Eigen::Matrix3d T1;
    T1 << scale2, 0, -scale2 * avg2(0), 0, scale2, -scale2 * avg2(1), 0, 0, 1;

    Eigen::MatrixXd T2(4, 4);
    T2 << scale3, 0, 0, -scale3 * avg3(0), 0, scale3, 0, -scale3 * avg3(1), 0, 0, scale3, -scale3 * avg3(2), 0, 0, 0, 1;


    // use Eigen
    Eigen::MatrixXd A(2 * n, 12);
    A.setZero(2 * n, 12);

    for (int i = 0; i < n; i++)
    {

        A(2 * i, 0) = objectPoints_t[i](0);
        A(2 * i, 1) = objectPoints_t[i](1);
        A(2 * i, 2) = objectPoints_t[i](2);
        A(2 * i, 3) = 1;
        A(2 * i, 4) = 0;
        A(2 * i, 5) = 0;
        A(2 * i, 6) = 0;
        A(2 * i, 7) = 0;
        A(2 * i, 8) = -imagePoints_t[i](0) * objectPoints_t[i](0);
        A(2 * i, 9) = -imagePoints_t[i](0) * objectPoints_t[i](1);
        A(2 * i, 10) = -imagePoints_t[i](0) * objectPoints_t[i](2);
        A(2 * i, 11) = -imagePoints_t[i](0) * 1;

        A(2 * i + 1, 0) = 0;
        A(2 * i + 1, 1) = 0;
        A(2 * i + 1, 2) = 0;
        A(2 * i + 1, 3) = 0;
        A(2 * i + 1, 4) = 1 * objectPoints_t[i](0);
        A(2 * i + 1, 5) = 1 * objectPoints_t[i](1);
        A(2 * i + 1, 6) = 1 * objectPoints_t[i](2);
        A(2 * i + 1, 7) = 1;
        A(2 * i + 1, 8) = -imagePoints_t[i](1) * objectPoints_t[i](0);
        A(2 * i + 1, 9) = -imagePoints_t[i](1) * objectPoints_t[i](1);
        A(2 * i + 1, 10) = -imagePoints_t[i](1) * objectPoints_t[i](2);
        A(2 * i + 1, 11) = -imagePoints_t[i](1) * 1;

    }

    Eigen::JacobiSVD<Eigen::MatrixXd> svd(A, Eigen::ComputeFullU | Eigen::ComputeFullV);
    const Eigen::VectorXd & v1 = svd.matrixV().col(11);

    this->Pt << v1(0), v1(1), v1(2), v1(3), v1(4), v1(5), v1(6), v1(7), v1(8), v1(9), v1(10), v1(11);
//    std::cout<<"A= \n"<< A<<std::endl;
//    std::cout<<Pt<<std::endl;
    P = T1.inverse() * Pt * T2;


    //Decompose the projection matrix
    cv::Mat Pr(3, 4, cv::DataType<float>::type);
    cv::Mat Mt(3, 3, cv::DataType<float>::type);
    cv::Mat Rt(3, 3, cv::DataType<float>::type);
    cv::Mat Tt(4, 1, cv::DataType<float>::type);

    for (unsigned i = 0; i < 3; i++)
    {
        for (unsigned int j = 0; j < 4; j++)
        {
            Pr.at<float> (i, j) = P(i, j);
        }
    }
    cv::decomposeProjectionMatrix(Pr, Mt, Rt, Tt);

    //scale: Mt(2,2) should = 1; so update the projection matrix and decomposition again
    float k = (1 / (Mt.at<float> (2, 2)));

    /* ****************************************************************************************
      * Upate the projection matrix
      * Decomposition again to get new intrinsic matrix and rotation matrix
      */
    this->P = k * P;

    cv::Mat Pro(3, 4, cv::DataType<float>::type);
    cv::Mat Mc(3, 3, cv::DataType<float>::type); // intrinsic parameter matrix
    cv::Mat Rc(3, 3, cv::DataType<float>::type); // rotation matrix
    cv::Mat Tc(4, 1, cv::DataType<float>::type); // translation vector

    for (unsigned i = 0; i < 3; i++)
    {
        for (unsigned int j = 0; j < 4; j++)
        {
            Pro.at<float> (i, j) = P(i, j);
        }
    }
    cv::decomposeProjectionMatrix(Pro, Mc, Rc, Tc);

    // Change from OpenCV varibles to Eigen
    for (unsigned i = 0; i < 3; i++)
    {
        for (unsigned int j = 0; j < 3; j++)
        {
            M(i, j) = Mc.at<float> (i, j) ;
        }
    }


    /* ****************************************************************************************
      * Compute te rotation matrix R and translation vector T
      */
    P_temp = M.inverse() * P;
    this->R = this->P_temp.block(0,0,3,3);
    this->T = this->P_temp.block(0,3,3,1);


    std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
//    std::cout << "T1 =\n " << T2 << std::endl;
//    std::cout << "T2 =\n " << T1 << std::endl;
//    std::cout << "A =\n " << A << std::endl;
//    std::cout << "svd.matrixV() =\n " << svd.matrixV() << std::endl;
//    std::cout << "Pt =\n " << Pt << std::endl;
    std::cout << "P =\n " << P << std::endl;
    std::cout << "M =\n " << M << std::endl;
    std::cout << "R =\n " << R << std::endl;
    std::cout << "Rc =\n " << Rc << std::endl;
    std::cout << "T =\n " << T << std::endl;
    std::cout << "Mt(2,2) = " << Mt.at<float> (2, 2) << std::endl;

}