bool in_range(int x,int y,int z) const { return dim.is_valid(x,y,z); }
std::pair<float,float> evaluate_fib( const image::geometry<3>& dim, const std::vector<std::vector<float> >& fib_fa, const std::vector<std::vector<float> >& fib_dir) { unsigned char num_fib = fib_fa.size(); char dx[13] = {1,0,0,1,1,0, 1, 1, 0, 1,-1, 1, 1}; char dy[13] = {0,1,0,1,0,1,-1, 0, 1, 1, 1,-1, 1}; char dz[13] = {0,0,1,0,1,1, 0,-1,-1, 1, 1, 1,-1}; std::vector<image::vector<3> > dis(13); for(unsigned int i = 0;i < 13;++i) { dis[i] = image::vector<3>(dx[i],dy[i],dz[i]); dis[i].normalize(); } float otsu = *std::max_element(fib_fa[0].begin(),fib_fa[0].end())*0.1; std::vector<std::vector<unsigned char> > connected(fib_fa.size()); for(unsigned int index = 0;index < connected.size();++index) connected[index].resize(dim.size()); float connection_count = 0; for(image::pixel_index<3> index(dim);index < dim.size();++index) { if(fib_fa[0][index.index()] <= otsu) continue; unsigned int index3 = index.index()+index.index()+index.index(); for(unsigned char fib1 = 0;fib1 < num_fib;++fib1) { if(fib_fa[fib1][index.index()] <= otsu) break; for(unsigned int j = 0;j < 2;++j) for(unsigned int i = 0;i < 13;++i) { image::vector<3,int> pos; pos = j ? image::vector<3,int>(index[0] + dx[i],index[1] + dy[i],index[2] + dz[i]) :image::vector<3,int>(index[0] - dx[i],index[1] - dy[i],index[2] - dz[i]); if(!dim.is_valid(pos)) continue; image::pixel_index<3> other_index(pos[0],pos[1],pos[2],dim); unsigned int other_index3 = other_index.index()+other_index.index()+other_index.index(); if(std::abs(image::vector<3>(&fib_dir[fib1][index3])*dis[i]) <= 0.8665) continue; for(unsigned char fib2 = 0;fib2 < num_fib;++fib2) if(fib_fa[fib2][other_index.index()] > otsu && std::abs(image::vector<3>(&fib_dir[fib2][other_index3])*dis[i]) > 0.8665) { connected[fib1][index.index()] = 1; connected[fib2][other_index.index()] = 1; connection_count += fib_fa[fib2][other_index.index()]; } } } } float no_connection_count = 0; for(image::pixel_index<3> index(dim);index < dim.size();++index) { for(unsigned int i = 0;i < num_fib;++i) if(fib_fa[i][index.index()] > otsu && !connected[i][index.index()]) { no_connection_count += fib_fa[i][index.index()]; } } return std::make_pair(connection_count,no_connection_count); }
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; }