00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkImage.h"
00019
00020 #include "mitkHistogramGenerator.h"
00021 #include "mitkPicHelper.h"
00022 #include "mitkImageTimeSelector.h"
00023
00024 #include "ipFunc/mitkIpFunc.h"
00025 #include "mitkIpPicTypeMultiplex.h"
00026
00027 #include <itkSmartPointerForwardReference.txx>
00028
00029 #include <vtkImageData.h>
00030
00031
00032
00033
00034
00035 mitk::Image::Image() :
00036 m_Dimension(0), m_Dimensions(NULL), m_OffsetTable(NULL),
00037 m_CompleteData(NULL), m_PixelType(NULL),
00038 m_TimeSelectorForExtremaObject(NULL)
00039 {
00040 m_CountOfMinValuedVoxels.resize(1, 0);
00041 m_CountOfMaxValuedVoxels.resize(1, 0);
00042 m_ScalarMin.resize(1, itk::NumericTraits<ScalarType>::max());
00043 m_ScalarMax.resize(1, itk::NumericTraits<ScalarType>::NonpositiveMin());
00044 m_Scalar2ndMin.resize(1, itk::NumericTraits<ScalarType>::max());
00045 m_Scalar2ndMax.resize(1, itk::NumericTraits<ScalarType>::NonpositiveMin());
00046
00047 m_Initialized = false;
00048 mitk::HistogramGenerator::Pointer generator = mitk::HistogramGenerator::New();
00049 m_HistogramGeneratorObject = generator;
00050 }
00051
00052 mitk::Image::~Image()
00053 {
00054 Clear();
00055 m_ReferenceCountLock.Lock();
00056 m_ReferenceCount = 3;
00057 m_ReferenceCountLock.Unlock();
00058 m_HistogramGeneratorObject = NULL;
00059 m_TimeSelectorForExtremaObject = NULL;
00060 m_ReferenceCountLock.Lock();
00061 m_ReferenceCount = 0;
00062 m_ReferenceCountLock.Unlock();
00063 delete [] m_OffsetTable;
00064 }
00065
00066 const mitk::PixelType& mitk::Image::GetPixelType(int ) const
00067 {
00068 return m_PixelType;
00069 }
00070
00071 unsigned int mitk::Image::GetDimension() const
00072 {
00073 return m_Dimension;
00074 }
00075
00076 unsigned int mitk::Image::GetDimension(int i) const
00077 {
00078 if((i>=0) && (i<(int)m_Dimension))
00079 return m_Dimensions[i];
00080 return 1;
00081 }
00082
00083 void* mitk::Image::GetData()
00084 {
00085 if(m_Initialized==false)
00086 {
00087 if(GetSource()==NULL)
00088 return NULL;
00089 if(GetSource()->Updating()==false)
00090 GetSource()->UpdateOutputInformation();
00091 }
00092 m_CompleteData=GetChannelData();
00093 return m_CompleteData->GetData();
00094 }
00095
00096 template <class T>
00097 void AccessPixel(mitkIpPicDescriptor* pic, const mitk::Index3D& p, double& value, int timestep)
00098 {
00099 if ( (p[0]>=0 && p[1] >=0 && p[2]>=0 && timestep>=0) && (unsigned int)p[0] < pic->n[0] && (unsigned int)p[1] < pic->n[1] && (unsigned int)p[2] < pic->n[2] && (unsigned int)timestep < pic->n[3] )
00100 {
00101 if(pic->bpe!=24)
00102 {
00103 value = (double) (((T*) pic->data)[ p[0] + p[1]*pic->n[0] + p[2]*pic->n[0]*pic->n[1] + timestep*pic->n[0]*pic->n[1]*pic->n[2] ]);
00104 }
00105 else
00106 {
00107 double returnvalue = (((T*) pic->data)[p[0]*3 + 0 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 + timestep*pic->n[0]*pic->n[1]*pic->n[2]*3 ]);
00108 returnvalue += (((T*) pic->data)[p[0]*3 + 1 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 + timestep*pic->n[0]*pic->n[1]*pic->n[2]*3]);
00109 returnvalue += (((T*) pic->data)[p[0]*3 + 2 + p[1]*pic->n[0]*3 + p[2]*pic->n[0]*pic->n[1]*3 + timestep*pic->n[0]*pic->n[1]*pic->n[2]*3]);
00110 value = returnvalue;
00111 }
00112 }
00113 else
00114 {
00115 value = 0;
00116 }
00117 };
00118
00119 double mitk::Image::GetPixelValueByIndex(const mitk::Index3D &position, unsigned int timestep)
00120 {
00121 mitkIpPicDescriptor* pic = this->GetPic();
00122 double value = 0;
00123 if (this->GetTimeSteps() < timestep)
00124 {
00125 timestep = this->GetTimeSteps();
00126 }
00127 mitkIpPicTypeMultiplex3(AccessPixel, pic, position, value, timestep);
00128 return value;
00129 }
00130
00131 double mitk::Image::GetPixelValueByWorldCoordinate(const mitk::Point3D& position, unsigned int timestep)
00132 {
00133 mitkIpPicDescriptor* pic = this->GetPic();
00134 double value = 0;
00135 if (this->GetTimeSteps() < timestep)
00136 {
00137 timestep = this->GetTimeSteps();
00138 }
00139
00140 Index3D itkIndex;
00141 this->GetGeometry()->WorldToIndex(position,itkIndex);
00142 mitkIpPicTypeMultiplex3(AccessPixel, pic, itkIndex, value, timestep);
00143
00144 return value;
00145 }
00146
00147 vtkImageData* mitk::Image::GetVtkImageData(int t, int n)
00148 {
00149 if(m_Initialized==false)
00150 {
00151 if(GetSource()==NULL)
00152 return NULL;
00153 if(GetSource()->Updating()==false)
00154 GetSource()->UpdateOutputInformation();
00155 }
00156 ImageDataItemPointer volume=GetVolumeData(t, n);
00157 if(volume.GetPointer()==NULL || volume->GetVtkImageData() == NULL)
00158 return NULL;
00159
00160 #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) ))
00161 float *fspacing = const_cast<float *>(GetSlicedGeometry(t)->GetFloatSpacing());
00162 double dspacing[3] = {fspacing[0],fspacing[1],fspacing[2]};
00163 volume->GetVtkImageData()->SetSpacing( dspacing );
00164 #else
00165 volume->GetVtkImageData()->SetSpacing(const_cast<float*>(GetSlicedGeometry(t)->GetFloatSpacing()));
00166 #endif
00167 return volume->GetVtkImageData();
00168 }
00169
00170 mitkIpPicDescriptor* mitk::Image::GetPic()
00171 {
00172 if(m_Initialized==false)
00173 {
00174 if(GetSource()==NULL)
00175 return NULL;
00176 if(GetSource()->Updating()==false)
00177 GetSource()->UpdateOutputInformation();
00178 }
00179 m_CompleteData=GetChannelData();
00180 if(m_CompleteData.GetPointer()==NULL)
00181 return NULL;
00182 return m_CompleteData->GetPicDescriptor();
00183 }
00184
00185 mitk::Image::ImageDataItemPointer mitk::Image::GetSliceData(int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement)
00186 {
00187 if(IsValidSlice(s,t,n)==false) return NULL;
00188
00189
00190 int pos=GetSliceIndex(s,t,n);
00191 if(m_Slices[pos].GetPointer()!=NULL)
00192 return m_Slices[pos];
00193
00194
00195 ImageDataItemPointer sl, ch, vol;
00196 vol=m_Volumes[GetVolumeIndex(t,n)];
00197 if((vol.GetPointer()!=NULL) && (vol->IsComplete()))
00198 {
00199 sl=new ImageDataItem(*vol, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(m_PixelType.GetBpe()/8));
00200 sl->SetComplete(true);
00201 return m_Slices[pos]=sl;
00202 }
00203
00204
00205 ch=m_Channels[n];
00206 if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
00207 {
00208 sl=new ImageDataItem(*ch, 2, data, importMemoryManagement == ManageMemory, (((size_t) s)*m_OffsetTable[2]+((size_t) t)*m_OffsetTable[3])*(m_PixelType.GetBpe()/8));
00209 sl->SetComplete(true);
00210 return m_Slices[pos]=sl;
00211 }
00212
00213
00214 if((GetSource()!=NULL) && (GetSource()->Updating()==false))
00215 {
00216
00217 m_RequestedRegion.SetIndex(0, 0);
00218 m_RequestedRegion.SetIndex(1, 0);
00219 m_RequestedRegion.SetIndex(2, s);
00220 m_RequestedRegion.SetIndex(3, t);
00221 m_RequestedRegion.SetIndex(4, n);
00222 m_RequestedRegion.SetSize(0, m_Dimensions[0]);
00223 m_RequestedRegion.SetSize(1, m_Dimensions[1]);
00224 m_RequestedRegion.SetSize(2, 1);
00225 m_RequestedRegion.SetSize(3, 1);
00226 m_RequestedRegion.SetSize(4, 1);
00227 m_RequestedRegionInitialized=true;
00228 GetSource()->Update();
00229 if(IsSliceSet(s,t,n))
00230
00231 return GetSliceData(s,t,n,data,importMemoryManagement);
00232 else
00233 return NULL;
00234 }
00235 else
00236 {
00237 ImageDataItemPointer item = AllocateSliceData(s,t,n,data,importMemoryManagement);
00238 item->SetComplete(true);
00239 return item;
00240 }
00241 }
00242
00243 mitk::Image::ImageDataItemPointer mitk::Image::GetVolumeData(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement)
00244 {
00245 if(IsValidVolume(t,n)==false) return NULL;
00246
00247 ImageDataItemPointer ch, vol;
00248
00249
00250 int pos=GetVolumeIndex(t,n);
00251 vol=m_Volumes[pos];
00252 if((vol.GetPointer()!=NULL) && (vol->IsComplete()))
00253 return vol;
00254
00255
00256 ch=m_Channels[n];
00257 if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
00258 {
00259 vol=new ImageDataItem(*ch, 3, data, importMemoryManagement == ManageMemory, (((size_t) t)*m_OffsetTable[3])*(m_PixelType.GetBpe()/8));
00260 vol->SetComplete(true);
00261 return m_Volumes[pos]=vol;
00262 }
00263
00264
00265 bool complete=true;
00266 unsigned int s;
00267 for(s=0;s<m_Dimensions[2];++s)
00268 {
00269 if(m_Slices[GetSliceIndex(s,t,n)].GetPointer()==NULL)
00270 {
00271 complete=false;
00272 break;
00273 }
00274 }
00275 if(complete)
00276 {
00277
00278 if(m_Dimensions[2]<=1)
00279 {
00280 ImageDataItemPointer sl;
00281 sl=GetSliceData(0,t,n,data,importMemoryManagement);
00282 vol=new ImageDataItem(*sl, 3, data, importMemoryManagement == ManageMemory);
00283 vol->SetComplete(true);
00284 }
00285 else
00286 {
00287 vol=m_Volumes[pos];
00288
00289 if(vol.GetPointer()==NULL)
00290 vol=new ImageDataItem(m_PixelType, 3, m_Dimensions, NULL, true);
00291 vol->SetComplete(true);
00292 size_t size=m_OffsetTable[2]*(m_PixelType.GetBpe()/8);
00293 for(s=0;s<m_Dimensions[2];++s)
00294 {
00295 int posSl;
00296 ImageDataItemPointer sl;
00297 posSl=GetSliceIndex(s,t,n);
00298
00299 sl=m_Slices[posSl];
00300 if(sl->GetParent()!=vol)
00301 {
00302
00303 size_t offset = ((size_t) s)*size;
00304 std::memcpy(static_cast<char*>(vol->GetData())+offset, sl->GetData(), size);
00305
00306 mitkIpPicDescriptor * pic = sl->GetPicDescriptor();
00307
00308
00309 sl=new ImageDataItem(*vol, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*size);
00310 sl->SetComplete(true);
00311 mitkIpFuncCopyTags(sl->GetPicDescriptor(), pic);
00312 m_Slices[posSl]=sl;
00313 }
00314 }
00315 if(vol->GetPicDescriptor()->info->tags_head==NULL)
00316 mitkIpFuncCopyTags(vol->GetPicDescriptor(), m_Slices[GetSliceIndex(0,t,n)]->GetPicDescriptor());
00317 }
00318 return m_Volumes[pos]=vol;
00319 }
00320
00321
00322 if((GetSource()!=NULL) && (GetSource()->Updating()==false))
00323 {
00324
00325 m_RequestedRegion.SetIndex(0, 0);
00326 m_RequestedRegion.SetIndex(1, 0);
00327 m_RequestedRegion.SetIndex(2, 0);
00328 m_RequestedRegion.SetIndex(3, t);
00329 m_RequestedRegion.SetIndex(4, n);
00330 m_RequestedRegion.SetSize(0, m_Dimensions[0]);
00331 m_RequestedRegion.SetSize(1, m_Dimensions[1]);
00332 m_RequestedRegion.SetSize(2, m_Dimensions[2]);
00333 m_RequestedRegion.SetSize(3, 1);
00334 m_RequestedRegion.SetSize(4, 1);
00335 m_RequestedRegionInitialized=true;
00336 GetSource()->Update();
00337 if(IsVolumeSet(t,n))
00338
00339 return GetVolumeData(t,n,data,importMemoryManagement);
00340 else
00341 return NULL;
00342 }
00343 else
00344 {
00345 ImageDataItemPointer item = AllocateVolumeData(t,n,data,importMemoryManagement);
00346 item->SetComplete(true);
00347 return item;
00348 }
00349 }
00350
00351 mitk::Image::ImageDataItemPointer mitk::Image::GetChannelData(int n, void *data, ImportMemoryManagementType importMemoryManagement)
00352 {
00353 if(IsValidChannel(n)==false) return NULL;
00354 ImageDataItemPointer ch, vol;
00355 ch=m_Channels[n];
00356 if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
00357 return ch;
00358
00359
00360 if(IsChannelSet(n))
00361 {
00362
00363 if(m_Dimensions[3]<=1)
00364 {
00365 vol=GetVolumeData(0,n,data,importMemoryManagement);
00366 ch=new ImageDataItem(*vol, 3, data, importMemoryManagement == ManageMemory);
00367 ch->SetComplete(true);
00368 }
00369 else
00370 {
00371 ch=m_Channels[n];
00372
00373 if(ch.GetPointer()==NULL)
00374 ch=new ImageDataItem(m_PixelType, m_Dimension, m_Dimensions, NULL, true);
00375 ch->SetComplete(true);
00376 size_t size=m_OffsetTable[m_Dimension-1]*(m_PixelType.GetBpe()/8);
00377 unsigned int t;
00378 ImageDataItemPointerArray::iterator slicesIt = m_Slices.begin()+n*m_Dimensions[2]*m_Dimensions[3];
00379 for(t=0;t<m_Dimensions[3];++t)
00380 {
00381 int posVol;
00382 ImageDataItemPointer vol;
00383
00384 posVol=GetVolumeIndex(t,n);
00385 vol=GetVolumeData(t,n,data,importMemoryManagement);
00386
00387 if(vol->GetParent()!=ch)
00388 {
00389
00390 size_t offset = ((size_t) t)*m_OffsetTable[3]*(m_PixelType.GetBpe()/8);
00391 std::memcpy(static_cast<char*>(ch->GetData())+offset, vol->GetData(), size);
00392
00393 mitkIpPicDescriptor * pic = vol->GetPicDescriptor();
00394
00395
00396 vol=new ImageDataItem(*ch, 3, data, importMemoryManagement == ManageMemory, offset);
00397 vol->SetComplete(true);
00398 mitkIpFuncCopyTags(vol->GetPicDescriptor(), pic);
00399
00400 m_Volumes[posVol]=vol;
00401
00402
00403 ImageDataItemPointer dnull=NULL;
00404 for(unsigned int i = 0; i < m_Dimensions[2]; ++i, ++slicesIt)
00405 {
00406 assert(slicesIt != m_Slices.end());
00407 *slicesIt = dnull;
00408 }
00409 }
00410 }
00411 if(ch->GetPicDescriptor()->info->tags_head==NULL)
00412 mitkIpFuncCopyTags(ch->GetPicDescriptor(), m_Volumes[GetVolumeIndex(0,n)]->GetPicDescriptor());
00413 }
00414 return m_Channels[n]=ch;
00415 }
00416
00417
00418 if((GetSource()!=NULL) && (GetSource()->Updating()==false))
00419 {
00420
00421 m_RequestedRegion.SetIndex(0, 0);
00422 m_RequestedRegion.SetIndex(1, 0);
00423 m_RequestedRegion.SetIndex(2, 0);
00424 m_RequestedRegion.SetIndex(3, 0);
00425 m_RequestedRegion.SetIndex(4, n);
00426 m_RequestedRegion.SetSize(0, m_Dimensions[0]);
00427 m_RequestedRegion.SetSize(1, m_Dimensions[1]);
00428 m_RequestedRegion.SetSize(2, m_Dimensions[2]);
00429 m_RequestedRegion.SetSize(3, m_Dimensions[3]);
00430 m_RequestedRegion.SetSize(4, 1);
00431 m_RequestedRegionInitialized=true;
00432 GetSource()->Update();
00433
00434 if(IsChannelSet(n))
00435
00436 return GetChannelData(n,data,importMemoryManagement);
00437 else
00438 return NULL;
00439 }
00440 else
00441 {
00442 ImageDataItemPointer item = AllocateChannelData(n,data,importMemoryManagement);
00443 item->SetComplete(true);
00444 return item;
00445 }
00446 }
00447
00448 bool mitk::Image::IsSliceSet(int s, int t, int n) const
00449 {
00450 if(IsValidSlice(s,t,n)==false) return false;
00451
00452 if(m_Slices[GetSliceIndex(s,t,n)].GetPointer()!=NULL)
00453 return true;
00454
00455 ImageDataItemPointer ch, vol;
00456 vol=m_Volumes[GetVolumeIndex(t,n)];
00457 if((vol.GetPointer()!=NULL) && (vol->IsComplete()))
00458 return true;
00459 ch=m_Channels[n];
00460 if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
00461 return true;
00462 return false;
00463 }
00464
00465 bool mitk::Image::IsVolumeSet(int t, int n) const
00466 {
00467 if(IsValidVolume(t,n)==false) return false;
00468 ImageDataItemPointer ch, vol;
00469
00470
00471 vol=m_Volumes[GetVolumeIndex(t,n)];
00472 if((vol.GetPointer()!=NULL) && (vol->IsComplete()))
00473 return true;
00474
00475
00476 ch=m_Channels[n];
00477 if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
00478 return true;
00479
00480
00481 unsigned int s;
00482 for(s=0;s<m_Dimensions[2];++s)
00483 if(m_Slices[GetSliceIndex(s,t,n)].GetPointer()==NULL)
00484 return false;
00485 return true;
00486 }
00487
00488 bool mitk::Image::IsChannelSet(int n) const
00489 {
00490 if(IsValidChannel(n)==false) return false;
00491 ImageDataItemPointer ch, vol;
00492 ch=m_Channels[n];
00493 if((ch.GetPointer()!=NULL) && (ch->IsComplete()))
00494
00495 return true;
00496
00497 unsigned int t;
00498 for(t=0;t<m_Dimensions[3];++t)
00499 if(IsVolumeSet(t,n)==false)
00500 return false;
00501 return true;
00502 }
00503
00504 bool mitk::Image::SetSlice(const void *data, int s, int t, int n)
00505 {
00506
00507 return SetImportSlice(const_cast<void*>(data), s, t, n, CopyMemory);
00508 }
00509
00510 bool mitk::Image::SetVolume(const void *data, int t, int n)
00511 {
00512
00513 return SetImportVolume(const_cast<void*>(data), t, n, CopyMemory);
00514 }
00515
00516 bool mitk::Image::SetChannel(const void *data, int n)
00517 {
00518
00519 return SetImportChannel(const_cast<void*>(data), n, CopyMemory);
00520 }
00521
00522 bool mitk::Image::SetImportSlice(void *data, int s, int t, int n, ImportMemoryManagementType importMemoryManagement)
00523 {
00524 if(IsValidSlice(s,t,n)==false) return false;
00525 ImageDataItemPointer sl;
00526 if(IsSliceSet(s,t,n))
00527 {
00528 sl=GetSliceData(s,t,n,data,importMemoryManagement);
00529 if(sl->GetManageMemory()==false)
00530 {
00531 sl=AllocateSliceData(s,t,n,data,importMemoryManagement);
00532 if(sl.GetPointer()==NULL) return false;
00533 }
00534 if ( sl->GetData() != data )
00535 std::memcpy(sl->GetData(), data, m_OffsetTable[2]*(m_PixelType.GetBpe()/8));
00536 sl->Modified();
00537
00538 Modified();
00539 }
00540 else
00541 {
00542 sl=AllocateSliceData(s,t,n,data,importMemoryManagement);
00543 if(sl.GetPointer()==NULL) return false;
00544 if ( sl->GetData() != data )
00545 std::memcpy(sl->GetData(), data, m_OffsetTable[2]*(m_PixelType.GetBpe()/8));
00546
00547
00548 }
00549 return true;
00550 }
00551
00552 bool mitk::Image::SetImportVolume(void *data, int t, int n, ImportMemoryManagementType importMemoryManagement)
00553 {
00554 if(IsValidVolume(t,n)==false) return false;
00555 ImageDataItemPointer vol;
00556 if(IsVolumeSet(t,n))
00557 {
00558 vol=GetVolumeData(t,n,data,importMemoryManagement);
00559 if(vol->GetManageMemory()==false)
00560 {
00561 vol=AllocateVolumeData(t,n,data,importMemoryManagement);
00562 if(vol.GetPointer()==NULL) return false;
00563 }
00564 if ( vol->GetData() != data )
00565 std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(m_PixelType.GetBpe()/8));
00566 vol->Modified();
00567 vol->SetComplete(true);
00568
00569 Modified();
00570 }
00571 else
00572 {
00573 vol=AllocateVolumeData(t,n,data,importMemoryManagement);
00574 if(vol.GetPointer()==NULL) return false;
00575 if ( vol->GetData() != data )
00576 {
00577 std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(m_PixelType.GetBpe()/8));
00578 }
00579 vol->SetComplete(true);
00580
00581
00582 }
00583 return true;
00584 }
00585
00586 bool mitk::Image::SetImportChannel(void *data, int n, ImportMemoryManagementType importMemoryManagement)
00587 {
00588 if(IsValidChannel(n)==false) return false;
00589 ImageDataItemPointer ch;
00590 if(IsChannelSet(n))
00591 {
00592 ch=GetChannelData(n,data,importMemoryManagement);
00593 if(ch->GetManageMemory()==false)
00594 {
00595 ch=AllocateChannelData(n,data,importMemoryManagement);
00596 if(ch.GetPointer()==NULL) return false;
00597 }
00598 if ( ch->GetData() != data )
00599 std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(m_PixelType.GetBpe()/8));
00600 ch->Modified();
00601 ch->SetComplete(true);
00602
00603 Modified();
00604 }
00605 else
00606 {
00607 ch=AllocateChannelData(n,data,importMemoryManagement);
00608 if(ch.GetPointer()==NULL) return false;
00609 if ( ch->GetData() != data )
00610 std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(m_PixelType.GetBpe()/8));
00611 ch->SetComplete(true);
00612
00613
00614 }
00615 return true;
00616 }
00617
00618 bool mitk::Image::SetPicSlice(const mitkIpPicDescriptor *pic, int s, int t, int n, ImportMemoryManagementType )
00619 {
00620 if(pic==NULL) return false;
00621 if(pic->dim!=2) return false;
00622 if((pic->n[0]!=m_Dimensions[0]) || (pic->n[1]!=m_Dimensions[1])) return false;
00623 if(SetSlice(pic->data,s,t,n))
00624 {
00625 ImageDataItemPointer sl;
00626 sl=GetSliceData(s,t,n,NULL,CopyMemory);
00627 mitkIpFuncCopyTags(sl->GetPicDescriptor(), const_cast<mitkIpPicDescriptor *>(pic));
00628 return true;
00629 }
00630 else
00631 return false;
00632 }
00633
00634 bool mitk::Image::SetPicVolume(const mitkIpPicDescriptor *pic, int t, int n, ImportMemoryManagementType )
00635 {
00636 if(pic==NULL) return false;
00637 if((pic->dim==2) && ((m_Dimension==2) || ((m_Dimension>2) && (m_Dimensions[2]==1)))) return SetPicSlice(pic, 0, t, n);
00638 if(pic->dim!=3) return false;
00639 if((pic->n[0]!=m_Dimensions[0]) || (pic->n[1]!=m_Dimensions[1]) || (pic->n[2]!=m_Dimensions[2])) return false;
00640 if(SetVolume(pic->data,t,n))
00641 {
00642 ImageDataItemPointer vol;
00643 vol=GetVolumeData(t,n,NULL,CopyMemory);
00644 mitkIpFuncCopyTags(vol->GetPicDescriptor(), const_cast<mitkIpPicDescriptor *>(pic));
00645 return true;
00646 }
00647 else
00648 return false;
00649 }
00650
00651 bool mitk::Image::SetPicChannel(const mitkIpPicDescriptor *pic, int n, ImportMemoryManagementType )
00652 {
00653 if(pic==NULL) return false;
00654 if(pic->dim<=3) return SetPicVolume(pic, 0, n);
00655 if(pic->dim!=m_Dimension) return false;
00656 unsigned int i;
00657 for(i=0;i<m_Dimension; ++i)
00658 {
00659 if(pic->n[i]!=m_Dimensions[i]) return false;
00660 }
00661 if(SetChannel(pic->data,n))
00662 {
00663 ImageDataItemPointer ch;
00664 ch=GetChannelData(n,NULL,CopyMemory);
00665
00666
00667
00668 return true;
00669 }
00670 else
00671 return false;
00672 }
00673
00674 void mitk::Image::Initialize()
00675 {
00676 ImageDataItemPointerArray::iterator it, end;
00677 for( it=m_Slices.begin(), end=m_Slices.end(); it!=end; ++it )
00678 {
00679 (*it)=NULL;
00680 }
00681 for( it=m_Volumes.begin(), end=m_Volumes.end(); it!=end; ++it )
00682 {
00683 (*it)=NULL;
00684 }
00685 for( it=m_Channels.begin(), end=m_Channels.end(); it!=end; ++it )
00686 {
00687 (*it)=NULL;
00688 }
00689 m_CompleteData = NULL;
00690
00691 this->GetTimeSelector();
00692
00693 SetRequestedRegionToLargestPossibleRegion();
00694 }
00695
00696 mitk::ImageTimeSelector* mitk::Image::GetTimeSelector() const
00697 {
00698 if(m_TimeSelectorForExtremaObject.IsNull())
00699 {
00700 m_TimeSelectorForExtremaObject = ImageTimeSelector::New();
00701
00702 ImageTimeSelector* timeSelector = static_cast<mitk::ImageTimeSelector*>( m_TimeSelectorForExtremaObject.GetPointer() );
00703 timeSelector->SetInput(this);
00704 this->UnRegister();
00705 }
00706
00707 return static_cast<ImageTimeSelector*>( m_TimeSelectorForExtremaObject.GetPointer() );
00708 }
00709
00710 void mitk::Image::Initialize(const mitk::PixelType& type, unsigned int dimension, unsigned int *dimensions, unsigned int channels)
00711 {
00712 Clear();
00713
00714 m_Dimension=dimension;
00715
00716 if(!dimensions)
00717 itkExceptionMacro(<< "invalid zero dimension image");
00718
00719 unsigned int i;
00720 for(i=0;i<dimension;++i)
00721 {
00722 if(dimensions[i]<1)
00723 itkExceptionMacro(<< "invalid dimension[" << i << "]: " << dimensions[i]);
00724 }
00725
00726 m_Dimensions=new unsigned int[m_Dimension>4?m_Dimension:4];
00727 std::memcpy(m_Dimensions, dimensions, sizeof(unsigned int)*m_Dimension);
00728 if(m_Dimension<4)
00729 {
00730 unsigned int *p;
00731 for(i=0,p=m_Dimensions+m_Dimension;i<4-m_Dimension;++i, ++p)
00732 *p=1;
00733 }
00734
00735 for(i=0;i<4;++i)
00736 {
00737 m_LargestPossibleRegion.SetIndex(i, 0);
00738 m_LargestPossibleRegion.SetSize (i, m_Dimensions[i]);
00739 }
00740 m_LargestPossibleRegion.SetIndex(i, 0);
00741 m_LargestPossibleRegion.SetSize(i, channels);
00742
00743 if(m_LargestPossibleRegion.GetNumberOfPixels()==0)
00744 {
00745 delete [] m_Dimensions;
00746 m_Dimensions = NULL;
00747 return;
00748 }
00749
00750 m_PixelType=type;
00751
00752 PlaneGeometry::Pointer planegeometry = PlaneGeometry::New();
00753 planegeometry->InitializeStandardPlane(m_Dimensions[0], m_Dimensions[1]);
00754
00755 SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New();
00756 slicedGeometry->InitializeEvenlySpaced(planegeometry, m_Dimensions[2]);
00757
00758 if(dimension>=4)
00759 {
00760 TimeBounds timebounds;
00761 timebounds[0] = 0.0;
00762 timebounds[1] = 1.0;
00763 slicedGeometry->SetTimeBounds(timebounds);
00764 }
00765
00766 TimeSlicedGeometry::Pointer timeSliceGeometry = TimeSlicedGeometry::New();
00767 timeSliceGeometry->InitializeEvenlyTimed(slicedGeometry, m_Dimensions[3]);
00768
00769 SetGeometry(timeSliceGeometry);
00770
00771 ImageDataItemPointer dnull=NULL;
00772
00773 m_Channels.assign(GetNumberOfChannels(), dnull);
00774
00775 m_Volumes.assign(GetNumberOfChannels()*m_Dimensions[3], dnull);
00776
00777 m_Slices.assign(GetNumberOfChannels()*m_Dimensions[3]*m_Dimensions[2], dnull);
00778
00779 ComputeOffsetTable();
00780
00781 Initialize();
00782
00783 m_Initialized = true;
00784 }
00785
00786 void mitk::Image::Initialize(const mitk::PixelType& type, const mitk::Geometry3D& geometry, unsigned int channels, int tDim )
00787 {
00788 unsigned int dimensions[5];
00789 dimensions[0] = (unsigned int)(geometry.GetExtent(0)+0.5);
00790 dimensions[1] = (unsigned int)(geometry.GetExtent(1)+0.5);
00791 dimensions[2] = (unsigned int)(geometry.GetExtent(2)+0.5);
00792 dimensions[3] = 0;
00793 dimensions[4] = 0;
00794
00795 unsigned int dimension = 2;
00796 if ( dimensions[2] > 1 )
00797 dimension = 3;
00798
00799 if ( tDim > 0)
00800 {
00801 dimensions[3] = tDim;
00802 }
00803 else
00804 {
00805 const mitk::TimeSlicedGeometry* timeGeometry = dynamic_cast<const mitk::TimeSlicedGeometry*>(&geometry);
00806 if ( timeGeometry != NULL )
00807 {
00808 dimensions[3] = timeGeometry->GetTimeSteps();
00809 }
00810 }
00811
00812 if ( dimensions[3] > 1 )
00813 dimension = 4;
00814
00815 Initialize( type, dimension, dimensions, channels );
00816
00817 SetGeometry(static_cast<Geometry3D*>(geometry.Clone().GetPointer()));
00818
00819 mitk::BoundingBox::BoundsArrayType bounds = geometry.GetBoundingBox()->GetBounds();
00820 if( (bounds[0] != 0.0) || (bounds[2] != 0.0) || (bounds[4] != 0.0) )
00821 {
00822 SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0);
00823
00824 mitk::Point3D origin; origin.Fill(0.0);
00825 slicedGeometry->IndexToWorld(origin, origin);
00826
00827 bounds[1]-=bounds[0]; bounds[3]-=bounds[2]; bounds[5]-=bounds[4];
00828 bounds[0] = 0.0; bounds[2] = 0.0; bounds[4] = 0.0;
00829
00830 slicedGeometry->SetBounds(bounds);
00831 slicedGeometry->GetIndexToWorldTransform()->SetOffset(origin.Get_vnl_vector().data_block());
00832
00833 GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, m_Dimensions[3]);
00834 }
00835 }
00836
00837 void mitk::Image::Initialize(const mitk::PixelType& type, int sDim, const mitk::Geometry2D& geometry2d, bool flipped, unsigned int channels, int tDim )
00838 {
00839 SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New();
00840 slicedGeometry->InitializeEvenlySpaced(static_cast<Geometry2D*>(geometry2d.Clone().GetPointer()), sDim, flipped);
00841 Initialize(type, *slicedGeometry, channels, tDim);
00842 }
00843
00844 void mitk::Image::Initialize(const mitk::Image* image)
00845 {
00846 Initialize(*image->GetPixelType().GetTypeId(), *image->GetTimeSlicedGeometry());
00847 }
00848
00849 void mitk::Image::Initialize(vtkImageData* vtkimagedata, int channels, int tDim, int sDim)
00850 {
00851 if(vtkimagedata==NULL) return;
00852
00853 m_Dimension=vtkimagedata->GetDataDimension();
00854 unsigned int i, *tmpDimensions=new unsigned int[m_Dimension>4?m_Dimension:4];
00855 for(i=0;i<m_Dimension;++i) tmpDimensions[i]=vtkimagedata->GetDimensions()[i];
00856 if(m_Dimension<4)
00857 {
00858 unsigned int *p;
00859 for(i=0,p=tmpDimensions+m_Dimension;i<4-m_Dimension;++i, ++p)
00860 *p=1;
00861 }
00862
00863 if(sDim>=0)
00864 {
00865 tmpDimensions[2]=sDim;
00866 if(m_Dimension < 3)
00867 m_Dimension = 3;
00868 }
00869 if(tDim>=0)
00870 {
00871 tmpDimensions[3]=tDim;
00872 if(m_Dimension < 4)
00873 m_Dimension = 4;
00874 }
00875
00876 mitk::PixelType pixelType;
00877
00878 switch ( vtkimagedata->GetScalarType() )
00879 {
00880 case VTK_BIT:
00881 case VTK_CHAR:
00882 pixelType.Initialize(typeid(char), vtkimagedata->GetNumberOfScalarComponents());
00883 break;
00884 case VTK_UNSIGNED_CHAR:
00885 pixelType.Initialize(typeid(unsigned char), vtkimagedata->GetNumberOfScalarComponents());
00886 break;
00887 case VTK_SHORT:
00888 pixelType.Initialize(typeid(short), vtkimagedata->GetNumberOfScalarComponents());
00889 break;
00890 case VTK_UNSIGNED_SHORT:
00891 pixelType.Initialize(typeid(unsigned short), vtkimagedata->GetNumberOfScalarComponents());
00892 break;
00893 case VTK_INT:
00894 pixelType.Initialize(typeid(int), vtkimagedata->GetNumberOfScalarComponents());
00895 break;
00896 case VTK_UNSIGNED_INT:
00897 pixelType.Initialize(typeid(unsigned int), vtkimagedata->GetNumberOfScalarComponents());
00898 break;
00899 case VTK_LONG:
00900 pixelType.Initialize(typeid(long), vtkimagedata->GetNumberOfScalarComponents());
00901 break;
00902 case VTK_UNSIGNED_LONG:
00903 pixelType.Initialize(typeid(unsigned long), vtkimagedata->GetNumberOfScalarComponents());
00904 break;
00905 case VTK_FLOAT:
00906 pixelType.Initialize(typeid(float), vtkimagedata->GetNumberOfScalarComponents());
00907 break;
00908 case VTK_DOUBLE:
00909 pixelType.Initialize(typeid(double), vtkimagedata->GetNumberOfScalarComponents());
00910 break;
00911 default:
00912 break;
00913 }
00914 Initialize(pixelType,
00915 m_Dimension,
00916 tmpDimensions,
00917 channels);
00918
00919 #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) ))
00920 const double *spacinglist = vtkimagedata->GetSpacing();
00921 #else
00922 const float *spacinglist = vtkimagedata->GetSpacing();
00923 #endif
00924 Vector3D spacing;
00925 FillVector3D(spacing, spacinglist[0], 1.0, 1.0);
00926 if(m_Dimension>=2)
00927 spacing[1]=spacinglist[1];
00928 if(m_Dimension>=3)
00929 spacing[2]=spacinglist[2];
00930
00931
00932 Point3D origin;
00933 vtkFloatingPointType vtkorigin[3];
00934 vtkimagedata->GetOrigin(vtkorigin);
00935 FillVector3D(origin, vtkorigin[0], 0.0, 0.0);
00936 if(m_Dimension>=2)
00937 origin[1]=vtkorigin[1];
00938 if(m_Dimension>=3)
00939 origin[2]=vtkorigin[2];
00940
00941 SlicedGeometry3D* slicedGeometry = GetSlicedGeometry(0);
00942
00943
00944 PlaneGeometry* planeGeometry = static_cast<PlaneGeometry*>(slicedGeometry->GetGeometry2D(0));
00945 planeGeometry->SetOrigin(origin);
00946
00947
00948 slicedGeometry->SetOrigin(origin);
00949 slicedGeometry->SetSpacing(spacing);
00950 GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, m_Dimensions[3]);
00951
00952 delete [] tmpDimensions;
00953 }
00954
00955 void mitk::Image::Initialize(const mitkIpPicDescriptor* pic, int channels, int tDim, int sDim)
00956 {
00957 if(pic==NULL) return;
00958
00959 Clear();
00960
00961 m_Dimension=pic->dim;
00962
00963 m_Dimensions=new unsigned int[m_Dimension>4?m_Dimension:4];
00964 std::memcpy(m_Dimensions, pic->n, sizeof(unsigned int)*m_Dimension);
00965 if(m_Dimension<4)
00966 {
00967 unsigned int i, *p;
00968 for(i=0,p=m_Dimensions+m_Dimension;i<4-m_Dimension;++i, ++p)
00969 *p=1;
00970 }
00971
00972 if(sDim>=0)
00973 {
00974 m_Dimensions[2]=sDim;
00975 if(m_Dimension < 3)
00976 m_Dimension = 3;
00977 }
00978 if(tDim>=0)
00979 {
00980 m_Dimensions[3]=tDim;
00981 if(m_Dimension < 4)
00982 m_Dimension = 4;
00983 }
00984
00985 unsigned int i;
00986 for(i=0;i<4;++i)
00987 {
00988 m_LargestPossibleRegion.SetIndex(i, 0);
00989 m_LargestPossibleRegion.SetSize (i, m_Dimensions[i]);
00990 }
00991 m_LargestPossibleRegion.SetIndex(i, 0);
00992 m_LargestPossibleRegion.SetSize(i, channels);
00993
00994 m_PixelType=PixelType(pic);
00995 SlicedGeometry3D::Pointer slicedGeometry = SlicedGeometry3D::New();
00996 PicHelper::InitializeEvenlySpaced(pic, m_Dimensions[2], slicedGeometry);
00997
00998 TimeSlicedGeometry::Pointer timeSliceGeometry = TimeSlicedGeometry::New();
00999 timeSliceGeometry->InitializeEvenlyTimed(slicedGeometry, m_Dimensions[3]);
01000
01001 SetGeometry(timeSliceGeometry);
01002
01003 ImageDataItemPointer dnull=NULL;
01004
01005 m_Channels.assign(GetNumberOfChannels(), dnull);
01006
01007 m_Volumes.assign(GetNumberOfChannels()*m_Dimensions[3], dnull);
01008
01009 m_Slices.assign(GetNumberOfChannels()*m_Dimensions[3]*m_Dimensions[2], dnull);
01010
01011 ComputeOffsetTable();
01012
01013 Initialize();
01014
01015 m_Initialized = true;
01016 }
01017
01018 bool mitk::Image::IsValidSlice(int s, int t, int n) const
01019 {
01020 if(m_Initialized)
01021 return ((s>=0) && (s<(int)m_Dimensions[2]) && (t>=0) && (t< (int) m_Dimensions[3]) && (n>=0) && (n< (int)GetNumberOfChannels()));
01022 else
01023 return false;
01024 }
01025
01026 bool mitk::Image::IsValidVolume(int t, int n) const
01027 {
01028 if(m_Initialized)
01029 return IsValidSlice(0, t, n);
01030 else
01031 return false;
01032 }
01033
01034 bool mitk::Image::IsValidChannel(int n) const
01035 {
01036 if(m_Initialized)
01037 return IsValidSlice(0, 0, n);
01038 else
01039 return false;
01040 }
01041
01042 void mitk::Image::ComputeOffsetTable()
01043 {
01044 if(m_OffsetTable!=NULL)
01045 delete [] m_OffsetTable;
01046
01047 m_OffsetTable=new size_t[m_Dimension>4 ? m_Dimension+1 : 4+1];
01048
01049 unsigned int i;
01050 size_t num=1;
01051 m_OffsetTable[0] = 1;
01052 for (i=0; i < m_Dimension; ++i)
01053 {
01054 num *= m_Dimensions[i];
01055 m_OffsetTable[i+1] = num;
01056 }
01057 for (;i < 4; ++i)
01058 m_OffsetTable[i+1] = num;
01059 }
01060
01061 int mitk::Image::GetSliceIndex(int s, int t, int n) const
01062 {
01063 if(IsValidSlice(s,t,n)==false) return false;
01064 return ((size_t)s)+((size_t) t)*m_Dimensions[2]+((size_t) n)*m_Dimensions[3]*m_Dimensions[2];
01065 }
01066
01067 int mitk::Image::GetVolumeIndex(int t, int n) const
01068 {
01069 if(IsValidVolume(t,n)==false) return false;
01070 return ((size_t)t)+((size_t) n)*m_Dimensions[3];
01071 }
01072
01073 mitk::Image::ImageDataItemPointer mitk::Image::AllocateSliceData(int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement)
01074 {
01075 int pos;
01076 pos=GetSliceIndex(s,t,n);
01077
01078
01079 ImageDataItemPointer sl, ch, vol;
01080 vol=m_Volumes[GetVolumeIndex(t,n)];
01081 if(vol.GetPointer()!=NULL)
01082 {
01083 sl=new ImageDataItem(*vol, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(m_PixelType.GetBpe()/8));
01084 sl->SetComplete(true);
01085 return m_Slices[pos]=sl;
01086 }
01087
01088
01089 ch=m_Channels[n];
01090 if(ch.GetPointer()!=NULL)
01091 {
01092 sl=new ImageDataItem(*ch, 2, data, importMemoryManagement == ManageMemory, (((size_t) s)*m_OffsetTable[2]+((size_t) t)*m_OffsetTable[3])*(m_PixelType.GetBpe()/8));
01093 sl->SetComplete(true);
01094 return m_Slices[pos]=sl;
01095 }
01096
01097
01098 m_Volumes[GetVolumeIndex(t,n)]=vol=AllocateVolumeData(t,n,NULL,importMemoryManagement);
01099 sl=new ImageDataItem(*vol, 2, data, importMemoryManagement == ManageMemory, ((size_t) s)*m_OffsetTable[2]*(m_PixelType.GetBpe()/8));
01100 sl->SetComplete(true);
01101 return m_Slices[pos]=sl;
01102
01105
01106
01107
01108 }
01109
01110 mitk::Image::ImageDataItemPointer mitk::Image::AllocateVolumeData(int t, int n, void *data, ImportMemoryManagementType importMemoryManagement)
01111 {
01112 int pos;
01113 pos=GetVolumeIndex(t,n);
01114
01115
01116 ImageDataItemPointer ch, vol;
01117 ch=m_Channels[n];
01118 if(ch.GetPointer()!=NULL)
01119 {
01120 vol=new ImageDataItem(*ch, 3, data, importMemoryManagement == ManageMemory, (((size_t) t)*m_OffsetTable[3])*(m_PixelType.GetBpe()/8));
01121 return m_Volumes[pos]=vol;
01122 }
01123
01124
01125 if(importMemoryManagement == CopyMemory)
01126 {
01127 vol=new ImageDataItem(m_PixelType, 3, m_Dimensions, NULL, true);
01128 if(data != NULL)
01129 std::memcpy(vol->GetData(), data, m_OffsetTable[3]*(m_PixelType.GetBpe()/8));
01130 }
01131 else
01132 {
01133 vol=new ImageDataItem(m_PixelType, 3, m_Dimensions, data, importMemoryManagement == ManageMemory);
01134 }
01135 m_Volumes[pos]=vol;
01136 return vol;
01137 }
01138
01139 mitk::Image::ImageDataItemPointer mitk::Image::AllocateChannelData(int n, void *data, ImportMemoryManagementType importMemoryManagement)
01140 {
01141 ImageDataItemPointer ch;
01142
01143 if(importMemoryManagement == CopyMemory)
01144 {
01145 ch=new ImageDataItem(m_PixelType, m_Dimension, m_Dimensions, NULL, true);
01146 if(data != NULL)
01147 std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(m_PixelType.GetBpe()/8));
01148 }
01149 else
01150 {
01151 ch=new ImageDataItem(m_PixelType, m_Dimension, m_Dimensions, data, importMemoryManagement == ManageMemory);
01152 }
01153 m_Channels[n]=ch;
01154 return ch;
01155 }
01156
01157 unsigned int* mitk::Image::GetDimensions() const
01158 {
01159 return m_Dimensions;
01160 }
01161
01162 void mitk::Image::Clear()
01163 {
01164 Superclass::Clear();
01165 delete [] m_Dimensions;
01166 m_Dimensions = NULL;
01167 }
01168
01169 void mitk::Image::SetGeometry(Geometry3D* aGeometry3D)
01170 {
01171 Superclass::SetGeometry(aGeometry3D);
01172 GetTimeSlicedGeometry()->ImageGeometryOn();
01173 }
01174
01175 const mitk::Image::HistogramType* mitk::Image::GetScalarHistogram(int t) const
01176 {
01177 mitk::ImageTimeSelector* timeSelector = this->GetTimeSelector();
01178 if(timeSelector!=NULL)
01179 {
01180 timeSelector->SetTimeNr(t);
01181 timeSelector->UpdateLargestPossibleRegion();
01182
01183 mitk::HistogramGenerator* generator = static_cast<mitk::HistogramGenerator*>(m_HistogramGeneratorObject.GetPointer());
01184 generator->SetImage(timeSelector->GetOutput());
01185 generator->ComputeHistogram();
01186 return static_cast<const mitk::Image::HistogramType*>(generator->GetHistogram());
01187 }
01188 return NULL;
01189 }
01190
01191 #include "mitkImageAccessByItk.h"
01192
01193
01194
01195 template < typename ItkImageType >
01196 void mitk::_ComputeExtremaInItkImage(ItkImageType* itkImage, mitk::Image* mitkImage, int t)
01197 {
01198 typename ItkImageType::RegionType region;
01199 region = itkImage->GetBufferedRegion();
01200 if(region.Crop(itkImage->GetRequestedRegion()) == false) return;
01201 if(region != itkImage->GetRequestedRegion()) return;
01202
01203 itk::ImageRegionConstIterator<ItkImageType> it(itkImage, region);
01204 typedef typename ItkImageType::PixelType TPixel;
01205 TPixel value = 0;
01206
01207 if ( !mitkImage || !mitkImage->IsValidTimeStep( t ) ) return;
01208 mitkImage->Expand(t+1);
01209 mitkImage->m_CountOfMinValuedVoxels[t] = 0;
01210 mitkImage->m_CountOfMaxValuedVoxels[t] = 0;
01211
01212 mitkImage->m_Scalar2ndMin[t]=
01213 mitkImage->m_ScalarMin[t] = itk::NumericTraits<ScalarType>::max();
01214 mitkImage->m_Scalar2ndMax[t]=
01215 mitkImage->m_ScalarMax[t] = itk::NumericTraits<ScalarType>::NonpositiveMin();
01216
01217 while( !it.IsAtEnd() )
01218 {
01219 value = it.Get();
01220
01221
01222
01223
01224
01225
01226 #ifdef BOUNDINGOBJECT_IGNORE
01227 if( value > -32765)
01228 {
01229 #endif
01230
01231 if ( value < mitkImage->m_ScalarMin[t] )
01232 {
01233 mitkImage->m_Scalar2ndMin[t] = mitkImage->m_ScalarMin[t]; mitkImage->m_ScalarMin[t] = value;
01234 mitkImage->m_CountOfMinValuedVoxels[t] = 1;
01235 }
01236 else if ( value == mitkImage->m_ScalarMin[t] )
01237 {
01238 ++mitkImage->m_CountOfMinValuedVoxels[t];
01239 }
01240 else if ( value < mitkImage->m_Scalar2ndMin[t] )
01241 {
01242 mitkImage->m_Scalar2ndMin[t] = value;
01243 }
01244
01245
01246 if ( value > mitkImage->m_ScalarMax[t] )
01247 {
01248 mitkImage->m_Scalar2ndMax[t] = mitkImage->m_ScalarMax[t]; mitkImage->m_ScalarMax[t] = value;
01249 mitkImage->m_CountOfMaxValuedVoxels[t] = 1;
01250 }
01251 else if ( value == mitkImage->m_ScalarMax[t] )
01252 {
01253 ++mitkImage->m_CountOfMaxValuedVoxels[t];
01254 }
01255 else if ( value > mitkImage->m_Scalar2ndMax[t] )
01256 {
01257 mitkImage->m_Scalar2ndMax[t] = value;
01258 }
01259 #ifdef BOUNDINGOBJECT_IGNORE
01260 }
01261 #endif
01262
01263 ++it;
01264 }
01265
01267 if (mitkImage->m_ScalarMax[t] == mitkImage->m_ScalarMin[t])
01268 {
01269 mitkImage->m_Scalar2ndMax[t] = mitkImage->m_Scalar2ndMin[t] = mitkImage->m_ScalarMax[t];
01270 }
01271 mitkImage->m_LastRecomputeTimeStamp.Modified();
01272
01273 }
01274
01275 bool mitk::Image::IsValidTimeStep(int t) const
01276 {
01277 return ( ( m_Dimension >= 4 && t <= (int)m_Dimensions[3] && t > 0 ) || (t == 0) );
01278 }
01279
01280 void mitk::Image::Expand( int timeSteps ) const
01281 {
01282 if(timeSteps < 1) itkExceptionMacro(<< "Invalid timestep in Image!");
01283 if(! IsValidTimeStep( timeSteps-1 ) ) return;
01284 if(timeSteps > (int)m_ScalarMin.size() )
01285 {
01286 m_ScalarMin.resize(timeSteps, itk::NumericTraits<ScalarType>::max());
01287 m_ScalarMax.resize(timeSteps, itk::NumericTraits<ScalarType>::NonpositiveMin());
01288 m_Scalar2ndMin.resize(timeSteps, itk::NumericTraits<ScalarType>::max());
01289 m_Scalar2ndMax.resize(timeSteps, itk::NumericTraits<ScalarType>::NonpositiveMin());
01290 m_CountOfMinValuedVoxels.resize(timeSteps, 0);
01291 m_CountOfMaxValuedVoxels.resize(timeSteps, 0);
01292 }
01293 }
01294
01295 void mitk::Image::ResetImageStatistics() const
01296 {
01297 m_ScalarMin.assign(1, itk::NumericTraits<ScalarType>::max());
01298 m_ScalarMax.assign(1, itk::NumericTraits<ScalarType>::NonpositiveMin());
01299 m_Scalar2ndMin.assign(1, itk::NumericTraits<ScalarType>::max());
01300 m_Scalar2ndMax.assign(1, itk::NumericTraits<ScalarType>::NonpositiveMin());
01301 m_CountOfMinValuedVoxels.assign(1, 0);
01302 m_CountOfMaxValuedVoxels.assign(1, 0);
01303 }
01304
01305 void mitk::Image::ComputeImageStatistics(int t) const
01306 {
01307
01308 if (!IsValidTimeStep(t)) return;
01309
01310
01311 if (this->GetMTime() > m_LastRecomputeTimeStamp.GetMTime())
01312 this->ResetImageStatistics();
01313
01314
01315 this->Expand(t+1);
01316
01317
01318 if( m_ScalarMin[t] != itk::NumericTraits<ScalarType>::max() ||
01319 m_Scalar2ndMin[t] != itk::NumericTraits<ScalarType>::max() ) return;
01320
01321 if(this->m_PixelType.GetNumberOfComponents() == 1)
01322 {
01323
01324 mitk::ImageTimeSelector* timeSelector = this->GetTimeSelector();
01325 if(timeSelector!=NULL)
01326 {
01327 timeSelector->SetTimeNr(t);
01328 timeSelector->UpdateLargestPossibleRegion();
01329 mitk::Image* image = timeSelector->GetOutput();
01330 mitk::Image* thisImage = const_cast<Image*>(this);
01331 AccessByItk_2( image, _ComputeExtremaInItkImage, thisImage, t );
01332 }
01333 }
01334 else if(this->m_PixelType.GetNumberOfComponents() > 1)
01335 {
01336 m_ScalarMin[t] = 0;
01337 m_ScalarMax[t] = 255;
01338 }
01339 }
01340
01341
01342 mitk::ScalarType mitk::Image::GetScalarValueMin(int t) const
01343 {
01344 ComputeImageStatistics(t);
01345 return m_ScalarMin[t];
01346 }
01347
01348 mitk::ScalarType mitk::Image::GetScalarValueMax(int t) const
01349 {
01350 ComputeImageStatistics(t);
01351 return m_ScalarMax[t];
01352 }
01353
01354 mitk::ScalarType mitk::Image::GetScalarValue2ndMin(int t) const
01355 {
01356 ComputeImageStatistics(t);
01357 return m_Scalar2ndMin[t];
01358 }
01359
01360 mitk::ScalarType mitk::Image::GetScalarValue2ndMax(int t) const
01361 {
01362 ComputeImageStatistics(t);
01363 return m_Scalar2ndMax[t];
01364 }
01365
01366 mitk::ScalarType mitk::Image::GetCountOfMinValuedVoxels(int t) const
01367 {
01368 ComputeImageStatistics(t);
01369 return m_CountOfMinValuedVoxels[t];
01370 }
01371
01372 mitk::ScalarType mitk::Image::GetCountOfMaxValuedVoxels(int t) const
01373 {
01374 ComputeImageStatistics(t);
01375 return m_CountOfMaxValuedVoxels[t];
01376 }
01377
01378 void mitk::Image::PrintSelf(std::ostream& os, itk::Indent indent) const
01379 {
01380 unsigned char i;
01381 if(m_Initialized)
01382 {
01383 os << indent << " PixelType: " << m_PixelType.GetTypeId()->name() << std::endl;
01384 os << indent << " BitsPerElement: " << m_PixelType.GetBpe() << std::endl;
01385 os << indent << " NumberOfComponents: " << m_PixelType.GetNumberOfComponents() << std::endl;
01386 os << indent << " BitsPerComponent: " << m_PixelType.GetBitsPerComponent() << std::endl;
01387 os << indent << " Dimension: " << m_Dimension << std::endl;
01388 os << indent << " Dimensions: ";
01389 for(i=0; i < m_Dimension; ++i)
01390 os << GetDimension(i) << " ";
01391 os << std::endl;
01392 }
01393 else
01394 {
01395 os << indent << " Image not initialized: m_Initialized: false" << std::endl;
01396 }
01397
01398 Superclass::PrintSelf(os,indent);
01399 }
01400
01401 bool mitk::Image::IsRotated() const
01402 {
01403 const mitk::Geometry3D* geo = this->GetGeometry();
01404 bool ret = false;
01405
01406 if(geo)
01407 {
01408 const vnl_matrix_fixed<float, 3, 3> & mx = geo->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
01409 float ref = 0;
01410 for(short k = 0; k < 3; ++k)
01411 ref += mx[k][k];
01412 ref/=1000;
01413
01414 for(short i = 0; i < 3; ++i)
01415 {
01416 for(short j = 0; j < 3; ++j)
01417 {
01418 if(i != j)
01419 {
01420 if(abs(mx[i][j]) > ref)
01421 ret = true;
01422 }
01423 }
01424 }
01425 }
01426 return ret;
01427 }