15 #include "gdcmImageReader.h"
18 inline string ToLower(
string s){
20 for(
int i=0; i<s.size(); i++){
21 result[i]=tolower(s[i]);
28 inline Grid3<T>::Grid3(
int width,
int height,
int depth,
double x_spacing,
double y_spacing,
double z_spacing){
35 data=std::vector<T>(NumberOfElements());
46 data=std::vector<T>(NumberOfElements());
50 inline void Grid3<T>::Init(
int width,
int height,
int depth,
double x_spacing,
double y_spacing,
double z_spacing) {
57 data=std::vector<T>(NumberOfElements());
78 result.x = p.x / GetSpacingX();
79 result.y = p.y / GetSpacingY();
80 result.z = p.z / GetSpacingZ();
88 result.x = p.x * GetSpacingX();
89 result.y = p.y * GetSpacingY();
90 result.z = p.z * GetSpacingZ();
96 return _width*_height*_depth;
136 return std::string(
typeid(T).name() );
142 return x+ y*_width + z*_width*_height;
148 c.z = index/(_width*_height);
149 index = index%(_width*_height);
157 return (x>=0 && x<_width && y>=0 && y<_height && z>=0 && z<_depth);
162 return IsInside(p.x,p.y,p.z);
180 return data[Offset(x,y,z)];
187 p.x=min(p.x,_width-1);
189 p.y=min(p.y,_height-1);
191 p.z=min(p.z,_depth-1);
193 return data[Offset(p.x,p.y,p.z)];
198 double xt=x-floor(x);
199 double yt=y-floor(y);
200 double zt=z-floor(z);
202 int x1=int(floor(x));
204 int y1=int(floor(y));
206 int z1=int(floor(z));
209 return (1-zt)*((1-yt)*((1-xt)*operator()(x1,y1,z1,
true)+
210 (xt)*
operator()(x2,y1,z1,
true))+
211 (yt)*((1-xt)*operator()(x1,y2,z1,
true)+
212 (xt)*
operator()(x2,y2,z1,
true)))+
213 (zt)*((1-yt)*((1-xt)*operator()(x1,y1,z2,
true)+
214 (xt)*
operator()(x2,y1,z2,
true))+
215 (yt)*((1-xt)*operator()(x1,y2,z2,
true)+
216 (xt)*
operator()(x2,y2,z2,
true)));
221 return LinearAt(p.x,p.y,p.z);
228 Vec3i coord=Coordinate(index);
229 if(coord.x+1<_width){
230 n.push_back(Offset(coord.x+1, coord.y, coord.z));
234 n.push_back(Offset(coord.x-1, coord.y, coord.z));
237 if(coord.y+1<_height){
238 n.push_back(Offset(coord.x, coord.y+1, coord.z));
242 n.push_back(Offset(coord.x, coord.y-1, coord.z));
245 if(coord.z+1<_depth){
246 n.push_back(Offset(coord.x, coord.y, coord.z+1));
250 n.push_back(Offset(coord.x, coord.y, coord.z-1));
260 n.push_back(
Vec3i(p.x+1, p.y, p.z));
264 n.push_back(
Vec3i(p.x-1, p.y, p.z));
268 n.push_back(
Vec3i(p.x, p.y+1, p.z));
272 n.push_back(
Vec3i(p.x, p.y-1, p.z));
276 n.push_back(
Vec3i(p.x, p.y, p.z+1));
280 n.push_back(
Vec3i(p.x, p.y, p.z-1));
286 std::fill(data.begin(),data.end(),value);
291 return *std::max_element(data.begin(), data.end());
296 return *std::min_element(data.begin(), data.end());
345 std::copy(src.data.begin(), src.data.end(), data.begin());
352 std::swap_ranges(v.data.begin(), v.data.end(), data.begin());
358 if(filename.find(
".vtk")!=std::string::npos){
359 return ReadVTK(filename);
361 else if(filename.find(
".mhd")!=string::npos){
362 return ReadMetaImage(filename);
364 else if(filename.find(
".mha")!=string::npos){
365 return ReadMetaImage(filename);
367 else if(filename.find(
".nii")!=string::npos){
368 return ReadNIFTI(filename);
370 else if(filename.find(
".dcm")!=string::npos){
371 return ReadDICOM(filename);
395 is.open( filename.c_str(), ios::in | ios::binary );
402 std::stringstream ss;
409 std::string checkvtk;
412 if( !(ToLower(checkvtk) ==
"vtk" )){
return false; }
417 bool read_dimensions=
false;
419 bool read_type=
false;
420 bool read_asciibinary=
false;
426 double spacing_x=1,spacing_y=1,spacing_z=1;
427 double origin_x=0,origin_y=0,origin_z=0;
429 while(!done && getline(is,line)){
431 std::stringstream ss2(line);
434 if(ToLower(keyword)==
"dimensions"){
439 read_dimensions=
true;
441 else if(ToLower(keyword)==
"binary"){
442 read_asciibinary=
true;
444 else if(ToLower(keyword)==
"ascii"){
446 read_asciibinary=
true;
448 else if(ToLower(keyword)==
"dataset"){
450 if(!(ToLower(dataset_type)==
"structured_points")){
454 else if(ToLower(keyword)==
"spacing" ||ToLower(keyword)==
"aspect_ratio" ){
459 else if(ToLower(keyword)==
"origin"){
464 else if(ToLower(keyword)==
"scalars"){
469 else if(ToLower(keyword)==
"lookup_table"){
473 done=read_dimensions && read_lut && read_type && read_asciibinary;
480 cout<<read_lut<<endl;
481 cout<<read_type<<endl;
482 cout<<read_asciibinary<<endl;
491 if(typestring==
"unsigned_char"){
492 uint8_t* tmpdata=
new uint8_t[nelem];
493 is.read((
char*)tmpdata, nelem*
sizeof(uint8_t));
494 #pragma omp parallel for
495 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
497 metadata.SetString(
"ORIGINAL_TYPE",
"UINT8");
500 else if(typestring==
"unsigned_short"){
501 uint16_t* tmpdata=
new uint16_t[nelem];
502 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(uint16_t), is);
503 #pragma omp parallel for
504 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
506 metadata.SetString(
"ORIGINAL_TYPE",
"UINT16");
509 else if(typestring==
"unsigned_int"){
510 uint32_t* tmpdata=
new uint32_t[nelem];
511 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(uint32_t), is);
512 #pragma omp parallel for
513 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
515 metadata.SetString(
"ORIGINAL_TYPE",
"UINT32");
518 else if(typestring==
"char"){
519 int8_t* tmpdata=
new int8_t[nelem];
520 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(int8_t), is);
521 #pragma omp parallel for
522 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
524 metadata.SetString(
"ORIGINAL_TYPE",
"INT8");
527 else if(typestring==
"short"){
528 int16_t* tmpdata=
new int16_t[nelem];
529 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(int16_t), is);
530 #pragma omp parallel for
531 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
533 metadata.SetString(
"ORIGINAL_TYPE",
"INT16");
536 else if(typestring==
"int"){
537 int32_t* tmpdata=
new int32_t[nelem];
538 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(int32_t), is);
539 #pragma omp parallel for
540 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
542 metadata.SetString(
"ORIGINAL_TYPE",
"INT32");
545 else if(typestring==
"float"){
546 float* tmpdata=
new float[nelem];
547 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(
float), is);
548 #pragma omp parallel for
549 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
551 metadata.SetString(
"ORIGINAL_TYPE",
"FLOAT");
554 else if(typestring==
"double"){
555 double* tmpdata=
new double[nelem];
556 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(
double), is);
557 #pragma omp parallel for
558 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
560 metadata.SetString(
"ORIGINAL_TYPE",
"DOUBLE");
585 outfile.open(filename,ofstream::out|ofstream::binary);
586 if(!outfile) {
return false; }
588 long nelem= _width*_height*_depth;
590 outfile<<
"# vtk DataFile Version 3.0"<<endl;
591 outfile<<
"Created using the Grid3 library"<<endl;
593 string Datamode=
"BINARY";
595 outfile<<Datamode<<endl;
597 outfile<<
"DATASET STRUCTURED_POINTS"<<endl;
599 outfile<<
"DIMENSIONS "<<_width<<
" "<<_height<<
" "<<_depth<<endl;
600 outfile<<
"ORIGIN 0.0 0.0 0.0"<<endl;
601 outfile<<
"SPACING "<<_spacingX<<
" "<<_spacingY<<
" "<<_spacingZ<<endl;
602 outfile<<
"POINT_DATA "<<nelem<<endl;
604 string datatype=GetDataType();
605 string vtk_datatype=
"";
607 if(datatype==
"UINT8"){vtk_datatype=
"unsigned_char";}
608 else if(datatype==
"INT8"){vtk_datatype=
"char";}
609 else if(datatype==
"UINT16"){vtk_datatype=
"unsigned_short";}
610 else if(datatype==
"INT16"){vtk_datatype=
"short";}
611 else if(datatype==
"UINT32"){vtk_datatype=
"unsigned_int";}
612 else if(datatype==
"INT32"){vtk_datatype=
"int";}
613 else if(datatype==
"float"){vtk_datatype=
"float";}
614 else if(datatype==
"double"){vtk_datatype=
"double";}
616 outfile<<
"SCALARS image_data "<<vtk_datatype<<endl;
617 outfile<<
"LOOKUP_TABLE default"<<endl;
623 WriteToBigEndian(reinterpret_cast<char*>(data), nelem,
sizeof(T), outfile);
645 map<string,string> header_info;
649 if(!f){
return false;}
651 string line,key, value;
656 size_t pos=line.find(
"=");
657 if(pos!=string::npos){
659 key=line.substr(0,pos);
660 value=line.substr(pos);
663 size_t first_non_space=key.find_first_not_of(
" ");
664 size_t last_non_space=key.find_last_not_of(
" ");
665 key=key.substr(first_non_space,last_non_space+1);
668 first_non_space=value.find_first_not_of(
" ");
669 last_non_space=value.find_last_not_of(
" ");
670 value=value.substr(first_non_space,last_non_space+1);
672 header_info[key]=value;
678 map<string,string>::iterator it;
682 it=header_info.find(
"ObjectType");
683 if(it==header_info.end() || it->second!=
"Image"){
return false;}
686 it=header_info.find(
"NDims");
687 if(it==header_info.end()){
return false;}
689 ss=stringstream(it->second);
691 if(!(ndims==2 || ndims==3)){
return false;}
695 it=header_info.find(
"DimSize");
696 if(it==header_info.end()){
return false;}
697 ss=stringstream(it->second);
698 int dimx, dimy, dimz;
703 if(ndims==3){ss>>dimz;}
707 it=header_info.find(
"ElementDataFile");
708 if(it==header_info.end()){
return false;}
709 string datafile=it->second;
712 it=header_info.find(
"ElementType");
713 if(it==header_info.end()){
return false;}
714 string typestring=it->second;
717 bool BinaryData=
true;
718 it=header_info.find(
"BinaryData");
719 if(it!=header_info.end()){
720 BinaryData=(it->second==
"True");
724 bool BinaryDataByteOrderMSB=IsBigEndian();
725 it=header_info.find(
"BinaryDataByteOrderMSB");
726 if(it!=header_info.end()){
727 BinaryDataByteOrderMSB=(it->second==
"True");
732 it=header_info.find(
"HeaderSize");
733 if(it!=header_info.end()){
734 ss=stringstream(it->second);
739 it=header_info.find(
"ElementSize");
740 double voxelsize_x=1, voxelsize_y=1, voxelsize_z=1;
741 if(it!=header_info.end()){
742 ss=stringstream(it->second);
743 ss>>voxelsize_x>>voxelsize_y;
744 if(ndims==3){ ss>>voxelsize_z;}
748 it=header_info.find(
"ElementSpacing");
749 _spacingX=voxelsize_x;
750 _spacingY=voxelsize_y;
751 _spacingZ=voxelsize_z;
752 if(it!=header_info.end()){
753 ss=stringstream(it->second);
754 ss>>_spacingX>>_spacingY;
755 if(ndims==3){ ss>>_spacingZ;}
759 long nelem=dimx*dimy*dimz;
760 Init(dimx,dimy,dimz,_spacingX,_spacingY,_spacingZ);
799 string Datafile_fullpath=
"";
801 size_t found=filename.find_last_of(
"/\\");
802 if(found!=string::npos){
803 Datafile_fullpath.append(filename.substr(0,found+1));
806 Datafile_fullpath.append(datafile);
810 f.open(Datafile_fullpath,ios::binary | ios::ate);
815 int fileSize=f.tellg();
818 f.open(Datafile_fullpath,ios::in|ios::binary);
821 cout << Datafile_fullpath << endl;
825 if(typestring==
"MET_UCHAR"){
826 uint8_t* tmpdata=
new uint8_t[nelem];
827 if(BinaryDataByteOrderMSB){
828 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(uint8_t), f);
831 ReadFromLittleEndian((
char*)tmpdata, nelem,
sizeof(uint8_t), f);
834 #pragma omp parallel for
835 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
837 metadata.SetString(
"ORIGINAL_TYPE",
"UINT8");
842 else if(typestring==
"MET_CHAR"){
843 int8_t* tmpdata=
new int8_t[nelem];
844 if(BinaryDataByteOrderMSB){
845 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(int8_t), f);
848 ReadFromLittleEndian((
char*)tmpdata, nelem,
sizeof(int8_t), f);
851 #pragma omp parallel for
852 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
854 metadata.SetString(
"ORIGINAL_TYPE",
"INT8");
858 else if(typestring==
"MET_USHORT"){
859 uint16_t* tmpdata=
new uint16_t[nelem];
860 if(BinaryDataByteOrderMSB){
861 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(uint16_t), f);
864 ReadFromLittleEndian((
char*)tmpdata, nelem,
sizeof(uint16_t), f);
867 #pragma omp parallel for
868 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
870 metadata.SetString(
"ORIGINAL_TYPE",
"UINT16");
874 else if(typestring==
"MET_SHORT"){
875 int16_t* tmpdata=
new int16_t[nelem];
876 if(BinaryDataByteOrderMSB){
877 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(int16_t), f);
880 ReadFromLittleEndian((
char*)tmpdata, nelem,
sizeof(int16_t), f);
883 #pragma omp parallel for
884 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
886 metadata.SetString(
"ORIGINAL_TYPE",
"INT16");
889 else if(typestring==
"MET_UINT"){
890 uint32_t* tmpdata=
new uint32_t[nelem];
891 if(BinaryDataByteOrderMSB){
892 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(uint32_t), f);
895 ReadFromLittleEndian((
char*)tmpdata, nelem,
sizeof(uint32_t), f);
898 #pragma omp parallel for
899 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
901 metadata.SetString(
"ORIGINAL_TYPE",
"UINT32");
905 else if(typestring==
"MET_INT"){
906 int32_t* tmpdata=
new int32_t[nelem];
907 if(BinaryDataByteOrderMSB){
908 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(int32_t), f);
911 ReadFromLittleEndian((
char*)tmpdata, nelem,
sizeof(int32_t), f);
914 #pragma omp parallel for
915 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
917 metadata.SetString(
"ORIGINAL_TYPE",
"INT32");
921 else if(typestring==
"MET_FLOAT"){
922 float* tmpdata=
new float[nelem];
923 if(BinaryDataByteOrderMSB){
924 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(
float), f);
927 ReadFromLittleEndian((
char*)tmpdata, nelem,
sizeof(
float), f);
930 #pragma omp parallel for
931 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
933 metadata.SetString(
"ORIGINAL_TYPE",
"FLOAT");
936 else if(typestring==
"MET_DOUBLE"){
937 double* tmpdata=
new double[nelem];
938 if(BinaryDataByteOrderMSB){
939 ReadFromBigEndian((
char*)tmpdata, nelem,
sizeof(
double), f);
942 ReadFromLittleEndian((
char*)tmpdata, nelem,
sizeof(
double), f);
945 #pragma omp parallel for
946 for(
long i=0; i<nelem; i++){ data[i]=T(tmpdata[i]); }
948 metadata.SetString(
"ORIGINAL_TYPE",
"DOUBLE");
958 it=header_info.find(
"Comment");
959 if(it!=header_info.end()){
960 metadata.SetString(it->first,it->second);
964 it=header_info.find(
"Name");
965 if(it!=header_info.end()){
966 metadata.SetString(it->first,it->second);
970 it=header_info.find(
"ID");
971 if(it!=header_info.end()){
972 metadata.SetString(it->first,it->second);
976 it=header_info.find(
"Position");
977 if(it!=header_info.end()){
978 metadata.SetString(it->first,it->second);
982 it=header_info.find(
"Orientation");
983 if(it!=header_info.end()){
984 metadata.SetString(it->first,it->second);
988 it=header_info.find(
"AnatomicalOrientation");
989 if(it!=header_info.end()){
990 metadata.SetString(it->first,it->second);
994 it=header_info.find(
"Modality");
995 if(it!=header_info.end()){
996 metadata.SetString(it->first,it->second);
1010 f.SetExtension(
"mhd");
1011 string headerfile_name=f.GetAsString();
1013 f.SetExtension(
"raw");
1014 string datafile=f.GetAsString();
1017 string relative_datafile=f.GetAsString();
1020 string datatype=GetDataType();
1021 string metaimage_datatype=
"";
1022 if(datatype==
"UINT8"){metaimage_datatype=
"MET_UCHAR";}
1023 else if(datatype==
"UINT16"){metaimage_datatype=
"MET_USHORT";}
1024 else if(datatype==
"UINT32"){metaimage_datatype=
"MET_UINT";}
1025 else if(datatype==
"INT8"){metaimage_datatype=
"MET_CHAR";}
1026 else if(datatype==
"INT16"){metaimage_datatype=
"MET_SHORT";}
1027 else if(datatype==
"INT32"){metaimage_datatype=
"MET_INT";}
1030 outfile.open(headerfile_name,ofstream::out|ofstream::binary);
1031 if(!outfile) {
return false; }
1033 outfile<<
"ObjectType = Image"<<endl;
1036 if( GetDepth()==1){ ndims=2; }
1037 outfile<<
"NDims = "<<ndims<<endl;
1039 outfile<<
"DimSize = "<<GetWidth()<<
" "<<GetHeight();
1040 if(ndims==3){outfile<<
" "<<GetDepth();}
1043 outfile<<
"HeaderSize = 0"<<endl;
1044 outfile<<
"ElementSize = 1 1 1"<<endl;
1045 outfile<<
"ElementSpacing = "<<GetSpacingX()<<
" "<<GetSpacingY()<<
" "<<GetSpacingZ()<<
" "<<endl;
1047 outfile<<
"ElementType = "<<metaimage_datatype<<endl;
1050 outfile<<
"ElementByteOrderMSB = True"<<endl;
1053 outfile<<
"ElementByteOrderMSB = False"<<endl;
1056 outfile<<
"ElementDataFile = "<<relative_datafile<<endl;
1060 long nelem= _width*_height*_depth;
1063 outfile.open(datafile,ofstream::out|ofstream::binary);
1064 outfile.write((
char*)data, nelem*
sizeof(T));
1080 f.open( filename.c_str(), std::ios::in | std::ios::binary );
1081 if( !f ) {
return false; }
1084 int32_t sizeof_hdr=0;
1085 f.read((
char*)&sizeof_hdr,4);
1086 if(sizeof_hdr!=348){
1096 f.read((
char*)&dim[0],16);
1098 if(!(dim[0]>0 && dim[0]<5)){
1105 if(dim[0]>=2){ dimy=dim[2]; }
1107 if(dim[0]>=3){ dimz=dim[3]; }
1109 if(dim[0]>=4){ nchannels=dim[4]; }
1114 f.read((
char*)&datatype,2);
1123 f.read((
char*)&pixdim[0],32);
1124 _spacingX=pixdim[1];
1125 _spacingY=pixdim[2];
1126 _spacingZ=pixdim[3];
1130 f.read((
char*)&vox_offset,4);
1133 f.seekg(std::streamoff(vox_offset));
1135 long nelem=dimx*dimy*dimz;
1136 Init(dimx,dimy,dimz);
1147 {uint8_t* tmpdata=
new uint8_t[nelem];
1148 metadata.SetString(
"ORIGINAL_TYPE",
"UINT8");
1149 f.read((
char*)tmpdata, nelem*
sizeof(uint8_t));
1150 #pragma omp parallel for
1151 for(
long i=0; i<nelem; i++){
1152 data[i]=T(tmpdata[i]);
1158 {int16_t* tmpdata=
new int16_t[nelem];
1159 metadata.SetString(
"ORIGINAL_TYPE",
"INT16");
1160 f.read((
char*)tmpdata, nelem*
sizeof(int16_t));
1161 #pragma omp parallel for
1162 for(
long i=0; i<nelem; i++){
1163 data[i]=T(tmpdata[i]);
1169 {int32_t* tmpdata=
new int32_t[nelem];
1170 metadata.SetString(
"ORIGINAL_TYPE",
"INT32");
1171 f.read((
char*)tmpdata, nelem*
sizeof(int32_t));
1172 #pragma omp parallel for
1173 for(
long i=0; i<nelem; i++){
1174 data[i]=T(tmpdata[i]);
1180 {
float* tmpdata=
new float[nelem];
1181 metadata.SetString(
"ORIGINAL_TYPE",
"FLOAT");
1182 f.read((
char*)tmpdata, nelem*
sizeof(
float));
1183 #pragma omp parallel for
1184 for(
long i=0; i<nelem; i++){
1185 data[i]=T(tmpdata[i]);
1195 {
double* tmpdata=
new double[nelem];
1196 metadata.SetString(
"ORIGINAL_TYPE",
"DOUBLE");
1197 f.read((
char*)tmpdata, nelem*
sizeof(
double));
1198 #pragma omp parallel for
1199 for(
long i=0; i<nelem; i++){
1200 data[i]=T(tmpdata[i]);
1206 {int8_t* tmpdata=
new int8_t[nelem];
1207 metadata.SetString(
"ORIGINAL_TYPE",
"INT8");
1208 f.read((
char*)tmpdata, nelem*
sizeof(int8_t));
1209 #pragma omp parallel for
1210 for(
long i=0; i<nelem; i++){
1211 data[i]=T(tmpdata[i]);
1217 {uint16_t* tmpdata=
new uint16_t[nelem];
1218 metadata.SetString(
"ORIGINAL_TYPE",
"UINT16");
1219 f.read((
char*)tmpdata, nelem*
sizeof(uint16_t));
1220 #pragma omp parallel for
1221 for(
long i=0; i<nelem; i++){
1222 data[i]=T(tmpdata[i]);
1228 {uint32_t* tmpdata=
new uint32_t[nelem];
1229 metadata.SetString(
"ORIGINAL_TYPE",
"UINT32");
1230 f.read((
char*)tmpdata, nelem*
sizeof(uint32_t));
1231 #pragma omp parallel for
1232 for(
long i=0; i<nelem; i++){
1233 data[i]=T(tmpdata[i]);
1251 outfile.open(filename);
1252 if( !outfile ) {
return false; }
1255 int32_t sizeof_hdr=348;
1256 outfile.write((
char*)&sizeof_hdr,4);
1270 outfile.write((
char*)&dim[0],16);
1275 string datatype_name=GetDataType();
1277 if(datatype_name==
"UINT8"){datatype=2;}
1278 else if(datatype_name==
"INT8"){datatype=256;}
1279 else if(datatype_name==
"UINT16"){datatype=512;}
1280 else if(datatype_name==
"INT16"){datatype=4;}
1281 else if(datatype_name==
"UINT32"){datatype=768;}
1282 else if(datatype_name==
"INT32"){datatype=8;}
1283 else if(datatype_name==
"float"){datatype=16;}
1284 else if(datatype_name==
"double"){datatype=64;}
1287 outfile.write((
char*)&datatype,2);
1293 pixdim[1]=_spacingX;
1294 pixdim[2]=_spacingY;
1295 pixdim[3]=_spacingZ;
1296 outfile.write((
char*)&pixdim[0],32);
1299 float vox_offset=352;
1301 outfile.write((
char*)&vox_offset,4);
1304 char magic[4]={
'n',
'+',
'1',
'\0'};
1306 outfile.write((
char*)&magic[0],4);
1311 outfile.write((
char*)data,
sizeof(T)*NumberOfElements());
1320 #ifdef grid3_use_gdcm
1322 gdcm::ImageReader ir;
1323 ir.SetFileName(filename.c_str());
1324 if(!ir.Read()){
return false; }
1326 const gdcm::Image &image = ir.GetImage();
1328 const unsigned int* dim = image.GetDimensions();
1329 Init(dim[0], dim[1], dim[2], image.GetSpacing(0), image.GetSpacing(1), image.GetSpacing(2));
1331 gdcm::PixelFormat pf= image.GetPixelFormat();
1332 if(pf.GetSamplesPerPixel()!=1){
return false;}
1334 long nelem=NumberOfElements();
1335 string type= string(pf.GetScalarTypeAsString());
1354 uint8_t* tmpdata=
new uint8_t[nelem];
1355 metadata.SetString(
"ORIGINAL_TYPE",
"UINT8");
1356 if( !image.GetBuffer( (
char*)tmpdata) ){
1360 #pragma omp parallel for
1361 for(
long i=0; i<nelem; i++){
1362 data[i]=T(tmpdata[i]);
1366 else if(type==
"UINT16"){
1367 uint16_t* tmpdata =
new uint16_t[nelem];
1368 metadata.SetString(
"ORIGINAL_TYPE",
"UINT16");
1369 if (!image.GetBuffer((
char*)tmpdata)){
1373 #pragma omp parallel for
1374 for (
long i = 0; i<nelem; i++){
1375 data[i] = T(tmpdata[i]);
1380 else if (type ==
"UINT32"){
1381 uint32_t* tmpdata =
new uint32_t[nelem];
1382 metadata.SetString(
"ORIGINAL_TYPE",
"UINT32");
1383 if (!image.GetBuffer((
char*)tmpdata)){
1387 #pragma omp parallel for
1388 for (
long i = 0; i<nelem; i++){
1389 data[i] = T(tmpdata[i]);
1393 else if (type ==
"INT8"){
1394 int8_t* tmpdata =
new int8_t[nelem];
1395 metadata.SetString(
"ORIGINAL_TYPE",
"INT8");
1396 if (!image.GetBuffer((
char*)tmpdata)){
1400 #pragma omp parallel for
1401 for (
long i = 0; i<nelem; i++){
1402 data[i] = T(tmpdata[i]);
1407 else if (type ==
"INT16"){
1408 int16_t* tmpdata =
new int16_t[nelem];
1409 metadata.SetString(
"ORIGINAL_TYPE",
"INT16");
1410 if (!image.GetBuffer((
char*)tmpdata)){
1414 #pragma omp parallel for
1415 for (
long i = 0; i<nelem; i++){
1416 data[i] = T(tmpdata[i]);
1420 else if (type ==
"INT32"){
1421 metadata.SetString(
"ORIGINAL_TYPE",
"INT32");
1422 int32_t* tmpdata =
new int32_t[nelem];
1423 if (!image.GetBuffer((
char*)tmpdata)){
1427 #pragma omp parallel for
1428 for (
long i = 0; i<nelem; i++){
1429 data[i] = T(tmpdata[i]);
1433 else if (type ==
"FLOAT16"){
1436 else if (type ==
"FLOAT32"){
1438 if (CHAR_BIT*
sizeof(
float) != 32){
1441 float* tmpdata =
new float[nelem];
1442 metadata.SetString(
"ORIGINAL_TYPE",
"FLOAT");
1443 if (!image.GetBuffer((
char*)tmpdata)){
1447 #pragma omp parallel for
1448 for (
long i = 0; i<nelem; i++){
1449 data[i] = T(tmpdata[i]);
1453 else if (type ==
"FLOAT64"){
1455 if (CHAR_BIT*
sizeof(
double) != 64){
1458 double* tmpdata =
new double[nelem];
1459 metadata.SetString(
"ORIGINAL_TYPE",
"DOUBLE");
1460 if (!image.GetBuffer((
char*)tmpdata)){
1464 #pragma omp parallel for
1465 for (
long i = 0; i<nelem; i++){
1466 data[i] = T(tmpdata[i]);
bool WriteVTK(std::string filename)
Save grid in VTK legacy format.
Definition: Grid3_i.h:571
int NumberOfElements()
Return the total number of grid points.
Definition: Grid3_i.h:95
Class representing 3D vectors, with elements of type T.
Definition: Vector3.h:9
T * Data()
Returns a pointer to the beginning of the internal data array. The called object owns the pointer...
Definition: Grid3_i.h:100
bool ReadVTK(std::string filename)
Construct grid from an image file in VTK legacy format.
Definition: Grid3_i.h:377
void Fill(T value)
Set all points in the grid to a specified value.
Definition: Grid3_i.h:285
std::string GetDataType()
Return a string representation of the voxel type.
Definition: Grid3_i.h:135
Grid3()
Default constructor.
Definition: Grid3.h:63
Definition: FileName.h:26
T & operator[](long index)
Access to the grid value at a specified index. The passed index is assumed to be within the grid boun...
Definition: Grid3_i.h:166
T GetMaxValue()
Return the maximum value in the grid.
Definition: Grid3_i.h:290
Vec3d GridToWorld(Vec3d p)
Transform point p from grid coordinates to world coordinates.
Definition: Grid3_i.h:86
T LinearAt(double x, double y, double z)
Get the grid value at a specified coordinate using trilinear interpolation.
Definition: Grid3_i.h:197
void Get6Neighbors(long index, vector< long > &n)
Fill the vector n with the indices of the 6-neighbors of the gridpoint at the specified index...
Definition: Grid3_i.h:225
void SetSpacing(double x_spacing, double y_spacing, double z_spacing)
Set spacing.
Definition: Grid3_i.h:62
void Init(int width, int height, int depth=1, double x_spacing=1.0, double y_spacing=1.0, double z_spacing=1.0)
Initialize the grid with given dimensions. Any previous data in the grid will be overwritten.
Definition: Grid3_i.h:50
void CopyDataFrom(Grid3< T > &src)
Replace the current grid data with that of another grid. If the two grids do not have the same Number...
Definition: Grid3_i.h:343
Class representing a 3D image grid, each voxel being of type T.
Definition: Grid3.h:53
bool ReadMetaImage(std::string filename)
Construct grid from an image file in MetaImage format.
Definition: Grid3_i.h:641
Vec3d WorldToGrid(Vec3d p)
Transform point p from world coordinates to grid coordinates.
Definition: Grid3_i.h:76
void SwapContentsWith(Grid3< T > &v)
Swap the contents of two grids. If the two grids do not have the same NumberOfElements(), nothing happens.
Definition: Grid3_i.h:350
int Offset(int x, int y, int z)
Returns the index of a specified coordinate in the internal data array.
Definition: Grid3_i.h:141
bool WriteMetaImage(std::string filename)
Save grid in MetaImage format.
Definition: Grid3_i.h:1004
bool WriteNIFTI(std::string filename)
Save grid in NIFTI format.
Definition: Grid3_i.h:1248
T GetMinValue()
Return the minimum value in the grid.
Definition: Grid3_i.h:295
bool IsInside(int x, int y, int z)
Test if the given grid point is within the bounds of the grid.
Definition: Grid3_i.h:156
bool CreateFromFile(std::string filename)
Construct grid from an image file.
Definition: Grid3_i.h:357
Vec3i Coordinate(long index)
Returns the coordinate corresponding to a specified index in the internal data array.
Definition: Grid3_i.h:146
bool ReadDICOM(std::string filename)
Construct grid from an image file in DICOM format.
Definition: Grid3_i.h:1319
T & operator()(int x, int y, int z=0, bool Safe=false)
Access to the grid value at a specified coordinate. If "Safe" is false, the passed coordinate is assu...
Definition: Grid3_i.h:171
bool ReadNIFTI(std::string filename)
Construct grid from an image file in NIFTI format.
Definition: Grid3_i.h:1072