X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=common%2FclitkDicomRT_ROI.cxx;h=af8bee67a77a769e680c3ea892e91fd98e235a47;hb=ef03fc34db849c864b1ae7f50c8442e125834f84;hp=6096ddc761f05643fbe3e5e9c5b007da4af88ef4;hpb=b9db5886a4d8e50a6940d7ceea622de32cfb230a;p=clitk.git diff --git a/common/clitkDicomRT_ROI.cxx b/common/clitkDicomRT_ROI.cxx index 6096ddc..af8bee6 100644 --- a/common/clitkDicomRT_ROI.cxx +++ b/common/clitkDicomRT_ROI.cxx @@ -4,7 +4,7 @@ Authors belongs to: - University of LYON http://www.universite-lyon.fr/ - - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr This software is distributed WITHOUT ANY WARRANTY; without even @@ -20,18 +20,29 @@ #include "clitkDicomRT_ROI.h" #include #include +#include +#include +#include +#include + +#if GDCM_MAJOR_VERSION >= 2 +#include "gdcmAttribute.h" +#include "gdcmItem.h" +#endif //-------------------------------------------------------------------- clitk::DicomRT_ROI::DicomRT_ROI() { mName = "NoName"; mNumber = -1; + mImage = NULL; mColor.resize(3); mColor[0] = mColor[1] = mColor[2] = 0; mMeshIsUpToDate = false; mBackgroundValue = 0; mForegroundValue = 1; - mZDelta = 0; + SetDicomUptodateFlag(false); + mFilename = ""; } //-------------------------------------------------------------------- @@ -62,6 +73,14 @@ int clitk::DicomRT_ROI::GetROINumber() const //-------------------------------------------------------------------- +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI::SetROINumber(int number) +{ + mNumber = number; +} +//-------------------------------------------------------------------- + + //-------------------------------------------------------------------- const std::string & clitk::DicomRT_ROI::GetName() const { @@ -129,13 +148,82 @@ double clitk::DicomRT_ROI::GetForegroundValueLabelImage() const //-------------------------------------------------------------------- -void clitk::DicomRT_ROI::Read(std::map & rois, gdcm::SQItem * item) +#if GDCM_MAJOR_VERSION >= 2 +bool clitk::DicomRT_ROI::Read(gdcm::Item * itemInfo, gdcm::Item * itemContour) { + //FATAL("Error : compile vv with itk4 + external gdcm"); + // Keep dicom item + mItemInfo = itemInfo; + mItemContour = itemContour; + // DD(mItemInfo); + + // ROI number [Referenced ROI Number] + const gdcm::DataSet & nesteddsInfo = mItemInfo->GetNestedDataSet(); + gdcm::Attribute<0x3006,0x0022> roinumber; + roinumber.SetFromDataSet( nesteddsInfo ); + int nb1 = roinumber.GetValue(); + + // Check this is the same with the other item + const gdcm::DataSet & nestedds = mItemContour->GetNestedDataSet(); + gdcm::Attribute<0x3006,0x0084> referencedroinumber; + referencedroinumber.SetFromDataSet( nestedds ); + int nb2 = referencedroinumber.GetValue(); + + // Must never be different + if (nb1 != nb2) { + DD(nb2); + DD(nb1); + FATAL("nb1 must equal nb2" << std::endl); + } + mNumber = nb1; - // Change number if needed + // Retrieve ROI Name (in the info item) + gdcm::Attribute<0x3006,0x26> roiname; + roiname.SetFromDataSet( nesteddsInfo ); + mName = roiname.GetValue(); + // DD(mName); - // TODO + // ROI Color [ROI Display Color] + gdcm::Attribute<0x3006,0x002a> color = {}; + color.SetFromDataSet( nestedds ); + assert( color.GetNumberOfValues() == 3 ); + mColor[0] = color.GetValue(0); + mColor[1] = color.GetValue(1); + mColor[2] = color.GetValue(2); + // Read contours [Contour Sequence] + gdcm::Tag tcsq(0x3006,0x0040); + if( !nestedds.FindDataElement( tcsq ) ) + { + std::cerr << "Warning. Could not read contour for structure <" << mName << ">, number" << mNumber << " ? I ignore it" << std::endl; + SetDicomUptodateFlag(true); + return false; + } + const gdcm::DataElement& csq = nestedds.GetDataElement( tcsq ); + mContoursSequenceOfItems = csq.GetValueAsSQ(); + gdcm::SmartPointer & sqi2 = mContoursSequenceOfItems; + if( !sqi2 || !sqi2->GetNumberOfItems() ) + { + return false; + } + unsigned int nitems = sqi2->GetNumberOfItems(); + + for(unsigned int i = 0; i < nitems; ++i) + { + gdcm::Item & j = sqi2->GetItem(i+1); // Item start at #1 + DicomRT_Contour::Pointer c = DicomRT_Contour::New(); + c->SetTransformMatrix(mTransformMatrix); + bool b = c->Read(&j); + if (b) { + mListOfContours.push_back(c); + } + } + SetDicomUptodateFlag(true); + return true; +} +#else +void clitk::DicomRT_ROI::Read(std::map & rois, gdcm::SQItem * item) +{ // ROI number [Referenced ROI Number] mNumber = atoi(item->GetEntryValue(0x3006,0x0084).c_str()); @@ -147,31 +235,29 @@ void clitk::DicomRT_ROI::Read(std::map & rois, gdcm::SQItem * // Read contours [Contour Sequence] gdcm::SeqEntry * contours=item->GetSeqEntry(0x3006,0x0040); - bool contour_processed=false; - bool delta_computed=false; - double last_z=0; - for(gdcm::SQItem* j=contours->GetFirstSQItem(); j!=0; j=contours->GetNextSQItem()) { - DicomRT_Contour::Pointer c = DicomRT_Contour::New(); - bool b = c->Read(j); - if (b) { - mListOfContours.push_back(c); - if (contour_processed) { - double delta=c->GetZ() - last_z; - if (delta_computed) - assert(mZDelta == delta); - else - mZDelta = delta; - } else - contour_processed=true; - last_z=c->GetZ(); + if (contours) { + int i=0; + for(gdcm::SQItem* j=contours->GetFirstSQItem(); j!=0; j=contours->GetNextSQItem()) { + DicomRT_Contour::Pointer c = DicomRT_Contour::New(); + c->SetTransformMatrix(mTransformMatrix); + bool b = c->Read(j); + if (b) { + mListOfContours.push_back(c); + } + ++i; } } + else { + std::cerr << "Warning. Could not read contour for structure <" << mName << ">, number" << mNumber << " ? I ignore it" << std::endl; + } + SetDicomUptodateFlag(true); } +#endif //-------------------------------------------------------------------- //-------------------------------------------------------------------- -void clitk::DicomRT_ROI::SetImage(vvImage * image) +void clitk::DicomRT_ROI::SetImage(vvImage::Pointer image) { mImage = image; } @@ -182,37 +268,101 @@ void clitk::DicomRT_ROI::SetImage(vvImage * image) vtkPolyData * clitk::DicomRT_ROI::GetMesh() { if (!mMeshIsUpToDate) { - ComputeMesh(); + ComputeMeshFromContour(); } return mMesh; } +//-------------------------------------------------------------------- + + //-------------------------------------------------------------------- clitk::DicomRT_Contour * clitk::DicomRT_ROI::GetContour(int n) { return mListOfContours[n]; } +//-------------------------------------------------------------------- + //-------------------------------------------------------------------- -void clitk::DicomRT_ROI::ComputeMesh() +void clitk::DicomRT_ROI::ComputeMeshFromContour() { - vtkAppendPolyData * append = vtkAppendPolyData::New(); + vtkSmartPointer append = vtkSmartPointer::New(); for(unsigned int i=0; iAddInput(mListOfContours[i]->GetMesh()); +#if VTK_MAJOR_VERSION <= 5 + append->AddInput(mListOfContours[i]->GetMesh()); +#else + append->AddInputData(mListOfContours[i]->GetMesh()); +#endif } append->Update(); - mMesh = append->GetOutput(); + + mMesh = vtkSmartPointer::New(); + mMesh->DeepCopy(append->GetOutput()); mMeshIsUpToDate = true; } //-------------------------------------------------------------------- +#if GDCM_MAJOR_VERSION >= 2 //-------------------------------------------------------------------- -void clitk::DicomRT_ROI::SetFromBinaryImage(vvImage * image, int n, - std::string name, - std::vector color, - std::string filename) +void clitk::DicomRT_ROI::UpdateDicomItem() { + FATAL("Error : compile vv with itk4 + external gdcm"); + + if (GetDicomUptoDateFlag()) return; + DD("ROI::UpdateDicomItem"); + DD(GetName()); + + // From now, only some item can be modified + + // Set ROI Name 0x3006,0x26> + gdcm::Attribute<0x3006,0x26> roiname; + roiname.SetValue(GetName()); + gdcm::DataElement de = roiname.GetAsDataElement(); + gdcm::DataSet & ds = mItemInfo->GetNestedDataSet(); + ds.Replace(de); + + // From MESH to CONTOURS + ComputeContoursFromImage(); + + // Update contours + DD(mListOfContours.size()); + for(uint i=0; iUpdateDicomItem();//mItemContour); + } + + // Nb of contours + unsigned int nitems = mContoursSequenceOfItems->GetNumberOfItems(); + DD(nitems); + + // Write [Contour Sequence] = 0x3006,0x0040) + gdcm::DataSet & dsc = mItemContour->GetNestedDataSet(); + gdcm::Tag tcsq(0x3006,0x0040); + const gdcm::DataElement& csq = dsc.GetDataElement( tcsq ); + gdcm::DataElement dec(csq); + dec.SetValue(*mContoursSequenceOfItems); + dsc.Replace(dec); + + gdcm::DataSet & a = mContoursSequenceOfItems->GetItem(1).GetNestedDataSet(); + gdcm::Attribute<0x3006,0x0050> at; + gdcm::Tag tcontourdata(0x3006,0x0050); + gdcm::DataElement contourdata = a.GetDataElement( tcontourdata ); + at.SetFromDataElement( contourdata ); + const double* points = at.GetValues(); + DD(points[0]); + +} +//-------------------------------------------------------------------- +#endif +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI::SetFromBinaryImage(vvImage::Pointer image, int n, + std::string name, + std::vector color, + std::string filename) +{ // ROI number [Referenced ROI Number] mNumber = n; @@ -238,3 +388,152 @@ vvImage * clitk::DicomRT_ROI::GetImage() const return mImage; } //-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI::SetTransformMatrix(vtkMatrix4x4* matrix) +{ + mTransformMatrix = matrix; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI::ComputeContoursFromImage() +{ + FATAL("ComputeContoursFromImage should not be call. To be replace"); + DD("ComputeMeshFromImage"); + + // Check that an image is loaded + if (!mImage) return; + + // Only consider 3D here + if (mImage->GetNumberOfDimensions() != 3) { + FATAL("DicomRT_ROI::ComputeMeshFromImage only work with 3D images"); + } + + // Get the VTK image + vtkImageData * image = mImage->GetVTKImages()[0]; + + // Get initial extend for the clipping + vtkSmartPointer clipper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 + clipper->SetInput(image); +#else + clipper->SetInputData(image); +#endif + + int* extent = image->GetExtent(); + DDV(extent, 6); + // std::vector extend; + + + // Loop on slice + uint n = image->GetDimensions()[2]; + DD(n); + DD(mListOfContours.size()); + mListOfContours.resize(n); /// ???FIXME + DD(mListOfContours.size()); + std::vector > contours; + for(uint i=0; i squares = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 + squares->SetInput(image); +#else + squares->SetInputData(image); +#endif + squares->SetImageRange(extent[0], extent[1], extent[2], extent[3], i, i); + squares->SetValue(1, 1.0); + squares->Update(); + DD(squares->GetNumberOfContours()); + + //clitk::DicomRT_Contour * contour = new clitk::DicomRT_Contour(); + //mListOfContours[i]->SetMesh(squares->GetOutput()); + + + vtkSmartPointer m = squares->GetOutput(); + contours.push_back(m); + + /* + // Clip to the current slice + extent[4] = extent[5] = image->GetOrigin()[2]+i*image->GetSpacing()[2]; + DDV(extent, 6); + // Prepare the marching squares + vtkSmartPointer squares = vtkSmartPointer::New(); + clipper->SetOutputWholeExtent(extent[0],extent[1],extent[2], + extent[3],extent[4],extent[5]); + + squares->SetInput(clipper->GetOutput()); + squares->Update(); + DD(squares->GetNumberOfContours()); + mListOfContours[i]->SetMesh(squares->GetOutput()); + */ + } + DD("done"); + + vtkSmartPointer append = vtkSmartPointer::New(); + for(unsigned int i=0; iAddInput(contours[i]); +#else + append->AddInputData(contours[i]); +#endif + } + append->Update(); + + mMesh = vtkSmartPointer::New(); + mMesh->DeepCopy(append->GetOutput()); + + // Write vtk + vtkPolyDataWriter * w = vtkPolyDataWriter::New(); +#if VTK_MAJOR_VERSION <= 5 + w->SetInput(mMesh); +#else + w->SetInputData(mMesh); +#endif + w->SetFileName("toto.vtk"); + w->Write(); + + DD("done"); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +#if CLITK_USE_SYSTEM_GDCM == 1 +void clitk::DicomRT_ROI::Read(vtkSmartPointer & reader, int roiindex) +{ + vtkRTStructSetProperties * p = reader->GetRTStructSetProperties(); + + mName = p->GetStructureSetROIName(roiindex); + mNumber = p->GetStructureSetROINumber(roiindex); + + //mColor = //FIXME !! + + // gdcm::Attribute<0x3006,0x002a> color = {}; + + // const gdcm::DataSet & nestedds = mItemContour->GetNestedDataSet(); + // color.SetFromDataSet( nestedds ); + // assert( color.GetNumberOfValues() == 3 ); + // mColor[0] = color.GetValue(0); + // mColor[1] = color.GetValue(1); + // mColor[2] = color.GetValue(2); + + + SetDicomUptodateFlag(true); + // Get the contour + mMesh = reader->GetOutput(roiindex); + DicomRT_Contour::Pointer c = DicomRT_Contour::New(); + c->SetTransformMatrix(mTransformMatrix); + c->SetMesh(mMesh); // FIXME no GetZ, not GetPoints + mMeshIsUpToDate = true; + mListOfContours.push_back(c); +} +#endif +//-------------------------------------------------------------------- +