diff --git a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp index 97ceff6921..468b06872d 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.cpp @@ -1,204 +1,230 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkFiberBundleX.h" #include #include // baptize array names const char* mitk::FiberBundleX::COLORCODING_ORIENTATION_BASED = "Color_Orient"; const char* mitk::FiberBundleX::COLORCODING_FA_BASED = "Color_FA"; mitk::FiberBundleX::FiberBundleX() { } mitk::FiberBundleX::~FiberBundleX() { } /* === main input method ==== * set computed fibers from tractography algorithms */ void mitk::FiberBundleX::SetFibers(vtkSmartPointer fiberPD) { - m_OriginalFiberPolyData = fiberPD; + m_FiberStructureData = fiberPD; } /* === main output method === * return fiberbundle as vtkPolyData * Depending on processing of input fibers, this method returns * the latest processed fibers. */ vtkPolyData* mitk::FiberBundleX::GetFibers() { - vtkPolyData* returningFibers = m_FiberPolyData; - - if (returningFibers == NULL) { - returningFibers = m_OriginalFiberPolyData; - } - - return returningFibers; + return m_FiberStructureData; } -/* - * return original set of fiberdata - */ -vtkPolyData* mitk::FiberBundleX::GetOriginalFibers() -{ - return m_OriginalFiberPolyData; -} + /*============================================== *++++ PROCESSING WITH FIBER INFORMATION +++++++ =============================================*/ void mitk::FiberBundleX::DoColorCodingOrientationbased() { + //===== FOR WRITING A TEST ======================== + // colorT size == tupelComponents * tupelElements + // compare color results + // to cover this code 100% also polydata needed, where colorarray already exists + // + one fiber with exactly 1 point + // + one fiber with 0 points + //================================================= + /* === decide which polydata to choose === - * usually you call this method when u received fresh fibers from an tracking algorithm. - * In this case the variable m_OriginalFiberPolyData will act as source for creating color - * information for each point. However, if u process on fibers and forgot calling colorcoding - * before calling any other method (e.g. linesmoothing), then - for performance reason - it makes - * sense not to process on the "original" pointset, but on the smoothed one (well, this might lack - * in performance anyway ;-) ). - * - * It might occur that u call this method again - u must be drunk then - but this algorithm takes - * care of ur incapability by checking if there already exists a color array for orientation based - * color information + ** ALL REDESIGNED */ - //these variables are needed for some intelligence in handling colorarrays and already smoothed structures - //both vars are sensing the "colorful" part of fiberbundles ;-) -// bool hasSmoothedFibColors = true; - bool hasOriginalFibColors = true; - bool hasSmoothedFibColors = false; - - //check if color array in original fiber dataset is valid - if ( m_OriginalFiberPolyData != NULL ) + bool hasFiberDataColor = false; + + // check if color array in original fiber dataset is valid + if ( m_FiberStructureData != NULL ) { - if ( m_OriginalFiberPolyData->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED) ) + if ( m_FiberStructureData->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED) && + m_FiberStructureData->GetNumberOfPoints() == + m_FiberStructureData->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)->GetNumberOfTuples() ) { - // validate input, number of items must match number of points - if ( m_OriginalFiberPolyData->GetNumberOfPoints() != - m_OriginalFiberPolyData->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)->GetNumberOfTuples() ) - { - //invalid color array, try to heal - MITK_INFO << "NUMBER OF POINTS DOES NOT MATCH COLOR INFORMATION in m_OriginalFiberPolyData, ARRAY: " << COLORCODING_ORIENTATION_BASED; - hasOriginalFibColors = doSelfHealingColorOrient(m_OriginalFiberPolyData); - - }//no else, cuz pointset matches color set :-) - - } else { - //so far no color array exists - hasOriginalFibColors = false; + hasFiberDataColor = true; } - } else { // else of check (m_OriginalFiberPolyData != NULL) + } else { MITK_INFO << "NO FIBERS FROM TRACTOGRAPHY PASSED TO mitkFiberBundleX yet!! no colorcoding can be processed!"; -// nothing to implement or return here because hasOriginalFibColors is set to true and the checking mechanism below will take care of this issue as well - } - - // make sure colorcoding in smoothed fibers are OK, otherwise do selfHealing - if (hasOriginalFibColors && - m_FiberPolyData.GetPointer() != NULL && - m_FiberPolyData->GetPointData()->HasArray(COLORCODING_ORIENTATION_BASED) && - (m_FiberPolyData->GetNumberOfPoints() != m_FiberPolyData->GetPointData()->GetArray(COLORCODING_ORIENTATION_BASED)->GetNumberOfTuples()) ) - { - hasSmoothedFibColors = doSelfHealingColorOrient(m_FiberPolyData); + hasFiberDataColor = true; // "true" will return later on } - -// make sure that processing colorcoding is only called when necessary - if (hasOriginalFibColors) - return; - if (hasOriginalFibColors && hasSmoothedFibColors) + /* make sure that processing colorcoding is only called when necessary */ + if (hasFiberDataColor) return; - + /* Finally, execute color calculation */ + vtkPoints* extrPoints = m_FiberStructureData->GetPoints(); + int numOfPoints = extrPoints->GetNumberOfPoints(); + //colors and alpha value for each single point, RGBA = 4 components + unsigned char rgba[4] = {0,0,0,0}; + int componentSize = sizeof(rgba); + vtkUnsignedCharArray *colorsT = vtkUnsignedCharArray::New(); - colorsT->SetNumberOfComponents(4); + colorsT->Allocate(numOfPoints * componentSize); + colorsT->SetNumberOfComponents(componentSize); colorsT->SetName(COLORCODING_ORIENTATION_BASED); - //colorcoding orientation based - unsigned char rgba[4] = {0,0,0,0}; - - int i=0; - if (iGetPoints()->GetNumberOfPoints()-1 && i>0) - {// process all points except starting and endpoint + /* catch case: fiber consists of only 1 point */ + if (numOfPoints > 1) + { - } else if (i==0) { - // process startingpoint + for (int i=0; i 0) + { + /* The color value of the current point is influenced by the previous point and next point. */ + vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(i)[0], extrPoints->GetPoint(i)[1],extrPoints->GetPoint(i)[2]); + vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(i+1)[0], extrPoints->GetPoint(i+1)[1], extrPoints->GetPoint(i+1)[2]); + vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(i-1)[0], extrPoints->GetPoint(i-1)[1], extrPoints->GetPoint(i-1)[2]); + + vnl_vector_fixed< double, 3 > diff1; + diff1 = currentPntvtk - nextPntvtk; + diff1.normalize(); + + vnl_vector_fixed< double, 3 > diff2; + diff2 = currentPntvtk - prevPntvtk; + diff2.normalize(); + + vnl_vector_fixed< double, 3 > diff; + diff = (diff1 - diff2) / 2.0; + + rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); + rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); + rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); + rgba[3] = (unsigned char) (255.0); + + + } else if (i==0) { + /* First point has no previous point, therefore only diff1 is taken */ + + vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(i)[0], extrPoints->GetPoint(i)[1],extrPoints->GetPoint(i)[2]); + vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(i+1)[0], extrPoints->GetPoint(i+1)[1], extrPoints->GetPoint(i+1)[2]); + + vnl_vector_fixed< double, 3 > diff1; + diff1 = currentPntvtk - nextPntvtk; + diff1.normalize(); + + rgba[0] = (unsigned char) (255.0 * std::abs(diff1[0])); + rgba[1] = (unsigned char) (255.0 * std::abs(diff1[1])); + rgba[2] = (unsigned char) (255.0 * std::abs(diff1[2])); + rgba[3] = (unsigned char) (255.0); + + } else if (i==numOfPoints-1) { + /* Last point has no next point, therefore only diff2 is taken */ + vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(i)[0], extrPoints->GetPoint(i)[1],extrPoints->GetPoint(i)[2]); + vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(i-1)[0], extrPoints->GetPoint(i-1)[1], extrPoints->GetPoint(i-1)[2]); + + vnl_vector_fixed< double, 3 > diff2; + diff2 = currentPntvtk - prevPntvtk; + diff2.normalize(); + + rgba[0] = (unsigned char) (255.0 * std::abs(diff2[0])); + rgba[1] = (unsigned char) (255.0 * std::abs(diff2[1])); + rgba[2] = (unsigned char) (255.0 * std::abs(diff2[2])); + rgba[3] = (unsigned char) (255.0); + + } + + colorsT->InsertTupleValue(i, rgba); + } //end for loop - } else if (i==m_OriginalFiberPolyData->GetPoints()->GetNumberOfPoints()-1) { - // process endpoint + } else if (numOfPoints == 1) { + /* Fiber consists of 1 point only, color that point as you wish :) */ + colorsT->InsertTupleValue(0, rgba); + } else { + MITK_INFO << "Fiber with 0 points detected... please check your tractography algorithm!" ; } - - -} - -//private repairMechanism for orientationbased colorcoding -bool mitk::FiberBundleX::doSelfHealingColorOrient(vtkPolyData* healMe) -{ - bool hasHealingSucceeded = false; - MITK_INFO << "FiberBundleX self repair mechanism is called, but not yet implemented"; -// check type of healMe - if (healMe == m_FiberPolyData) - { - //todo - - } else if (healMe == m_OriginalFiberPolyData) - { - //todo + //mini test, shall be ported to MITK TESTINGS! + if (colorsT->GetSize() != numOfPoints*componentSize) { + MITK_INFO << "ALLOCATION ERROR IN INITIATING COLOR ARRAY"; } - return hasHealingSucceeded; } +////private repairMechanism for orientationbased colorcoding +//bool mitk::FiberBundleX::doSelfHealingColorOrient(vtkPolyData* healMe) +//{ +// bool hasHealingSucceeded = false; +// MITK_INFO << "FiberBundleX self repair mechanism is called, but not yet implemented"; +//// check type of healMe +// if (healMe == m_ImportedFiberData) +// { +// //todo +// } +// +// return hasHealingSucceeded; +//} + /* ESSENTIAL IMPLEMENTATION OF SUPERCLASS METHODS */ void mitk::FiberBundleX::UpdateOutputInformation() { } void mitk::FiberBundleX::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::FiberBundleX::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::FiberBundleX::VerifyRequestedRegion() { return true; } void mitk::FiberBundleX::SetRequestedRegion( itk::DataObject *data ) { } \ No newline at end of file diff --git a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h index 3a909fdfe3..481ac1f0e3 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundleX/mitkFiberBundleX.h @@ -1,107 +1,107 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision: 11989 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_FiberBundleX_H #define _MITK_FiberBundleX_H //includes for MITK datastructure #include "mitkBaseData.h" #include "MitkDiffusionImagingExports.h" //includes storing fiberdata #include //may be replaced by class precompile argument #include // may be replaced by class #include // my be replaced by class namespace mitk { /** * \brief Base Class for Fiber Bundles; */ class MitkDiffusionImaging_EXPORT FiberBundleX : public BaseData { public: // names of certain arrays (e.g colorcodings, etc.) static const char* COLORCODING_ORIENTATION_BASED; static const char* COLORCODING_FA_BASED; /* friend classes wanna access typedefs ContainerPointType, ContainerTractType, ContainerType */ friend class FiberBundleXWriter; friend class FiberBundleXReader; // ======virtual methods must have====== virtual void UpdateOutputInformation(); virtual void SetRequestedRegionToLargestPossibleRegion(); virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); virtual bool VerifyRequestedRegion(); virtual void SetRequestedRegion( itk::DataObject *data ); //======================================= mitkClassMacro( FiberBundleX, BaseData ); itkNewMacro( Self ); // import fiber result from tractography algorithms void SetFibers(vtkSmartPointer); // return original computed fibers ... actually there is no smartpointer needed because original fibers are passed from the tractography filter vtkPolyData* GetOriginalFibers(); // return processed fibers vtkPolyData* GetFibers(); // return vertex polydata vtkPolyData* GetVertices(); void DoColorCodingOrientationbased(); protected: FiberBundleX(); virtual ~FiberBundleX(); private: -// ====TODO==================================== - bool doSelfHealingColorOrient( vtkPolyData* ); -// ============================================ +//// ====TODO==================================== +// bool doSelfHealingColorOrient( vtkPolyData* ); +//// ============================================ // The following polydata variables are used for fiber- and pointbased representation of the tractography results. As VTK suggests, one vtkPolyData is used to manage vertices and the other for polylines. // FiberPolyData stores all brain fibers using polylines (in world coordinates) // this variable hosts the smoothed fiber data, this data we generate, therefore a smartpointer structure is recommended - vtkSmartPointer m_FiberPolyData; - +// vtkSmartPointer m_FiberPolyData; is depricated +// // this variable hosts the original fiber data, no smartpointer needed because who or whatever passes this data to FiberBundleX should use vtkSmartPointer structure - vtkPolyData* m_OriginalFiberPolyData; + vtkPolyData* m_FiberStructureData; // VertexPolyData stores all original points as vertices computed by tracking algorithms vtkSmartPointer m_VertexPolyData; }; } // namespace mitk #endif /* _MITK_FiberBundleX_H */