00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00021 #ifndef _FileConversion_hpp
00022 #define _FileConversion_hpp
00023 #include<ImLib3D/ImageProcessor.hpp>
00024 #include<ImLib3D/FFT.hpp>
00025 #include<ImLib3D/ConvenienceProcessors.hpp>
00026
00027 #include<avwio/avwio.h>
00028
00029 namespace FileConversion
00030 {
00031 inline string AVWImLib3DImageType(string fname)
00032 {
00033 string typeName;
00034 AVW *avw=AvwOpen( fname.c_str(), "r" );
00035 if(!avw){ThrowError("CReadFromFileAVW:: open failed for \"%s\"",fname);}
00036 short dataType;
00037 AvwGetDataType ( avw, &dataType );
00038 if(dataType==DT_UNSIGNED_CHAR ){typeName=TypeName<Mask3D>();}
00039 if(dataType==DT_SIGNED_SHORT ){typeName=TypeName<Image3Dlinear<short int> >();}
00040 if(dataType==DT_SIGNED_INT ){typeName=TypeName<LabelImage3D>();}
00041 if(dataType==DT_FLOAT ){typeName=TypeName<Image3Df>();}
00042 if(dataType==DT_COMPLEX ){typeName=TypeName<Image3Dcomplexd>();}
00043 if(dataType==DT_DOUBLE ){typeName=TypeName<Image3Dd>();}
00044 AvwClose ( avw );
00045 return typeName;
00046 }
00047
00048 template <class TTT>
00049 inline short AVWType (){return DT_UNKNOWN ;}
00050 template<> inline short AVWType<byte >(){return DT_UNSIGNED_CHAR ;}
00051 template<> inline short AVWType<short >(){return DT_SIGNED_SHORT ;}
00052 template<> inline short AVWType<int >(){return DT_SIGNED_INT ;}
00053 template<> inline short AVWType<float >(){return DT_FLOAT ;}
00054 template<> inline short AVWType<complex<double> >(){return DT_COMPLEX ;}
00055 template<> inline short AVWType<double >(){return DT_DOUBLE ;}
00056 template <class TTT>
00057 struct IsAVWType {typedef __false_type type;};
00058 template <> struct IsAVWType<byte > {typedef __true_type type;};
00059 template <> struct IsAVWType<short > {typedef __true_type type;};
00060 template <> struct IsAVWType<int > {typedef __true_type type;};
00061 template <> struct IsAVWType<float > {typedef __true_type type;};
00062 template <> struct IsAVWType<complex<double> > {typedef __true_type type;};
00063 template <> struct IsAVWType<double > {typedef __true_type type;};
00064
00065
00066
00067 };
00068
00069
00070
00071 namespace IP3D
00072 {
00091 template <class ImageType>
00092 void ImageFromRawData(const typename ImageType::value_type *data,const Size3D &size,string order,ImageType &res,bool reverseEndian=false)
00093 {
00094 typedef typename ImageType::value_type Im3DValue;
00095 res.Resize(size);
00096 Vect3Di vorder;
00097 for(int i=0;i<3;i++)
00098 {
00099 vorder(i)=order[i]-'X';
00100 if(vorder(i)<0 || vorder(i)>2){ThrowError("CImageFromRawData::bad order string");}
00101 }
00102 Vect3Di fact;
00103 Vect3Di vsize=size.GetV();
00104 fact(vorder(0))=1;
00105 fact(vorder(1))=vsize(vorder(0));
00106 fact(vorder(2))=vsize(vorder(0))*vsize(vorder(1));
00107
00108 for(typename ImageType::iteratorXYZ p=res.begin();p!=res.end();++p)
00109 {
00110 const Im3DValue &v=data[p.x*fact.x+p.y*fact.y+p.z*fact.z];
00111 if(!reverseEndian){*p=v;}
00112 else{ReverseEndian(v,*p);}
00113 }
00114 }
00115 };
00116 namespace IP3D
00117 {
00129 template <class ImageType>
00130 void RawDataFromImage(const ImageType &src,string order,typename ImageType::value_type **pres,bool reverseEndian=false)
00131 {
00132 typedef typename ImageType::value_type Im3DValue;
00133 *pres=new Im3DValue[src.GetNVoxels()];
00134 Im3DValue *res=*pres;
00135 Vect3Di vorder;
00136 for(int i=0;i<3;i++)
00137 {
00138 vorder(i)=order[i]-'X';
00139 if(vorder(i)<0 || vorder(i)>2){ThrowError("CRawDataFromImage::bad order string");}
00140 }
00141 Vect3Di fact;
00142 Vect3Di vsize=src.SizeV();
00143 fact(vorder(0))=1;
00144 fact(vorder(1))=vsize(vorder(0));
00145 fact(vorder(2))=vsize(vorder(0))*vsize(vorder(1));
00146
00147 for(typename ImageType::const_iteratorXYZ p=src.begin();p!=src.end();++p)
00148 {
00149 Im3DValue v;
00150 if(!reverseEndian){v=*p;}
00151 else{ReverseEndian(*p,v);}
00152 res[p.x*fact.x+p.y*fact.y+p.z*fact.z]=v;
00153 }
00154 }
00155 };
00156
00157
00158 namespace IP3D
00159 {
00166 template <class ImageType >
00167 void WriteToFileAVW(const ImageType &src,const string &fname)
00168 {
00169 using namespace FileConversion;
00170 if(IsSameType<__false_type,typename IsAVWType<typename ImageType::value_type>::type>())
00171 {
00172 ThrowError("IP3D::WriteToFileAVW ImageType:\"%s\" can not be converted to AVW",TypeName<ImageType>());
00173 }
00174 AVW *avw=AvwOpen( fname.c_str(), "w" );
00175 if(!avw){ThrowError("CWriteToFileAVW:: open failed for \"%s\"",fname);}
00176 AvwInitHeader ( avw, FileConversion::AVWType<typename ImageType::value_type>(),
00177 src.Width(), src.Height(), src.Width(), 1,
00178 1,1,1, 0,
00179 3, "mm" );
00180 size_t nVolsRes=AvwWriteVolumes (avw, (const void *)src.GetData(), 1 );
00181 printf("CWriteToFileAVW:: wrote %d volumes\n",nVolsRes);
00182 AvwClose ( avw );
00183 }
00184 };
00185
00186 namespace IP3D
00187 {
00194 template <class ImageType >
00195 void ReadFromFileAVW(const string &fname,ImageType &res)
00196 {
00197 using namespace FileConversion;
00198 AVW *avw=AvwOpen( fname.c_str(), "r" );
00199 if(!avw){ThrowError("CReadFromFileAVW:: open failed for \"%s\"",fname);}
00200 short w,h,d,v;
00201 short dataType;
00202 AvwGetDataType ( avw, &dataType );
00203 if(dataType!=FileConversion::AVWType<typename ImageType::value_type>())
00204 {
00205 ThrowError("CReadFromFileAVW:: template image data type:%d does not match data type in avw file:%d",
00206 FileConversion::AVWType<typename ImageType::value_type>(),dataType);
00207 }
00208 AvwGetDim ( avw,&w,&h,&d,&v );
00209 char orientation[1000];
00210 AvwGetOrientation ( avw, orientation );
00211 printf("CReadFromFileAVW:: image size:%d %d %d nvol:%d orientation:\"%s\"\n",w,h,d,v,orientation);
00212 res.Resize(Size3D(w,h,d));
00213 size_t nVolsRes=AvwReadVolumes (avw, (void *)res.GetData(), 1 );
00214 printf("CReadFromFileAVW:: read %d volumes\n",nVolsRes);
00215 AvwClose ( avw );
00216 }
00217 };
00218
00219 namespace IP3D
00220 {
00229 void ReadFromFileBruker(const string &fname,int imageNumber,Image3Dlinear<short int> &res);
00230 };
00231
00232 namespace IP3D
00233 {
00256 template <class ImageType>
00257 void ExportImageSlice(const ImageType &src,int direction,int position,const string &fname,float rescale=1)
00258 {
00259 bool doRescaling=(rescale!=0);
00260 bool fullImageRescale=(rescale <0);
00261 rescale=fabs(rescale);
00262
00263 int c1=(direction+1)%3;
00264 int c2=(direction+2)%3;
00265 int width=src.SizeV()(c1);
00266 int height=src.SizeV()(c2);
00267 typedef byte ppmtype;
00268 ppmtype *res=new ppmtype[width*height];
00269 uint maxvalue=(1<<(8*sizeof(ppmtype)))-1;
00270
00271 float minv,maxv;
00272 if(doRescaling)
00273 {
00274 vector<float> values;
00275 values.reserve(fullImageRescale ? src.GetNVoxels() : width*height);
00276 for(typename ImageType::const_iteratorXYZ p=src.begin();p!=src.end();++p)
00277 {
00278 if(fullImageRescale || p.Pos()(direction)==position){values.push_back((float)(*p));}
00279 }
00280 float margin=(1-rescale)/2.0;
00281 int n1=(int)floor( margin *(values.size()-1));
00282 int n2=(int)ceil ((1-margin)*(values.size()-1));
00283 nth_element(values.begin(),values.begin()+n1,values.end());
00284 minv=values[n1];
00285 nth_element(values.begin(),values.begin()+n2,values.end());
00286 maxv=values[n2];
00287 printf("minv:%f maxv:%f rescale:%f margin:%f n1:%d n2:%d\n",minv,maxv,rescale,margin,n1,n2);
00288 }
00289 for(int x=0;x<width;x++)
00290 for(int y=0;y<height;y++)
00291 {
00292 Vect3Di pos;
00293 pos(direction)=position;
00294 pos(c1)=x;
00295 pos(c2)=y;
00296 if(doRescaling)
00297 {
00298 res[x+y*width]=(ppmtype)(( (min(maxv,max(minv,(float)src(pos)))-minv)/(maxv-minv))*maxvalue);
00299 }
00300 else
00301 {
00302 res[x+y*width]=(ppmtype)src(pos);
00303 }
00304 }
00305 FILE *F=fopen(fname.c_str(),"w");
00306 if(!F){ThrowError("IP3D::ExportImageSlice output file \"%s\" open failed",fname);}
00307 fprintf(F,"P5\n%d %d\n%d\n",width,height,maxvalue);
00308 fwrite((void *)res,width*height*sizeof(ppmtype),1,F);
00309 fclose(F);
00310 delete [] res;
00311 }
00312 };
00313
00314 #endif// _FileConversion_hpp