示例#1
0
bool output_odfs(const image::basic_image<unsigned char,3>& mni_mask,
                 const char* out_name,
                 const char* ext,
                 std::vector<std::vector<float> >& odfs,
                 const tessellated_icosahedron& ti,
                 const float* vs,
                 const float* mni,
                 const std::string& report,
                 bool record_odf = true)
{
    begin_prog("output");
    ImageModel image_model;
    if(report.length())
        image_model.voxel.report = report.c_str();
    image_model.voxel.dim = mni_mask.geometry();
    image_model.voxel.ti = ti;
    image_model.voxel.odf_decomposition = false;
    image_model.voxel.odf_deconvolusion = false;
    image_model.voxel.half_sphere = false;
    image_model.voxel.max_fiber_number = 5;
    image_model.voxel.z0 = 0.0;
    image_model.voxel.need_odf = record_odf;
    image_model.voxel.template_odfs.swap(odfs);
    image_model.voxel.param = mni;
    image_model.file_name = out_name;
    image_model.mask = mni_mask;
    std::copy(vs,vs+3,image_model.voxel.vs.begin());
    if (prog_aborted() || !image_model.reconstruct<reprocess_odf>(1))
        return false;
    image_model.save_fib(ext);
    image_model.voxel.template_odfs.swap(odfs);
    return true;
}
示例#2
0
bool output_odfs(const tipl::image<unsigned char,3>& mni_mask,
                 const char* out_name,
                 const char* ext,
                 std::vector<std::vector<float> >& odfs,
                 const tessellated_icosahedron& ti,
                 const float* vs,
                 const float* mni,
                 const std::string& report,
                 bool record_odf = true)
{
    begin_prog("output");
    ImageModel image_model;
    if(report.length())
        image_model.voxel.report = report.c_str();
    image_model.voxel.dim = mni_mask.geometry();
    image_model.voxel.ti = ti;
    image_model.voxel.max_fiber_number = 5;
    image_model.voxel.need_odf = record_odf;
    image_model.voxel.template_odfs.swap(odfs);
    image_model.file_name = out_name;
    image_model.voxel.mask = mni_mask;
    std::copy(mni,mni+16,image_model.voxel.trans_to_mni);
    std::copy(vs,vs+3,image_model.voxel.vs.begin());
    if (prog_aborted() || !image_model.reconstruct<reprocess_odf>())
        return false;
    image_model.save_fib(ext);
    image_model.voxel.template_odfs.swap(odfs);
    return true;
}
示例#3
0
 void save_fib(const std::string& ext)
 {
     std::string output_name = file_name;
     output_name += ext;
     begin_prog("saving data");
     gz_mat_write mat_writer(output_name.c_str());
     save_to_file(mat_writer);
     voxel.end(mat_writer);
     std::string final_report = voxel.report.c_str();
     final_report += voxel.recon_report.str();
     mat_writer.write("report",final_report.c_str(),1,final_report.length());
 }
示例#4
0
void MainWindow::on_RenameDICOM_clicked()
{
    QStringList filenames = QFileDialog::getOpenFileNames(
                                this,
                                "Open DICOM files",
                                ui->workDir->currentText(),
                                "All files (*)" );
    if ( filenames.isEmpty() )
        return;
    begin_prog("Rename DICOM Files");
    for (unsigned int index = 0;check_prog(index,filenames.size());++index)
        RenameDICOMToDir(filenames[index],QFileInfo(filenames[index]).absolutePath());
}
示例#5
0
 bool reconstruct(unsigned int thread_count)
 {
     begin_prog("reconstruction");
     voxel.image_model = this;
     voxel.CreateProcesses<ProcessType>();
     voxel.init(thread_count);
     boost::thread_group threads;
     for (unsigned int index = 1;index < thread_count;++index)
         threads.add_thread(new boost::thread(&Voxel::thread_run,&voxel,
                                              index,thread_count,mask));
     voxel.thread_run(0,thread_count,mask);
     threads.join_all();
     return !prog_aborted();
 }
