00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkConfig.h"
00019 #include "mitkPicHelper.h"
00020 #include "mitkSlicedGeometry3D.h"
00021 #include "mitkPlaneGeometry.h"
00022 #ifdef HAVE_IPDICOM
00023 #include "ipDicom/ipDicom.h"
00024 #endif
00025
00026 bool mitk::PicHelper::GetSpacing(const mitkIpPicDescriptor* aPic, Vector3D & spacing)
00027 {
00028 mitkIpPicDescriptor* pic = const_cast<mitkIpPicDescriptor*>(aPic);
00029
00030 mitkIpPicTSV_t *tsv;
00031 bool pixelSize = false;
00032
00033 tsv = mitkIpPicQueryTag( pic, "REAL PIXEL SIZE" );
00034 if(tsv==NULL)
00035 {
00036 tsv = mitkIpPicQueryTag( pic, "PIXEL SIZE" );
00037 pixelSize = true;
00038 }
00039 if(tsv)
00040 {
00041 bool tagFound = false;
00042 if((tsv->dim*tsv->n[0]>=3) && (tsv->type==mitkIpPicFloat))
00043 {
00044 if(tsv->bpe==32)
00045 {
00046 FillVector3D(spacing,((mitkIpFloat4_t*)tsv->value)[0], ((mitkIpFloat4_t*)tsv->value)[1],((mitkIpFloat4_t*)tsv->value)[2]);
00047 tagFound = true;
00048 }
00049 else
00050 if(tsv->bpe==64)
00051 {
00052 FillVector3D(spacing,((mitkIpFloat8_t*)tsv->value)[0], ((mitkIpFloat8_t*)tsv->value)[1],((mitkIpFloat8_t*)tsv->value)[2]);
00053 tagFound = true;
00054 }
00055 }
00056 if(tagFound && pixelSize)
00057 {
00058 tsv = mitkIpPicQueryTag( pic, "PIXEL SPACING" );
00059 if(tsv)
00060 {
00061 mitk::ScalarType zSpacing = 0;
00062 if((tsv->dim*tsv->n[0]>=3) && (tsv->type==mitkIpPicFloat))
00063 {
00064 if(tsv->bpe==32)
00065 {
00066 zSpacing = ((mitkIpFloat4_t*)tsv->value)[2];
00067 }
00068 else
00069 if(tsv->bpe==64)
00070 {
00071 zSpacing = ((mitkIpFloat8_t*)tsv->value)[2];
00072 }
00073 if(zSpacing != 0)
00074 {
00075 spacing[2] = zSpacing;
00076 }
00077 }
00078 }
00079 }
00080 if(tagFound) return true;
00081 }
00082 #ifdef HAVE_IPDICOM
00083 tsv = mitkIpPicQueryTag( pic, "SOURCE HEADER" );
00084 if( tsv )
00085 {
00086 void *data;
00087 mitkIpUInt4_t len;
00088 mitkIpFloat8_t spacing_z = 0;
00089 mitkIpFloat8_t thickness = 1;
00090 mitkIpFloat8_t fx = 1;
00091 mitkIpFloat8_t fy = 1;
00092 bool ok=false;
00093
00094 if( dicomFindElement( (unsigned char *) tsv->value, 0x0018, 0x0088, &data, &len ) )
00095 {
00096 ok=true;
00097 sscanf( (char *) data, "%lf", &spacing_z );
00098
00099 }
00100 if( dicomFindElement( (unsigned char *) tsv->value, 0x0018, 0x0050, &data, &len ) )
00101 {
00102 ok=true;
00103 sscanf( (char *) data, "%lf", &thickness );
00104
00105
00106 if( thickness == 0 )
00107 thickness = 1;
00108 }
00109 if( dicomFindElement( (unsigned char *) tsv->value, 0x0028, 0x0030, &data, &len )
00110 && len>0 && ((char *)data)[0] )
00111 {
00112 sscanf( (char *) data, "%lf\\%lf", &fy, &fx );
00113
00114 }
00115 else
00116 ok=false;
00117 if(ok)
00118 FillVector3D(spacing, fx, fy,( spacing_z > 0 ? spacing_z : thickness));
00119 return ok;
00120 }
00121 #endif
00122 if(spacing[0]<=0 || spacing[1]<=0 || spacing[2]<=0)
00123 {
00124 itkGenericOutputMacro(<< "illegal spacing by pic tag: " << spacing << ". Setting spacing to (1,1,1).");
00125 spacing.Fill(1);
00126 }
00127 return false;
00128 }
00129
00130 bool mitk::PicHelper::GetTimeSpacing(const mitkIpPicDescriptor* aPic, float& timeSpacing)
00131 {
00132
00133 mitkIpPicDescriptor* pic = const_cast<mitkIpPicDescriptor*>(aPic);
00134
00135 mitkIpPicTSV_t *tsv;
00136
00137 tsv = mitkIpPicQueryTag( pic, "PIXEL SIZE" );
00138 if(tsv)
00139 {
00140 timeSpacing = ((mitkIpFloat4_t*)tsv->value)[3];
00141 if( timeSpacing <=0 ) timeSpacing = 1;
00142 }
00143 else timeSpacing = 1;
00144 return true;
00145 }
00146
00147 bool mitk::PicHelper::SetSpacing(const mitkIpPicDescriptor* aPic, SlicedGeometry3D* slicedgeometry)
00148 {
00149 mitkIpPicDescriptor* pic = const_cast<mitkIpPicDescriptor*>(aPic);
00150
00151 Vector3D spacing(slicedgeometry->GetSpacing());
00152
00153 mitkIpPicTSV_t *tsv;
00154 if ( (tsv = mitkIpPicQueryTag( pic, "REAL PIXEL SIZES" )) != NULL)
00155 {
00156 int count = tsv->n[1];
00157 float* value = (float*) tsv->value;
00158 mitk::Vector3D pixelSize;
00159 spacing.Fill(0);
00160
00161 for ( int s=0; s < count; s++ )
00162 {
00163 pixelSize[0] = (ScalarType) *value++;
00164 pixelSize[1] = (ScalarType) *value++;
00165 pixelSize[2] = (ScalarType) *value++;
00166 spacing += pixelSize;
00167 }
00168 spacing *= 1.0f/count;
00169 slicedgeometry->SetSpacing(spacing);
00170
00171 itkGenericOutputMacro(<< "the slices are inhomogeneous" );
00172 }
00173 else
00174 if(GetSpacing(pic, spacing))
00175 {
00176 slicedgeometry->SetSpacing(spacing);
00177 return true;
00178 }
00179 return false;
00180 }
00181
00182 void mitk::PicHelper::InitializeEvenlySpaced(const mitkIpPicDescriptor* pic, unsigned int slices, SlicedGeometry3D* slicedgeometry)
00183 {
00184 assert(pic!=NULL);
00185 assert(slicedgeometry!=NULL);
00186
00187 mitk::PlaneGeometry::Pointer planegeometry=mitk::PlaneGeometry::New();
00188
00189 mitkIpPicTSV_t *geometryTag;
00190 if ( (geometryTag = mitkIpPicQueryTag( const_cast<mitkIpPicDescriptor*>(pic), "ISG" )) != NULL)
00191 {
00192 mitk::Point3D origin;
00193 mitk::Vector3D rightVector;
00194 mitk::Vector3D downVector;
00195 mitk::Vector3D spacing;
00196
00197 mitk::vtk2itk(((float*)geometryTag->value+0), origin);
00198 mitk::vtk2itk(((float*)geometryTag->value+3), rightVector);
00199 mitk::vtk2itk(((float*)geometryTag->value+6), downVector);
00200 mitk::vtk2itk(((float*)geometryTag->value+9), spacing);
00201
00202 mitk::PlaneGeometry::Pointer planegeometry = PlaneGeometry::New();
00203 planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], rightVector, downVector, &spacing);
00204 planegeometry->SetOrigin(origin);
00205 slicedgeometry->InitializeEvenlySpaced(planegeometry, slices);
00206 }
00207 else
00208 {
00209 Vector3D spacing;
00210 spacing.Fill(1);
00211 GetSpacing(pic, spacing);
00212 planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], spacing);
00213 slicedgeometry->InitializeEvenlySpaced(planegeometry, spacing[2], slices);
00214 }
00215
00216 if(pic->dim>=4)
00217 {
00218 float ts = 0;
00219 GetTimeSpacing(pic, ts);
00220 TimeBounds timebounds;
00221 timebounds[0] = 0.0;
00222 timebounds[1] = ts;
00223 slicedgeometry->SetTimeBounds(timebounds);
00224 }
00225 }
00226
00227 bool mitk::PicHelper::SetGeometry2D(const mitkIpPicDescriptor* aPic, int s, SlicedGeometry3D* slicedgeometry)
00228 {
00229 mitkIpPicDescriptor* pic = const_cast<mitkIpPicDescriptor*>(aPic);
00230 if((pic!=NULL) && (slicedgeometry->IsValidSlice(s)))
00231 {
00232
00233 mitk::Point3D origin;
00234 mitk::Vector3D rightDV, bottomDV;
00235 mitkIpPicTSV_t *tsv;
00236 if ( (tsv = mitkIpPicQueryTag( pic, "REAL PIXEL SIZES" )) != NULL)
00237 {
00238 unsigned int count = (unsigned int) tsv->n[1];
00239 float* value = (float*) tsv->value;
00240 mitk::Vector3D pixelSize;
00241 ScalarType zPosition = 0.0f;
00242
00243 if(s >= 0)
00244 {
00245 if(count < (unsigned int) s)
00246 return false;
00247 count = s;
00248 }
00249 else
00250 {
00251 if(count < slicedgeometry->GetSlices())
00252 return false;
00253 count = slicedgeometry->GetSlices();
00254 }
00255
00256 unsigned int slice;
00257 for (slice=0; slice < count; ++slice )
00258 {
00259 pixelSize[0] = (ScalarType) *value++;
00260 pixelSize[1] = (ScalarType) *value++;
00261 pixelSize[2] = (ScalarType) *value++;
00262
00263 zPosition += pixelSize[2] / 2.0f;
00264
00265 if((s==-1) || (slice== (unsigned int) s))
00266 {
00267 Vector3D spacing;
00268 spacing = pixelSize;
00269 FillVector3D(origin, 0, 0, zPosition);
00270 FillVector3D(rightDV, pic->n[0], 0, 0);
00271 FillVector3D(bottomDV, 0, pic->n[1], 0);
00272
00273 mitk::PlaneGeometry::Pointer planegeometry=mitk::PlaneGeometry::New();
00274 planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], rightDV.Get_vnl_vector(), bottomDV.Get_vnl_vector(), &spacing);
00275 planegeometry->SetOrigin(origin);
00276 slicedgeometry->SetGeometry2D(planegeometry, s);
00277 }
00278
00279 zPosition += pixelSize[2] / 2.0f;
00280 }
00281
00282 }
00283 else
00284 {
00285 FillVector3D(origin,0,0,s); slicedgeometry->IndexToWorld(origin, origin);
00286 FillVector3D(rightDV,pic->n[0],0,0);
00287 FillVector3D(bottomDV,0,pic->n[1],0);
00288
00289 mitk::PlaneGeometry::Pointer planegeometry=mitk::PlaneGeometry::New();
00290 planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], rightDV.Get_vnl_vector(), bottomDV.Get_vnl_vector(), &slicedgeometry->GetSpacing());
00291 planegeometry->SetOrigin(origin);
00292 slicedgeometry->SetGeometry2D(planegeometry, s);
00293 }
00294 return true;
00295 }
00296 return false;
00297 }