예제 #1
0
    bool load_from_file(const char* dwi_file_name)
    {
        file_name = dwi_file_name;
        if (!mat_reader.load_from_file(dwi_file_name))
        {
            error_msg = "Cannot open file";
            return false;
        }
        unsigned int row,col;

        const unsigned short* dim_ptr = 0;
        if (!mat_reader.read("dimension",row,col,dim_ptr))
        {
            error_msg = "Cannot find dimension matrix";
            return false;
        }
        const float* voxel_size = 0;
        if (!mat_reader.read("voxel_size",row,col,voxel_size))
        {
            //error_msg = "Cannot find voxel size matrix";
            //return false;
            std::fill(voxel.vs.begin(),voxel.vs.end(),3.0);
        }
        else
            std::copy(voxel_size,voxel_size+3,voxel.vs.begin());

        if (dim_ptr[0]*dim_ptr[1]*dim_ptr[2] <= 0)
        {
            error_msg = "Invalid dimension setting";
            return false;
        }
        voxel.dim[0] = dim_ptr[0];
        voxel.dim[1] = dim_ptr[1];
        voxel.dim[2] = dim_ptr[2];

        const float* table;
        if (!mat_reader.read("b_table",row,col,table))
        {
            error_msg = "Cannot find b_table matrix";
            return false;
        }
        voxel.bvalues.resize(col);
        voxel.bvectors.resize(col);
        for (unsigned int index = 0;index < col;++index)
        {
            voxel.bvalues[index] = table[0];
            voxel.bvectors[index][0] = table[1];
            voxel.bvectors[index][1] = table[2];
            voxel.bvectors[index][2] = table[3];
            voxel.bvectors[index].normalize();
            table += 4;
        }

        const char* report_buf = 0;
        if(mat_reader.read("report",row,col,report_buf))
            voxel.report = std::string(report_buf,report_buf+row*col);
        else
            get_report(voxel.bvalues,voxel.vs,voxel.report);

        dwi_data.resize(voxel.bvalues.size());
        for (unsigned int index = 0;index < voxel.bvalues.size();++index)
        {
            std::ostringstream out;
            out << "image" << index;
            mat_reader.read(out.str().c_str(),row,col,dwi_data[index]);
            if (!dwi_data[index])
            {
                error_msg = "Cannot find image matrix";
                return false;
            }
        }


        {
            // this grad_dev matrix is rotated
            const float* grad_dev = 0;
            if(mat_reader.read("grad_dev",row,col,grad_dev) && row*col == voxel.dim.size()*9)
            {
                for(unsigned int index = 0;index < 9;index++)
                    voxel.grad_dev.push_back(image::make_image(voxel.dim,grad_dev+index*voxel.dim.size()));
            }
        }

        // create mask;
        calculate_dwi_sum();

        const unsigned char* mask_ptr = 0;
        if(mat_reader.read("mask",row,col,mask_ptr))
        {
            mask.resize(voxel.dim);
            if(row*col == voxel.dim.size())
                std::copy(mask_ptr,mask_ptr+row*col,mask.begin());
        }
        else
            calculate_mask();

        return true;
    }
예제 #2
0
 unsigned short* begin(void)
 {
     return &*image.begin();
 }
예제 #3
0
    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;

    }
예제 #4
0
 const unsigned short* begin(void) const
 {
     return &*image.begin();
 }