示例#6
0
void MainWindow::loadFib(QString filename)
{
    std::string file_name = filename.toLocal8Bit().begin();
    begin_prog("load fib");
    std::shared_ptr<fib_data> new_handle(new fib_data);
    if (!new_handle->load_from_file(&*file_name.begin()))
    {
        if(!prog_aborted())
            QMessageBox::information(this,"error",new_handle->error_msg.c_str(),0);
        return;
    }
    tracking_window* new_mdi = new tracking_window(this,new_handle);
    new_mdi->setAttribute(Qt::WA_DeleteOnClose);
    new_mdi->setWindowTitle(filename);
    new_mdi->showNormal();
    addFib(filename);
    add_work_dir(QFileInfo(filename).absolutePath());
    QDir::setCurrent(QFileInfo(filename).absolutePath());
}
void individual_connectometry::on_compare_clicked()
{
    unsigned char normalization;
    if(ui->norm0->isChecked())
        normalization = 0;
    if(ui->norm1->isChecked())
        normalization = 1;
    if(ui->norm2->isChecked())
        normalization = 2;
    if(ui->norm3->isChecked())
        normalization = 3;
    QSettings settings;
    settings.setValue("individual_connectometry_norm",(int)normalization);

    begin_prog("comparing");
    if(ui->inv_db->isChecked())
    {
        if(!cur_tracking_window.cnt_result.individual_vs_db(cur_tracking_window.handle,subject2_file.toLocal8Bit().begin()))
            QMessageBox::information(this,"Error",cur_tracking_window.cnt_result.error_msg.c_str());
    }

    if(ui->inv_template->isChecked())
    {
        if(!cur_tracking_window.cnt_result.individual_vs_atlas(cur_tracking_window.handle,subject2_file.toLocal8Bit().begin(),normalization))
            QMessageBox::information(this,"Error",cur_tracking_window.cnt_result.error_msg.c_str());
    }

    if(ui->inv_inv->isChecked())
    {
        if(!cur_tracking_window.cnt_result.individual_vs_individual(cur_tracking_window.handle,
                                                                    subject_file.toLocal8Bit().begin(),subject2_file.toLocal8Bit().begin(),normalization))
            QMessageBox::information(this,"Error",cur_tracking_window.cnt_result.error_msg.c_str());
    }
    cur_tracking_window.initialize_tracking_index(cur_tracking_window.handle->dir.index_data.size()-1);
    cur_tracking_window.scene.show_slice();
    check_prog(0,0);
    hide();
    accept();

}
示例#8
0
void MainWindow::on_batch_src_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(
                                this,
                                "Open directory",
                                ui->workDir->currentText());
    if(dir.isEmpty())
        return;
    add_work_dir(dir);

    {
        QStringList dir_list;
        dir_list << dir;
        bool all = false;
        bool choice = false;
        begin_prog("batch creating src");
        for(unsigned int i = 0;check_prog(i,dir_list.size()) && !prog_aborted();++i)
        {
            QDir cur_dir = dir_list[i];
            QStringList new_list = cur_dir.entryList(QStringList(""),QDir::AllDirs|QDir::NoDotAndDotDot);
            for(unsigned int index = 0;index < new_list.size();++index)
                dir_list << cur_dir.absolutePath() + "/" + new_list[index];


            std::vector<std::shared_ptr<DwiHeader> > dwi_files;


            if(QFileInfo(dir_list[i] + "/data.nii.gz").exists() &&
               QFileInfo(dir_list[i] + "/bvals").exists() &&
               QFileInfo(dir_list[i] + "/bvecs").exists() &&
               load_4d_nii(QString(dir_list[i] + "/data.nii.gz").toLocal8Bit().begin(),dwi_files))
            {
                DwiHeader::output_src(QString(dir_list[i] + "/data.src.gz").toLocal8Bit().begin(),dwi_files,0);
                continue;
            }

            QStringList nifti_file_list = cur_dir.entryList(QStringList("*.nii.gz"),QDir::Files|QDir::NoSymLinks);
            for (unsigned int index = 0;index < nifti_file_list.size();++index)
            {
                if(QFileInfo(dir_list[i] + "/" + QFileInfo(nifti_file_list[index]).baseName()+".bval").exists() &&
                   QFileInfo(dir_list[i] + "/" + QFileInfo(nifti_file_list[index]).baseName()+".bvec").exists() &&
                    load_4d_nii(QString(dir_list[i] + "/" + nifti_file_list[index]).toLocal8Bit().begin(),dwi_files))
                {
                    DwiHeader::output_src(QString(dir_list[i] + "/" +
                        QFileInfo(nifti_file_list[index]).baseName() + ".src.gz").toLocal8Bit().begin(),dwi_files,0);
                    continue;
                }
            }

            QStringList dicom_file_list = cur_dir.entryList(QStringList("*.dcm"),QDir::Files|QDir::NoSymLinks);
            if(dicom_file_list.empty())
                continue;
            for (unsigned int index = 0;index < dicom_file_list.size();++index)
                dicom_file_list[index] = dir_list[i] + "/" + dicom_file_list[index];
            QString output = dir_list[i] + "/" + QFileInfo(get_src_name(dicom_file_list[0])).baseName()+".src.gz";
            if(QFileInfo(output).exists())
            {
                if(!all)
                {
                    QMessageBox msgBox;
                    msgBox.setText(QString("Existing SRC file ") + output);
                    msgBox.setInformativeText("Overwrite?");
                    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoAll);
                    msgBox.setDefaultButton(QMessageBox::Save);
                    switch(msgBox.exec())
                    {
                    case QMessageBox::YesToAll:
                        all = true;
                    case QMessageBox::Yes:
                        choice = true;
                        break;
                    case QMessageBox::NoAll:
                        all = true;
                    case QMessageBox::No:
                        choice = false;
                        break;
                    }
                }
                if(!choice)
                    continue;
            }
            if(!load_all_files(dicom_file_list,dwi_files) || prog_aborted())
                continue;
            if(dwi_files.size() == 1) //MPRAGE or T2W
            {
                std::sort(dicom_file_list.begin(),dicom_file_list.end(),compare_qstring());
                image::io::volume v;
                image::io::dicom header;
                std::vector<std::string> file_list;
                for(unsigned int index = 0;index < dicom_file_list.size();++index)
                    file_list.push_back(dicom_file_list[index].toLocal8Bit().begin());
                if(!v.load_from_files(file_list,file_list.size()) ||
                   !header.load_from_file(dicom_file_list[0].toLocal8Bit().begin()))
                    continue;
                image::basic_image<float,3> I;
                image::vector<3> vs;
                v >> I;
                v.get_voxel_size(vs.begin());
                gz_nifti nii_out;
                image::flip_xy(I);
                nii_out << I;
                nii_out.set_voxel_size(vs);


                std::string manu,make,seq,report;
                header.get_text(0x0008,0x0070,manu);//Manufacturer
                header.get_text(0x0008,0x1090,make);
                header.get_text(0x0018,0x1030,seq);
                std::replace(manu.begin(),manu.end(),' ',(char)0);
                make.erase(std::remove(make.begin(),make.end(),' '),make.end());
                std::ostringstream out;
                out << manu.c_str() << " " << make.c_str() << " " << seq
                    << ".TE=" << header.get_float(0x0018,0x0081) << ".TR=" << header.get_float(0x0018,0x0080)  << ".";
                report = out.str();
                std::copy(report.begin(),report.begin() + std::min<int>(80,report.length()+1),nii_out.nif_header.descrip);

                QString output_name = QFileInfo(get_src_name(dicom_file_list[0])).absolutePath() + "/" +
                                      QFileInfo(get_src_name(dicom_file_list[0])).baseName()+ "."+seq.c_str() + ".nii.gz";
                nii_out.save_to_file(output_name.toLocal8Bit().begin());
            }
            else
            {
                for(unsigned int index = 0;index < dwi_files.size();++index)
                    if(dwi_files[index]->get_bvalue() < 100)
                    {
                        dwi_files[index]->set_bvalue(0);
                        dwi_files[index]->set_bvec(0,0,0);
                    }
                DwiHeader::output_src(output.toLocal8Bit().begin(),dwi_files,0);
            }
        }
