bool load_cerebrum_mask(void) { if(!cerebrum_1mm.empty() && !cerebrum_2mm.empty()) return true; QString file1 = "/cerebrum1.nii.gz"; QString file2 = "/cerebrum2.nii.gz"; if(QFileInfo(QCoreApplication::applicationDirPath() + file1).exists()) file1 = QCoreApplication::applicationDirPath() + file1; else if(QFileInfo(QDir::currentPath() + file1).exists()) file1 = QDir::currentPath() + file1; else return false; if(QFileInfo(QCoreApplication::applicationDirPath() + file2).exists()) file2 = QCoreApplication::applicationDirPath() + file2; else if(QFileInfo(QDir::currentPath() + file2).exists()) file2 = QDir::currentPath() + file2; else return false; { gz_nifti n1; if(!n1.load_from_file(file1.toLocal8Bit().begin())) return false; n1.toLPS(cerebrum_1mm); } { gz_nifti n2; if(!n2.load_from_file(file2.toLocal8Bit().begin())) return false; n2.toLPS(cerebrum_2mm); } return true; }
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; }
void swap(DwiHeader& rhs) { image.swap(rhs.image); std::swap(bvec, rhs.bvec); std::swap(bvalue, rhs.bvalue); std::swap(te, rhs.te); }
void trim(void) { image::geometry<3> range_min,range_max; image::bounding_box(mask,range_min,range_max,0); for (unsigned int index = 0;check_prog(index,dwi_data.size());++index) { image::pointer_image<unsigned short,3> I = image::make_image(voxel.dim,(unsigned short*)dwi_data[index]); image::basic_image<unsigned short,3> I0 = I; image::crop(I0,range_min,range_max); std::fill(I.begin(),I.end(),0); std::copy(I0.begin(),I0.end(),I.begin()); } calculate_dwi_sum(); image::crop(mask,range_min,range_max); voxel.dim = mask.geometry(); }
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; }
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; }
unsigned int size(void) const { return image.size(); }
unsigned short* begin(void) { return &*image.begin(); }
const unsigned short* begin(void) const { return &*image.begin(); }