示例#9
0
const char* odf_average(const char* out_name,std::vector<std::string>& file_names)
{
    static std::string error_msg,report;
    tessellated_icosahedron ti;
    float vs[3];
    tipl::image<unsigned char,3> mask;
    std::vector<std::vector<float> > odfs;
    unsigned int half_vertex_count = 0;
    unsigned int row,col;
    float mni[16]={0};
    begin_prog("averaging");
    for (unsigned int index = 0;check_prog(index,file_names.size());++index)
    {
        const char* file_name = file_names[index].c_str();
        gz_mat_read reader;
        set_title(file_names[index].c_str());
        if(!reader.load_from_file(file_name))
        {
            error_msg = "Cannot open file ";
            error_msg += file_name;
            check_prog(0,0);
            return error_msg.c_str();
        }
        if(index == 0)
        {
            {
                const char* report_buf = 0;
                if(reader.read("report",row,col,report_buf))
                    report = std::string(report_buf,report_buf+row*col);
            }
            const float* odf_buffer;
            const short* face_buffer;
            const unsigned short* dimension;
            const float* vs_ptr;
            const float* fa0;
            const float* mni_ptr;
            unsigned int face_num,odf_num;
            error_msg = "";
            if(!reader.read("dimension",row,col,dimension))
                error_msg = "dimension";
            if(!reader.read("fa0",row,col,fa0))
                error_msg = "fa0";
            if(!reader.read("voxel_size",row,col,vs_ptr))
                error_msg = "voxel_size";
            if(!reader.read("odf_faces",row,face_num,face_buffer))
                error_msg = "odf_faces";
            if(!reader.read("odf_vertices",row,odf_num,odf_buffer))
                error_msg = "odf_vertices";
            if(!reader.read("trans",row,col,mni_ptr))
                error_msg = "trans";
            if(error_msg.length())
            {
                error_msg += " missing in ";
                error_msg += file_name;
                check_prog(0,0);
                return error_msg.c_str();
            }
            mask.resize(tipl::geometry<3>(dimension));
            for(unsigned int index = 0;index < mask.size();++index)
                if(fa0[index] != 0.0)
                    mask[index] = 1;
            std::copy(vs_ptr,vs_ptr+3,vs);
            ti.init(odf_num,odf_buffer,face_num,face_buffer);
            half_vertex_count = odf_num >> 1;
            std::copy(mni_ptr,mni_ptr+16,mni);
        }
        else
        // check odf consistency
        {
示例#10
0
void gen_dialog::on_buttonBox_accepted()
{
    begin_prog("Generate images");
    for(unsigned int index = 0;check_prog(index,file_list.size());++index)
    {
        wsi w;
        if(QFileInfo(file_list[index]).suffix() != "gz") // recognition file
        {
            if(!w.open(file_list[index].toLocal8Bit().begin()))
            {
                QMessageBox::information(this,"Error",file_list[index] + " is an invalid file",0);
                continue;
            }
            if(!w.load_text_reco_result((file_list[index]+".txt").toLocal8Bit().begin()))
            {
                QMessageBox::information(this,"Error",file_list[index] + " has no recognition results",0);
                continue;
            }
        }
        else
        if(!w.load_recognition_result(file_list[index].toLocal8Bit().begin()))
        {
            QMessageBox::information(this,"Error",file_list[index] + " is an invalid file",0);
            continue;
        }
        tipl::image<float,2> sdi_value;
        tipl::image<unsigned char,2> sdi_contour;
        w.get_distribution_image(sdi_value,sdi_contour,
                                 ui->resolution->value(),ui->resolution->value(),
                                 ui->type->currentIndex());

        tipl::color_image sdi_image(sdi_value.geometry());

        {
            float r = 255.99/(ui->value_max->value()-ui->value_min->value());
            for(unsigned int index = 0;index < sdi_value.size();++index)
            {
                int i = std::max<int>(0,std::min<int>(255,std::floor((sdi_value[index]-ui->value_min->value())*r)));
                sdi_image[index] = colormap[i];
            }
        }
        if(ui->contour->isChecked())
        {
            for(unsigned int index = 0;index < sdi_value.size();++index)
                if(sdi_contour[index])
                    sdi_value[index] = 0;
        }

        if(ui->format->currentIndex() == 1)// mat
        {
            QString output_file = file_list[index] + ".mat";
            tipl::io::mat_write mat(output_file.toLocal8Bit().begin());
            mat << sdi_value;
        }
        if(ui->format->currentIndex() == 0)// tif
        {
            QString output_file = file_list[index] + ".jpg";
            QImage I((unsigned char*)&*sdi_image.begin(),sdi_image.width(),sdi_image.height(),QImage::Format_RGB32);
            I.save(output_file);
        }
        if(w.is_tma)
        {
            QString output_file = file_list[index] + ".tma.txt";
            w.save_tma_result(output_file.toStdString().c_str(),ui->label_on_right->isChecked());
        }
    }
}
示例#11
0
    void createLayout(const char* file_name,
                      float fa_value,
                      const std::vector<float>& angle_iteration,
                      unsigned int repeat_num,
                      unsigned int phantom_width,
                      unsigned int boundary)
    {
        float iso_fraction = 0.2f;
        float fiber_fraction = 1.0f-iso_fraction;
        dim[0] = phantom_width+boundary+boundary;
        dim[1] = phantom_width+boundary+boundary;
        dim[2] = std::max<int>(1,angle_iteration.size())*repeat_num;

        unsigned int total_size = dim.size();
        std::vector<float> fa[2];
        std::vector<float> gfa;
        std::vector<short> findex[2];

        models.resize(total_size);
        fa[0].resize(total_size);
        fa[1].resize(total_size);

        gfa.resize(total_size);
        findex[0].resize(total_size);
        findex[1].resize(total_size);


        unsigned int main_fiber_index = ti.discretize(tipl::vector<3>(1.0,0.0,0.0));

        std::fill(models.begin(),models.end(),(MixGaussianModel*)0);
        begin_prog("creating layout");

        if(angle_iteration.empty()) // use 0 to 90 degrees crossing
            for (unsigned int n = 0,index = 0; n < repeat_num; ++n)
                    {
                        if (!check_prog(index,total_size))
                            break;
                        float fa2 = fa_value*fa_value;
                        //fa*fa = (r*r-2*r+1)/(r*r+2)
                        float r = (1.0+fa_value*std::sqrt(3-2*fa2))/(1-fa2);
                        float l2 = mean_dif*3.0/(2.0+r);
                        float l1 = r*l2;
                        for (unsigned int y = 0; y < dim[1]; ++y)
                        {
                            for (unsigned int x = 0; x < dim[0]; ++x,++index)
                            {
                                if (x >= boundary &&
                                    x < boundary+phantom_width &&
                                    y >= boundary &&
                                    y < boundary+phantom_width)
                                {
                                    float xf = ((float)x - boundary + 1)/((float)phantom_width);//from 0.02 to 1.00
                                    xf = 1.0f-xf;//0.00 to 0.98
                                    xf = 0.5f+0.5f*xf;//0.50 to 0.99
                                    float angle = ((float)y - boundary)/((float)phantom_width);//0.00 to 0.98
                                    angle = 1.0f-angle;//0.02 to 1.00
                                    angle *= float(M_PI*0.5f);//1.8 degrees 90 degrees
                                    models[index] = new MixGaussianModel(l1,l2,mean_dif,angle,
                                                                         fiber_fraction*xf,
                                                                         fiber_fraction*(1.0-xf));
                                    fa[0][index] = fiber_fraction*xf;
                                    fa[1][index] = fiber_fraction*(1.0-xf);
                                    gfa[index] = fa_value;
                                    findex[0][index] = main_fiber_index;
                                    findex[1][index] = ti.discretize(tipl::vector<3>(std::cos(angle),std::sin(angle),0.0));
                                }
                            }
                        }
                    }
        else
            for (unsigned int j = 0,index = 0; j < angle_iteration.size(); ++j)
                for (unsigned int n = 0; n < repeat_num; ++n)
                {
                    if (!check_prog(index,total_size))
                        break;
                    float inner_angle = angle_iteration[j]*M_PI/180.0;
                    float fa2 = fa_value*fa_value;
                    //fa*fa = (r*r-2*r+1)/(r*r+2)
                    float r = (1.0+fa_value*std::sqrt(3-2*fa2))/(1-fa2);
                    float l2 = mean_dif*3.0/(2.0+r);
                    float l1 = r*l2;
                    for (unsigned int y = 0; y < dim[1]; ++y)
                    {
                        for (unsigned int x = 0; x < dim[0]; ++x,++index)
                        {
                            if (x >= boundary &&
                                x < boundary+phantom_width &&
                                y >= boundary &&
                                y < boundary+phantom_width)
                            {
                                if(inner_angle >= 0.0)
                                    models[index] = new MixGaussianModel(l1,l2,mean_dif,inner_angle,0.5,0.5);
                                else
                                    models[index] = new GaussianDispersion(l1,l2,mean_dif,inner_angle,1.0);
                                fa[0][index] = fiber_fraction/2.0;
                                fa[1][index] = fiber_fraction/2.0;
                                gfa[index] = fa_value;
                                findex[0][index] = main_fiber_index;
                                findex[1][index] = ti.discretize(tipl::vector<3>(std::cos(inner_angle),std::sin(inner_angle),0.0));
                            }
                        }
                    }
                }

        set_title("Generating images");

        std::string fib_file_name(file_name);
        fib_file_name += ".layout.fib";
        gz_mat_write mat_writer(file_name),mat_layout(fib_file_name.c_str());
        // output dimension
        {
            mat_writer.write("dimension",&*dim.begin(),1,3);
            mat_layout.write("dimension",&*dim.begin(),1,3);
        }
        // output vexol size
        {
            float vs[3] = {1.0,1.0,1.0};
            mat_writer.write("voxel_size",vs,1,3);
            mat_layout.write("voxel_size",vs,1,3);
        }
        // output b_table
        {
            std::vector<float> buffer;
            buffer.reserve(bvalues.size()*4);
            for (unsigned int index = 0; index < bvalues.size(); ++index)
            {
                buffer.push_back(bvalues[index]);
                std::copy(bvectors[index].begin(),bvectors[index].end(),std::back_inserter(buffer));
            }
            mat_writer.write("b_table",&*buffer.begin(),4,bvalues.size());
        }
        // output images
        {
            std::vector<short> buffer(models.size());
            begin_prog("generating images");
            for (unsigned int index = 0; check_prog(index,bvectors.size()); ++index)
            {
                for (unsigned int i = 0; i < models.size(); ++i)
                {
                    if (models[i])
                        buffer[i] = encodeNoise((*models[i])(bvalues[index]/1000.0,bvectors[index])*spin_density*0.5); // 0.5 volume of water
                    else
                        buffer[i] = encodeNoise(spin_density*exp(-bvalues[index]*0.0016));
                    // water its coefficient is 0.0016 mm?/s
                }
                std::ostringstream out;
                out << "image" << index;
                mat_writer.write(out.str().c_str(),&*buffer.begin(),1,buffer.size());
            }
        }
        // output layout
        {
            std::vector<float> float_data;
            std::vector<short> short_data;
            ti.save_to_buffer(float_data,short_data);
            mat_layout.write("odf_vertices",&*float_data.begin(),3,ti.vertices_count);
            mat_layout.write("odf_faces",&*short_data.begin(),3,ti.faces.size());
            mat_layout.write("fa0",&*fa[0].begin(),1,fa[0].size());
            mat_layout.write("fa1",&*fa[1].begin(),1,fa[1].size());
            mat_layout.write("gfa",&*gfa.begin(),1,gfa.size());
            mat_layout.write("index0",&*findex[0].begin(),1,findex[0].size());
            mat_layout.write("index1",&*findex[1].begin(),1,findex[1].size());

        }


    }
    virtual void init(Voxel& voxel)
    {
        if(voxel.vs[0] == 0.0 ||
           voxel.vs[1] == 0.0 ||
           voxel.vs[2] == 0.0)
            throw std::runtime_error("No spatial information found in src file. Recreate src file or contact developer for assistance");

        begin_prog("normalization");

        VG = fa_template_imp.I;
        VF = voxel.fa_map;

        image::filter::gaussian(voxel.fa_map);
        image::filter::gaussian(voxel.fa_map);
        image::filter::gaussian(voxel.qa_map);
        image::filter::gaussian(voxel.qa_map);
        image::normalize(voxel.fa_map,1.0);
        image::normalize(voxel.qa_map,1.0);
        for(unsigned int index = 0;index < voxel.qa_map.size();++index)
            if(voxel.qa_map[index] == 0.0 || voxel.fa_map[index]/voxel.qa_map[index] > 2.5)
                VF[index] = 0.0;
        image::filter::gaussian(VF);

        src_geo = VF.geometry();

        image::normalize(VF,1.0);
        //VF.save_to_file<image::io::nifti<> >("VF.nii");

        image::normalize(VG,1.0);

        // get rid of the gray matters
        image::minus_constant(VF.begin(),VF.end(),0.3);
        image::lower_threshold(VF.begin(),VF.end(),0.00);
        image::normalize(VF,1.0);

        image::minus_constant(VG.begin(),VG.end(),0.3);
        image::lower_threshold(VG.begin(),VG.end(),0.00);
        image::normalize(VG,1.0);

        VGvs[0] = std::fabs(fa_template_imp.tran[0]);
        VGvs[1] = std::fabs(fa_template_imp.tran[5]);
        VGvs[2] = std::fabs(fa_template_imp.tran[10]);

        image::affine_transform<3,double> arg_min;
        // VG: FA TEMPLATE
        // VF: SUBJECT QA
        arg_min.scaling[0] = voxel.vs[0] / VGvs[0];
        arg_min.scaling[1] = voxel.vs[1] / VGvs[1];
        arg_min.scaling[2] = voxel.vs[2] / VGvs[2];
        voxel_volume_scale = arg_min.scaling[0]*arg_min.scaling[1]*arg_min.scaling[2];
        // calculate center of mass
        image::vector<3,double> mF = center_of_mass(VF);
        image::vector<3,double> mG = center_of_mass(VG);

        arg_min.translocation[0] = mG[0]-mF[0]*arg_min.scaling[0];
        arg_min.translocation[1] = mG[1]-mF[1]*arg_min.scaling[1];
        arg_min.translocation[2] = mG[2]-mF[2]*arg_min.scaling[2];


        bool terminated = false;
        set_title("linear registration");
        begin_prog("conducting registration");
        check_prog(0,2);
        image::reg::linear(VF,VG,arg_min,image::reg::affine,image::reg::square_error(),terminated,0.25);
        check_prog(1,2);

        // create VFF the affine transformed VF
        image::basic_image<float,3> VFF(VG.geometry());
        {

            affine = arg_min;
            image::reg::linear_get_trans(VF.geometry(),VG.geometry(),affine);
            {
                std::vector<double> T(16);
                affine.save_to_transform(T.begin());
                T[15] = 1.0;
                math::matrix_inverse(T.begin(),math::dim<4,4>());
                affine.load_from_transform(T.begin());
            }

            image::resample(VF,VFF,affine);

            //VFF.save_to_file<image::io::nifti<> >("VFF.nii");
            //VG.save_to_file<image::io::nifti<> >("VG.nii");

        }
        {
            switch(voxel.reg_method)
            {
                case 0:
                    mni.normalize(VG,VFF);
                break;
                case 1:
                    mni.normalize(VG,VFF,12,14,12,4,8);
                break;
            }

            //calculate the goodness of fit
            std::vector<float> x,y;
            x.reserve(VG.size());
            y.reserve(VG.size());
            image::interpolation<image::linear_weighting,3> trilinear_interpolation;
            for(image::pixel_index<3> index;VG.geometry().is_valid(index);
                    index.next(VG.geometry()))
                if(VG[index.index()] != 0)
                {
                    image::vector<3,double> pos;
                    mni.warp_coordinate(index,pos);
                    double value = 0.0;
                    if(!trilinear_interpolation.estimate(VFF,pos,value))
                        continue;
                    x.push_back(VG[index.index()]);
                    y.push_back(value);
                }
            R2 = x.empty() ? 0.0 : image::correlation(x.begin(),x.end(),y.begin());
            R2 *= R2;
            std::cout << "R2 = " << R2 << std::endl;
        }

        check_prog(2,2);


        // setup output bounding box
        {
            //setBoundingBox(-78,-112,-50,78,76,85,1.0);
            float voxel_size = voxel.param[1];
            bounding_box_lower[0] = std::floor(-78.0/voxel_size+0.5)*voxel_size;
            bounding_box_lower[1] = std::floor(-112.0/voxel_size+0.5)*voxel_size;
            bounding_box_lower[2] = std::floor(-50.0/voxel_size+0.5)*voxel_size;
            bounding_box_upper[0] = std::floor(78.0/voxel_size+0.5)*voxel_size;
            bounding_box_upper[1] = std::floor(76.0/voxel_size+0.5)*voxel_size;
            bounding_box_upper[2] = std::floor(85.0/voxel_size+0.5)*voxel_size;
            des_geo[0] = (bounding_box_upper[0]-bounding_box_lower[0])/voxel_size+1;//79
            des_geo[1] = (bounding_box_upper[1]-bounding_box_lower[1])/voxel_size+1;//95
            des_geo[2] = (bounding_box_upper[2]-bounding_box_lower[2])/voxel_size+1;//69
            des_offset[0] = bounding_box_lower[0]/VGvs[0]-fa_template_imp.tran[3]/fa_template_imp.tran[0];
            des_offset[1] = bounding_box_lower[1]/VGvs[1]-fa_template_imp.tran[7]/fa_template_imp.tran[5];
            des_offset[2] = bounding_box_lower[2]/VGvs[2]-fa_template_imp.tran[11]/fa_template_imp.tran[10];
            scale[0] = voxel_size/VGvs[0];
            scale[1] = voxel_size/VGvs[1];
            scale[2] = voxel_size/VGvs[2];
        }

        begin_prog("q-space diffeomorphic reconstruction");


        float sigma = voxel.param[0]; //diffusion sampling length ratio, optimal 1.24
        // setup mask
        {
            // set the current mask to template space
            voxel.image_model->set_dimension(des_geo[0],des_geo[1],des_geo[2]);
            for(image::pixel_index<3> index;des_geo.is_valid(index);index.next(des_geo))
            {
                image::vector<3,int> mni_pos(index);
                mni_pos *= voxel.param[1];
                mni_pos[0] /= VGvs[0];
                mni_pos[1] /= VGvs[1];
                mni_pos[2] /= VGvs[2];
                mni_pos += des_offset;
                voxel.image_model->mask[index.index()] =
                        fa_template_imp.I.at(mni_pos[0],mni_pos[1],mni_pos[2]) > 0.0? 1: 0;
            }
        }


        q_vectors_time.resize(voxel.bvalues.size());
        for (unsigned int index = 0; index < voxel.bvalues.size(); ++index)
        {
            q_vectors_time[index] = voxel.bvectors[index];
            q_vectors_time[index] *= std::sqrt(voxel.bvalues[index]*0.01506);// get q in (mm) -1
            q_vectors_time[index] *= sigma;
        }

        b0_index = -1;
        if(voxel.half_sphere)
            for(unsigned int index = 0;index < voxel.bvalues.size();++index)
                if(voxel.bvalues[index] == 0)
                    b0_index = index;

        ptr_images.clear();
        for (unsigned int index = 0; index < voxel.image_model->dwi_data.size(); ++index)
            ptr_images.push_back(point_image_type((const unsigned short*)voxel.image_model->dwi_data[index],src_geo));


        voxel.qa_scaling = voxel.reponse_function_scaling/voxel.vs[0]/voxel.vs[1]/voxel.vs[2];
        max_accumulated_qa = 0;

        std::fill(voxel.vs.begin(),voxel.vs.end(),voxel.param[1]);

        jdet.resize(des_geo.size());


        if (voxel.odf_deconvolusion)
        {
            gqi.init(voxel);
            deconvolution.init(voxel);
        }
        if (voxel.odf_decomposition)
        {
            gqi.init(voxel);
            decomposition.init(voxel);
        }
        angle_variance = 8; //degress;
        angle_variance *= M_PI/180;
        angle_variance *= angle_variance;
        angle_variance *= 2.0;

    }
示例#13
0
    const char* reconstruction(ImageModel* image_model,unsigned int method_id,const float* param_values)
{
    static std::string output_name;
    try
    {
        {
            std::vector<unsigned int> shell;
            if(image_model->voxel.bvalues.front() != 0.0)
                shell.push_back(0);
            for(unsigned int index = 1;index < image_model->voxel.bvalues.size();++index)
                if(std::abs(image_model->voxel.bvalues[index]-image_model->voxel.bvalues[index-1]) > 100)
                    shell.push_back(index);

            image_model->voxel.half_sphere =
                    (method_id == 7 || method_id == 4) &&
                    (shell.size() > 5) && (shell[1] - shell[0] <= 3);
            image_model->voxel.scheme_balance =
                    (method_id == 7 || method_id == 4) &&
                    (shell.size() <= 5) && !shell.empty() &&
                    image_model->voxel.bvalues.size()-shell.back() < 100;
        }


        image_model->voxel.recon_report.clear();
        image_model->voxel.recon_report.str("");
        image_model->voxel.param = param_values;
        std::ostringstream out;
        if(method_id == 1) // DTI
        {
            image_model->voxel.need_odf = 0;
            image_model->voxel.output_jacobian = 0;
            image_model->voxel.output_mapping = 0;
            image_model->voxel.scheme_balance = 0;
            image_model->voxel.half_sphere = 0;
            image_model->voxel.odf_deconvolusion = 0;
            image_model->voxel.odf_decomposition = 0;
        }
        if(method_id != 1) // not DTI
        {
            out << ".odf" << image_model->voxel.ti.fold;// odf_order
            out << ".f" << image_model->voxel.max_fiber_number;
            if (image_model->voxel.need_odf)
                out << "rec";
            if (image_model->voxel.scheme_balance)
                out << ".bal";
            if (image_model->voxel.half_sphere)
                out << ".hs";
            if (image_model->voxel.odf_deconvolusion)
            {
                out << ".de" << param_values[2];
                if(image_model->voxel.odf_xyz[0] != 0 ||
                   image_model->voxel.odf_xyz[1] != 0 ||
                   image_model->voxel.odf_xyz[2] != 0)
                    out << ".at_" << image_model->voxel.odf_xyz[0]
                        << "_" << image_model->voxel.odf_xyz[1]
                        << "_" << image_model->voxel.odf_xyz[2];
            }
            if (image_model->voxel.odf_decomposition)
            {
                out << ".dec" << param_values[3] << "m" << (int)param_values[4];
                if(image_model->voxel.odf_xyz[0] != 0 ||
                   image_model->voxel.odf_xyz[1] != 0 ||
                   image_model->voxel.odf_xyz[2] != 0)
                    out << ".at_" << image_model->voxel.odf_xyz[0]
                        << "_" << image_model->voxel.odf_xyz[1]
                        << "_" << image_model->voxel.odf_xyz[2];
            }
        }
        // correct for b-table orientation

        {
            set_title("checking b-table");
            image_model->reconstruct<dti_process>();
            std::vector<std::vector<float> > fib_fa(1);
            std::vector<std::vector<float> > fib_dir(1);
            fib_fa[0].swap(image_model->voxel.fib_fa);
            fib_dir[0].swap(image_model->voxel.fib_dir);
            unsigned int cur_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first;
            flip_fib_dir(fib_dir[0],true,false,false);
            unsigned int flip_x_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first;
            flip_fib_dir(fib_dir[0],true,true,false);
            unsigned int flip_y_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first;
            flip_fib_dir(fib_dir[0],false,true,true);
            unsigned int flip_z_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first;
            if(flip_x_score > cur_score &&
               flip_x_score > flip_y_score && flip_x_score > flip_z_score)
            {
                std::cout << "b-table flipped x" << std::endl;
                for(unsigned int index = 0;index < image_model->voxel.bvectors.size();++index)
                    image_model->voxel.bvectors[index][0] = -image_model->voxel.bvectors[index][0];
            }
            if(flip_y_score > cur_score &&
               flip_y_score > flip_x_score && flip_y_score > flip_z_score)
            {
                std::cout << "b-table flipped y" << std::endl;
                for(unsigned int index = 0;index < image_model->voxel.bvectors.size();++index)
                    image_model->voxel.bvectors[index][1] = -image_model->voxel.bvectors[index][1];
            }
            if(flip_z_score > cur_score &&
               flip_z_score > flip_y_score && flip_z_score > flip_x_score)
            {
                std::cout << "b-table flipped z" << std::endl;
                for(unsigned int index = 0;index < image_model->voxel.bvectors.size();++index)
                    image_model->voxel.bvectors[index][2] = -image_model->voxel.bvectors[index][2];
            }

        }




        switch (method_id)
        {
        case 0: //DSI local max
            image_model->voxel.recon_report <<
            " The diffusion data were reconstructed using diffusion spectrum imaging (Wedeen et al. MRM, 2005) with a Hanning filter of " << (int)param_values[0] << ".";
            if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition)
            {
                if (!image_model->reconstruct<dsi_estimate_response_function>())
                    return "reconstruction calceled";
                begin_prog("calculating");
            }
            out << ".dsi."<< (int)param_values[0] << ".fib.gz";
            if (!image_model->reconstruct<dsi_process>(out.str()))
                return "reconstruction canceled";
            break;
        case 1://DTI
            image_model->voxel.recon_report << " The diffusion tensor was calculated.";
            out << ".dti.fib.gz";
            image_model->voxel.max_fiber_number = 1;
            if (!image_model->reconstruct<dti_process>(out.str()))
                return "reconstruction canceled";
            break;

        case 2://QBI
            image_model->voxel.recon_report << " The diffusion data was reconstructed using q-ball imaging (Tuch, MRM 2004).";
            if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition)
            {
                if (!image_model->reconstruct<qbi_estimate_response_function>())
                    return "reconstruction calceled";
                begin_prog("calculating");
            }
            out << ".qbi."<< param_values[0] << "_" << param_values[1] << ".fib.gz";
            if (!image_model->reconstruct<qbi_process>(out.str()))
                return "reconstruction canceled";
            break;
        case 3://QBI
            image_model->voxel.recon_report << " The diffusion data was reconstructed using spherical-harmonic-based q-ball imaging (Descoteaux et al., MRM 2007).";
            if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition)
            {
                if (!image_model->reconstruct<qbi_sh_estimate_response_function>())
                    return "reconstruction calceled";
                begin_prog("calculating");
            }
            out << ".qbi.sh"<< (int) param_values[1] << "." << param_values[0] << ".fib.gz";
            if (!image_model->reconstruct<qbi_sh_process>(out.str()))
                return "reconstruction canceled";
            break;

        case 4://GQI
            if(param_values[0] == 0.0) // spectral analysis
            {
                image_model->voxel.recon_report <<
                " The diffusion data were reconstructed using generalized q-sampling imaging (Yeh et al., IEEE TMI, 2010).";
                out << (image_model->voxel.r2_weighted ? ".gqi2.spec.fib.gz":".gqi.spec.fib.gz");
                if (!image_model->reconstruct<gqi_spectral_process>(out.str()))
                    return "reconstruction canceled";
                break;
            }
            image_model->voxel.recon_report <<
            " The diffusion data were reconstructed using generalized q-sampling imaging (Yeh et al., IEEE TMI, 2010) with a diffusion sampling length ratio of " << (float)param_values[0] << ".";
            if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition)
            {
                if (!image_model->reconstruct<gqi_estimate_response_function>())
                    return "reconstruction calceled";
                begin_prog("calculating");
            }
            if(image_model->voxel.r2_weighted)
                image_model->voxel.recon_report << " The ODF calculation was weighted by the square of the diffuion displacement.";
            out << (image_model->voxel.r2_weighted ? ".gqi2.":".gqi.") << param_values[0] << ".fib.gz";
            if (!image_model->reconstruct<gqi_process>(out.str()))
                return "reconstruction canceled";
            break;
        case 6:
            image_model->voxel.recon_report
                    << " The diffusion data were converted to HARDI using generalized q-sampling method with a regularization parameter of " << param_values[2] << ".";
            out << ".hardi."<< param_values[0]
                << ".b" << param_values[1]
                << ".reg" << param_values[2] << ".src.gz";
            if (!image_model->reconstruct<hardi_convert_process>(out.str()))
                return "reconstruction canceled";
            break;
        case 7:
            image_model->voxel.recon_report
            << " The diffusion data were reconstructed using q-space diffeomorphic reconstruction (Yeh et al. Neuroimage, 2011) with a diffusion sampling length ratio of "
            << (float)param_values[0] << ". The output resolution was " << param_values[1] << " mm.";
            // run gqi to get the spin quantity
            if (!image_model->reconstruct<gqi_estimate_response_function>())
                return "reconstruction calceled";
            out << ".reg" << (int)image_model->voxel.reg_method;
            out << (image_model->voxel.r2_weighted ? ".qsdr2.":".qsdr.");
            out << param_values[0] << "." << param_values[1] << "mm";
            if(image_model->voxel.output_jacobian)
                out << ".jac";
            if(image_model->voxel.output_mapping)
                out << ".map";
            out << ".fib.gz";
            begin_prog("deforming");
            if (!image_model->reconstruct<gqi_mni_process>(out.str()))
                return "reconstruction canceled";
            break;
        }
        output_name = image_model->file_name + out.str();
    }
    catch (std::exception& e)
    {
        output_name = e.what();
        return output_name.c_str();
    }
    catch (...)
    {
        return "unknown exception";
    }
    return output_name.c_str();
}