diff --git a/Modules/FiberTracking/Algorithms/mitkTractometry.cpp b/Modules/FiberTracking/Algorithms/mitkTractometry.cpp new file mode 100644 index 0000000..fa437e6 --- /dev/null +++ b/Modules/FiberTracking/Algorithms/mitkTractometry.cpp @@ -0,0 +1,273 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center. + +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ +#include "mitkTractometry.h" + +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include + +namespace mitk{ + +bool Tractometry::Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer< vtkPolyData > ref_poly) +{ + double d_direct = 0; + double d_flipped = 0; + + vtkCell* cell1 = polydata1->GetCell(0); + if (ref_poly!=nullptr) + cell1 = ref_poly->GetCell(0); + auto numPoints1 = cell1->GetNumberOfPoints(); + vtkPoints* points1 = cell1->GetPoints(); + + std::vector> ref_points; + for (int j=0; jGetPoint(j); + itk::Point itk_p; + itk_p[0] = p1[0]; + itk_p[1] = p1[1]; + itk_p[2] = p1[2]; + ref_points.push_back(itk_p); + } + + vtkCell* cell2 = polydata1->GetCell(i); + vtkPoints* points2 = cell2->GetPoints(); + + for (int j=0; jGetPoint(j); + d_direct += (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + (p1[2]-p2[2])*(p1[2]-p2[2]); + + double* p3 = points2->GetPoint(numPoints1-j-1); + d_flipped += (p1[0]-p3[0])*(p1[0]-p3[0]) + (p1[1]-p3[1])*(p1[1]-p3[1]) + (p1[2]-p3[2])*(p1[2]-p3[2]); + } + + if (d_direct>d_flipped) + return true; + return false; +} + + +void Tractometry::ResampleIfNecessary(mitk::FiberBundle::Pointer fib, unsigned int num_points) +{ + auto poly = fib->GetFiberPolyData(); + bool resample = false; + for (int i=0; iGetNumberOfCells(); i++) + { + vtkCell* cell = poly->GetCell(i); + if (cell->GetNumberOfPoints()!=num_points) + { + resample = true; + MITK_INFO << "Resampling required!"; + break; + } + } + + if (resample) + fib->ResampleToNumPoints(num_points); +} + + +std::vector> Tractometry::NearestCentroidPointTractometry(itk::Image::Pointer itkImage, mitk::FiberBundle::Pointer working_fib, unsigned int num_points, unsigned int max_centroids, float cluster_size, mitk::FiberBundle::Pointer ref_fib) +{ + vtkSmartPointer< vtkPolyData > polydata = working_fib->GetFiberPolyData(); + vtkSmartPointer< vtkPolyData > ref_polydata = nullptr; + if (ref_fib!=nullptr) + { + ResampleIfNecessary(ref_fib, num_points); + ref_polydata = ref_fib->GetFiberPolyData(); + } + + auto interpolator = itk::LinearInterpolateImageFunction< itk::Image, float >::New(); + interpolator->SetInputImage(itkImage); + + mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); + lookupTable->SetType(mitk::LookupTable::MULTILABEL); + + std::vector> output_temp; + for(unsigned int i=0; i metrics; + metrics.push_back({new mitk::ClusteringMetricEuclideanStd()}); + + mitk::FiberBundle::Pointer resampled = working_fib->GetDeepCopy(); + ResampleIfNecessary(resampled, num_points); + + std::vector centroids; + std::shared_ptr< mitk::TractClusteringFilter > clusterer = std::make_shared(); + int c=0; + while (c<30 && (centroids.empty() || centroids.size()>max_centroids)) + { + float cs = cluster_size + cluster_size*c*0.2; + float max_d = 0; + int i=1; + std::vector< float > distances; + while (max_d < resampled->GetGeometry()->GetDiagonalLength()/2) + { + distances.push_back(cs*i); + max_d = cs*i; + ++i; + } + + clusterer->SetDistances(distances); + clusterer->SetTractogram(resampled); + clusterer->SetMetrics(metrics); + clusterer->SetMergeDuplicateThreshold(cs); + clusterer->SetDoResampling(false); + clusterer->SetNumPoints(num_points); + if (c==29) + clusterer->SetMaxClusters(max_centroids); + clusterer->SetMinClusterSize(1); + clusterer->Update(); + centroids = clusterer->GetOutCentroids(); + ++c; + } + + for (unsigned int i=0; iGetNumFibers(); ++i) + { + vtkCell* cell = polydata->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vnl_vector values; values.set_size(numPoints); + + for (int j=0; jGetPoint(j); + + int min_bin = 0; + float d=999999; + for (auto centroid : centroids) + { + auto centroid_polydata = centroid->GetFiberPolyData(); + + vtkCell* centroid_cell = centroid_polydata->GetCell(0); + auto centroid_numPoints = centroid_cell->GetNumberOfPoints(); + vtkPoints* centroid_points = centroid_cell->GetPoints(); + + bool centroid_flip = Flip(centroid_polydata, 0, ref_polydata); + + for (int bin=0; binGetPoint(bin); + float temp_d = std::sqrt((p[0]-centroid_p[0])*(p[0]-centroid_p[0]) + (p[1]-centroid_p[1])*(p[1]-centroid_p[1]) + (p[2]-centroid_p[2])*(p[2]-centroid_p[2])); + if (temp_dGetColor(min_bin+1, rgb); + working_fib->ColorSinglePoint(i, j, rgb); + + double pixelValue = mitk::imv::GetImageValue(mitk::imv::GetItkPoint(p), true, interpolator); + output_temp.at(min_bin).push_back(pixelValue); + } + } + + std::vector> output; + for (auto row_v : output_temp) + { + vnl_vector row; row.set_size(row_v.size()); + int i = 0; + for (auto v : row_v) + { + row.put(i, v); + ++i; + } + output.push_back(row); + } + + return output; +} + +vnl_matrix Tractometry::StaticResamplingTractometry(itk::Image::Pointer itkImage, mitk::FiberBundle::Pointer working_fib, unsigned int num_points, mitk::FiberBundle::Pointer ref_fib) +{ + + ResampleIfNecessary(working_fib, num_points); + vtkSmartPointer< vtkPolyData > polydata = working_fib->GetFiberPolyData(); + vtkSmartPointer< vtkPolyData > ref_polydata = nullptr; + if (ref_fib!=nullptr) + { + ResampleIfNecessary(ref_fib, num_points); + ref_polydata = ref_fib->GetFiberPolyData(); + } + + auto interpolator = itk::LinearInterpolateImageFunction< itk::Image, float >::New(); + interpolator->SetInputImage(itkImage); + + mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); + lookupTable->SetType(mitk::LookupTable::MULTILABEL); + + vnl_matrix output; output.set_size(num_points, working_fib->GetNumFibers()); + output.fill(0.0); + + for (unsigned int i=0; iGetNumFibers(); ++i) + { + vtkCell* cell = polydata->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + bool flip = Flip(polydata, i, ref_polydata); + + for (int j=0; jGetColor(j+1, rgb); + + double* p; + if (flip) + { + auto p_idx = numPoints - j - 1; + p = points->GetPoint(p_idx); + + working_fib->ColorSinglePoint(i, p_idx, rgb); + } + else + { + p = points->GetPoint(j); + + working_fib->ColorSinglePoint(i, j, rgb); + } + + double pixelValue = mitk::imv::GetImageValue(mitk::imv::GetItkPoint(p), true, interpolator); + output.put(j, i, pixelValue); + } + } + + return output; +} + +} + + + + diff --git a/Modules/FiberTracking/Algorithms/mitkTractometry.h b/Modules/FiberTracking/Algorithms/mitkTractometry.h new file mode 100644 index 0000000..d328036 --- /dev/null +++ b/Modules/FiberTracking/Algorithms/mitkTractometry.h @@ -0,0 +1,57 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center. + +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ +#ifndef TractometryFilter_h +#define TractometryFilter_h + +// MITK +#include +#include +#include +#include + +// ITK +#include + +// VTK +#include +#include +#include +#include +#include + +namespace mitk{ + +/** +* \brief */ + +class MITKFIBERTRACKING_EXPORT Tractometry +{ +public: + + static vnl_matrix StaticResamplingTractometry(itk::Image::Pointer itkImage, mitk::FiberBundle::Pointer fib, unsigned int num_points, mitk::FiberBundle::Pointer ref_fib); + + static std::vector> NearestCentroidPointTractometry(itk::Image::Pointer itkImage, mitk::FiberBundle::Pointer fib, unsigned int num_points, unsigned int max_centroids, float cluster_size, mitk::FiberBundle::Pointer ref_fib); + +protected: + + static bool Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer< vtkPolyData > ref_poly=nullptr); + + static void ResampleIfNecessary(mitk::FiberBundle::Pointer fib, unsigned int num_points); + +}; +} + +#endif diff --git a/Modules/FiberTracking/files.cmake b/Modules/FiberTracking/files.cmake index c6f3b07..81a3950 100644 --- a/Modules/FiberTracking/files.cmake +++ b/Modules/FiberTracking/files.cmake @@ -1,73 +1,75 @@ set(CPP_FILES mitkStreamlineTractographyParameters.cpp # Tractography Algorithms/GibbsTracking/mitkParticleGrid.cpp Algorithms/GibbsTracking/mitkMetropolisHastingsSampler.cpp Algorithms/GibbsTracking/mitkEnergyComputer.cpp Algorithms/GibbsTracking/mitkGibbsEnergyComputer.cpp Algorithms/GibbsTracking/mitkFiberBuilder.cpp Algorithms/GibbsTracking/mitkSphereInterpolator.cpp Algorithms/mitkTractClusteringFilter.cpp Algorithms/itkStreamlineTrackingFilter.cpp Algorithms/TrackingHandlers/mitkTrackingDataHandler.cpp Algorithms/TrackingHandlers/mitkTrackingHandlerTensor.cpp Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.cpp Algorithms/TrackingHandlers/mitkTrackingHandlerOdf.cpp + Algorithms/mitkTractometry.cpp ) set(H_FILES mitkStreamlineTractographyParameters.h # Algorithms Algorithms/itkTractDensityImageFilter.h Algorithms/itkTractsToFiberEndingsImageFilter.h Algorithms/itkTractsToRgbaImageFilter.h Algorithms/itkTractsToVectorImageFilter.h Algorithms/itkEvaluateDirectionImagesFilter.h Algorithms/itkEvaluateTractogramDirectionsFilter.h Algorithms/itkFiberCurvatureFilter.h Algorithms/mitkTractClusteringFilter.h Algorithms/itkTractDistanceFilter.h Algorithms/itkFiberExtractionFilter.h Algorithms/itkTdiToVolumeFractionFilter.h Algorithms/itkDistanceFromSegmentationImageFilter.h Algorithms/itkTractParcellationFilter.h + Algorithms/mitkTractometry.h # Tractography Algorithms/TrackingHandlers/mitkTrackingDataHandler.h Algorithms/TrackingHandlers/mitkTrackingHandlerRandomForest.h Algorithms/TrackingHandlers/mitkTrackingHandlerTensor.h Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.h Algorithms/TrackingHandlers/mitkTrackingHandlerOdf.h Algorithms/itkGibbsTrackingFilter.h Algorithms/itkStochasticTractographyFilter.h Algorithms/GibbsTracking/mitkParticle.h Algorithms/GibbsTracking/mitkParticleGrid.h Algorithms/GibbsTracking/mitkMetropolisHastingsSampler.h Algorithms/GibbsTracking/mitkSimpSamp.h Algorithms/GibbsTracking/mitkEnergyComputer.h Algorithms/GibbsTracking/mitkGibbsEnergyComputer.h Algorithms/GibbsTracking/mitkSphereInterpolator.h Algorithms/GibbsTracking/mitkFiberBuilder.h Algorithms/itkStreamlineTrackingFilter.h # Clustering Algorithms/ClusteringMetrics/mitkClusteringMetric.h Algorithms/ClusteringMetrics/mitkClusteringMetricEuclideanMean.h Algorithms/ClusteringMetrics/mitkClusteringMetricEuclideanMax.h Algorithms/ClusteringMetrics/mitkClusteringMetricEuclideanStd.h Algorithms/ClusteringMetrics/mitkClusteringMetricAnatomic.h Algorithms/ClusteringMetrics/mitkClusteringMetricScalarMap.h Algorithms/ClusteringMetrics/mitkClusteringMetricInnerAngles.h Algorithms/ClusteringMetrics/mitkClusteringMetricLength.h ) set(RESOURCE_FILES # Binary directory resources FiberTrackingLUTBaryCoords.bin FiberTrackingLUTIndices.bin ) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp index b406557..96ac42d 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp @@ -1,688 +1,440 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include "QmitkTractometryView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include const std::string QmitkTractometryView::VIEW_ID = "org.mitk.views.tractometry"; using namespace mitk; QmitkTractometryView::QmitkTractometryView() : QmitkAbstractView() , m_Controls( nullptr ) , m_Visible(false) { } // Destructor QmitkTractometryView::~QmitkTractometryView() { } void QmitkTractometryView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkTractometryViewControls; m_Controls->setupUi( parent ); connect( m_Controls->m_MethodBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()) ); connect( m_Controls->m_StartButton, SIGNAL(clicked()), this, SLOT(StartTractometry()) ); mitk::TNodePredicateDataType::Pointer imageP = mitk::TNodePredicateDataType::New(); mitk::NodePredicateDimension::Pointer dimP = mitk::NodePredicateDimension::New(3); m_Controls->m_ImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_ImageBox->SetPredicate(mitk::NodePredicateAnd::New(imageP, dimP)); m_Controls->m_ChartWidget->SetXAxisLabel("Tract position"); m_Controls->m_ChartWidget->SetYAxisLabel("Image Value"); m_Controls->m_ChartWidget->SetTheme(QmitkChartWidget::ColorTheme::darkstyle); } } void QmitkTractometryView::SetFocus() { } void QmitkTractometryView::UpdateGui() { berry::IWorkbenchPart::Pointer nullPart; OnSelectionChanged(nullPart, QList(m_CurrentSelection)); } -bool QmitkTractometryView::Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer< vtkPolyData > ref_poly) -{ - double d_direct = 0; - double d_flipped = 0; - - vtkCell* cell1 = polydata1->GetCell(0); - if (ref_poly!=nullptr) - cell1 = ref_poly->GetCell(0); - auto numPoints1 = cell1->GetNumberOfPoints(); - vtkPoints* points1 = cell1->GetPoints(); - - std::vector> ref_points; - for (int j=0; jGetPoint(j); - itk::Point itk_p; - itk_p[0] = p1[0]; - itk_p[1] = p1[1]; - itk_p[2] = p1[2]; - ref_points.push_back(itk_p); - } - - vtkCell* cell2 = polydata1->GetCell(i); - vtkPoints* points2 = cell2->GetPoints(); - - for (int j=0; jGetPoint(j); - d_direct += (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + (p1[2]-p2[2])*(p1[2]-p2[2]); - - double* p3 = points2->GetPoint(numPoints1-j-1); - d_flipped += (p1[0]-p3[0])*(p1[0]-p3[0]) + (p1[1]-p3[1])*(p1[1]-p3[1]) + (p1[2]-p3[2])*(p1[2]-p3[2]); - } - - if (d_direct>d_flipped) - return true; - return false; -} - void QmitkTractometryView::StaticResamplingTractometry(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector > &data, std::string& clipboard_string) { - mitk::FiberBundle::Pointer fib = dynamic_cast(node->GetData()); - - unsigned int num_points = m_Controls->m_SamplingPointsBox->value(); - mitk::FiberBundle::Pointer working_fib = fib->GetDeepCopy(); - working_fib->ResampleToNumPoints(num_points); - vtkSmartPointer< vtkPolyData > polydata = working_fib->GetFiberPolyData(); - - double rgb[3] = {0,0,0}; - - mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); - lookupTable->SetType(mitk::LookupTable::MULTILABEL); - - std::vector > all_values; - std::vector< double > mean_values; - for (unsigned int i=0; i::Pointer itkImage = itk::Image::New(); CastToItkImage(image, itkImage); - auto interpolator = itk::LinearInterpolateImageFunction< itk::Image, float >::New(); - interpolator->SetInputImage(itkImage); - - double min = 100000.0; - double max = 0; - double mean = 0; - for (unsigned int i=0; iGetNumFibers(); ++i) - { - vtkCell* cell = polydata->GetCell(i); - auto numPoints = cell->GetNumberOfPoints(); - vtkPoints* points = cell->GetPoints(); - - std::vector< double > fib_vals; - - bool flip = false; - if (i>0) - flip = Flip(polydata, i); - else if (m_ReferencePolyData!=nullptr) - flip = Flip(polydata, 0, m_ReferencePolyData); - - for (int j=0; jGetTableValue(j+1, rgb); - - double* p; - if (flip) - { - auto p_idx = numPoints - j - 1; - p = points->GetPoint(p_idx); - - working_fib->ColorSinglePoint(i, p_idx, rgb); - } - else - { - p = points->GetPoint(j); - - working_fib->ColorSinglePoint(i, j, rgb); - } - - double pixelValue = mitk::imv::GetImageValue(mitk::imv::GetItkPoint(p), true, interpolator); - fib_vals.push_back(pixelValue); - mean += pixelValue; - if (pixelValuemax) - max = pixelValue; - - mean_values.at(j) += pixelValue; - - } + mitk::FiberBundle::Pointer fib = dynamic_cast(node->GetData()); - all_values.push_back(fib_vals); - } + unsigned int num_points = m_Controls->m_SamplingPointsBox->value(); + mitk::FiberBundle::Pointer working_fib = fib->GetDeepCopy(); - if (m_ReferencePolyData==nullptr) - m_ReferencePolyData = polydata; + vnl_matrix output = mitk::Tractometry::StaticResamplingTractometry(itkImage, working_fib, num_points, m_ReferenceFib); std::vector< double > std_values1; std::vector< double > std_values2; - for (unsigned int i=0; i mean_values; + + for (unsigned int i=0; iGetNumFibers(); + auto row = output.get_row(i); + float mean = row.mean(); double stdev = 0; - for (unsigned int j=0; j(mean_values.at(i)); + clipboard_string += boost::lexical_cast(mean); clipboard_string += " "; clipboard_string += boost::lexical_cast(stdev); clipboard_string += "\n"; + + mean_values.push_back(mean); + std_values1.push_back(mean + stdev); + std_values2.push_back(mean - stdev); } clipboard_string += "\n"; data.push_back(mean_values); data.push_back(std_values1); data.push_back(std_values2); - MITK_INFO << "Min: " << min; - MITK_INFO << "Max: " << max; - MITK_INFO << "Mean: " << mean/working_fib->GetNumberOfPoints(); - if (m_Controls->m_ShowBinned->isChecked()) { mitk::DataNode::Pointer new_node = mitk::DataNode::New(); - auto children = GetDataStorage()->GetDerivations(node); - for (unsigned int i=0; isize(); ++i) - { - if (children->at(i)->GetName() == "binned_static") - { - new_node = children->at(i); - new_node->SetData(working_fib); - new_node->SetVisibility(true); - node->SetVisibility(false); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - return; - } - } - new_node->SetData(working_fib); new_node->SetName("binned_static"); new_node->SetVisibility(true); node->SetVisibility(false); GetDataStorage()->Add(new_node, node); } } void QmitkTractometryView::NearestCentroidPointTractometry(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string) { mitk::FiberBundle::Pointer fib = dynamic_cast(node->GetData()); unsigned int num_points = m_Controls->m_SamplingPointsBox->value(); mitk::FiberBundle::Pointer working_fib = fib->GetDeepCopy(); working_fib->ResampleSpline(1.0); - vtkSmartPointer< vtkPolyData > working_polydata = working_fib->GetFiberPolyData(); - - // clustering - std::vector< mitk::ClusteringMetric* > metrics; - metrics.push_back({new mitk::ClusteringMetricEuclideanStd()}); - - mitk::FiberBundle::Pointer fib_static_resampled = fib->GetDeepCopy(); - fib_static_resampled->ResampleToNumPoints(num_points); - vtkSmartPointer< vtkPolyData > polydata_static_resampled = fib_static_resampled->GetFiberPolyData(); - - std::vector centroids; - std::shared_ptr< mitk::TractClusteringFilter > clusterer = std::make_shared(); - int c=0; - while (c<30 && (centroids.empty() || centroids.size()>static_cast(m_Controls->m_MaxCentroids->value()))) - { - float cluster_size = m_Controls->m_ClusterSize->value() + m_Controls->m_ClusterSize->value()*c*0.2; - float max_d = 0; - int i=1; - std::vector< float > distances; - while (max_d < working_fib->GetGeometry()->GetDiagonalLength()/2) - { - distances.push_back(cluster_size*i); - max_d = cluster_size*i; - ++i; - } - - clusterer->SetDistances(distances); - clusterer->SetTractogram(fib_static_resampled); - clusterer->SetMetrics(metrics); - clusterer->SetMergeDuplicateThreshold(cluster_size); - clusterer->SetDoResampling(false); - clusterer->SetNumPoints(num_points); - // clusterer->SetMaxClusters(m_Controls->m_MaxCentroids->value()); - clusterer->SetMinClusterSize(1); - clusterer->Update(); - centroids = clusterer->GetOutCentroids(); - ++c; - } - - double rgb[3] = {0,0,0}; - mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); - lookupTable->SetType(mitk::LookupTable::MULTILABEL); - - std::vector > all_values; - std::vector< double > mean_values; - std::vector< unsigned int > value_count; - for (unsigned int i=0; i::Pointer itkImage = itk::Image::New(); CastToItkImage(image, itkImage); - auto interpolator = itk::LinearInterpolateImageFunction< itk::Image, float >::New(); - interpolator->SetInputImage(itkImage); - - double min = 100000.0; - double max = 0; - double mean = 0; - for (unsigned int i=0; iGetNumFibers(); ++i) - { - vtkCell* cell = working_polydata->GetCell(i); - auto numPoints = cell->GetNumberOfPoints(); - vtkPoints* points = cell->GetPoints(); - - std::vector< double > fib_vals; - for (int j=0; jGetPoint(j); - - int min_bin = 0; - float d=999999; - for (auto centroid : centroids) - { - auto centroid_polydata = centroid->GetFiberPolyData(); - - vtkCell* centroid_cell = centroid_polydata->GetCell(0); - auto centroid_numPoints = centroid_cell->GetNumberOfPoints(); - vtkPoints* centroid_points = centroid_cell->GetPoints(); - - bool centroid_flip = Flip(centroid_polydata, 0, centroids.at(0)->GetFiberPolyData()); - - for (int bin=0; binGetPoint(bin); - float temp_d = std::sqrt((p[0]-centroid_p[0])*(p[0]-centroid_p[0]) + (p[1]-centroid_p[1])*(p[1]-centroid_p[1]) + (p[2]-centroid_p[2])*(p[2]-centroid_p[2])); - if (temp_dGetTableValue(min_bin+1, rgb); - working_fib->ColorSinglePoint(i, j, rgb); - - double pixelValue = mitk::imv::GetImageValue(mitk::imv::GetItkPoint(p), true, interpolator); - fib_vals.push_back(pixelValue); - mean += pixelValue; - if (pixelValuemax) - max = pixelValue; - - mean_values.at(min_bin) += pixelValue; - value_count.at(min_bin) += 1; - } - - all_values.push_back(fib_vals); - } - - if (m_ReferencePolyData==nullptr) - m_ReferencePolyData = working_polydata; + auto output = mitk::Tractometry::NearestCentroidPointTractometry(itkImage, working_fib, num_points, m_Controls->m_MaxCentroids->value(), m_Controls->m_ClusterSize->value(), m_ReferenceFib); std::vector< double > std_values1; std::vector< double > std_values2; - for (unsigned int i=0; i mean_values; + + for (auto row : output) { - mean_values.at(i) /= value_count.at(i); + float mean = row.mean(); double stdev = 0; - for (unsigned int j=0; j(mean_values.at(i)); + clipboard_string += boost::lexical_cast(mean); clipboard_string += " "; clipboard_string += boost::lexical_cast(stdev); clipboard_string += "\n"; + + mean_values.push_back(mean); + std_values1.push_back(mean + stdev); + std_values2.push_back(mean - stdev); } clipboard_string += "\n"; data.push_back(mean_values); data.push_back(std_values1); data.push_back(std_values2); - MITK_INFO << "Min: " << min; - MITK_INFO << "Max: " << max; - MITK_INFO << "Mean: " << mean/working_fib->GetNumberOfPoints(); - if (m_Controls->m_ShowBinned->isChecked()) { mitk::DataNode::Pointer new_node = mitk::DataNode::New(); -// mitk::DataNode::Pointer new_node2; - auto children = GetDataStorage()->GetDerivations(node); - for (unsigned int i=0; isize(); ++i) - { - if (children->at(i)->GetName() == "binned_centroid") - { - new_node = children->at(i); - new_node->SetData(working_fib); - new_node->SetVisibility(true); - node->SetVisibility(false); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - return; - } - } new_node->SetData(working_fib); new_node->SetName("binned_centroid"); new_node->SetVisibility(true); node->SetVisibility(false); GetDataStorage()->Add(new_node, node); } } void QmitkTractometryView::Activated() { } void QmitkTractometryView::Deactivated() { } void QmitkTractometryView::Visible() { m_Visible = true; QList selection = GetDataManagerSelection(); berry::IWorkbenchPart::Pointer nullPart; OnSelectionChanged(nullPart, selection); } void QmitkTractometryView::Hidden() { m_Visible = false; } std::string QmitkTractometryView::RGBToHexString(double *rgb) { std::ostringstream os; for (int i = 0; i < 3; ++i) { os << std::setw(2) << std::setfill('0') << std::hex << static_cast(rgb[i] * 255); } return os.str(); } void QmitkTractometryView::AlongTractRadiomicsPreprocessing(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string) { mitk::FiberBundle::Pointer fib = dynamic_cast(node->GetData()); // calculate mask typedef itk::Image ParcellationImageType; ParcellationImageType::Pointer itkImage = ParcellationImageType::New(); CastToItkImage(image, itkImage); itk::TractParcellationFilter< >::Pointer parcellator = itk::TractParcellationFilter< >::New(); parcellator->SetInputImage(itkImage); parcellator->SetNumParcels(m_Controls->m_SamplingPointsBox->value()); parcellator->SetInputTract(fib); parcellator->SetNumCentroids(m_Controls->m_MaxCentroids->value()); parcellator->SetStartClusterSize(m_Controls->m_ClusterSize->value()); parcellator->Update(); ParcellationImageType::Pointer out_image = parcellator->GetOutput(0); ParcellationImageType::Pointer out_image_pp = parcellator->GetOutput(1); auto binary_masks = parcellator->GetBinarySplit(out_image_pp); mitk::Image::Pointer seg_img = mitk::Image::New(); seg_img->InitializeByItk(out_image.GetPointer()); seg_img->SetVolume(out_image->GetBufferPointer()); mitk::Image::Pointer seg_img_pp = mitk::Image::New(); seg_img_pp->InitializeByItk(out_image_pp.GetPointer()); seg_img_pp->SetVolume(out_image_pp->GetBufferPointer()); std::vector< double > std_values1; std::vector< double > std_values2; std::vector< double > mean_values; for (auto mask : binary_masks) { itk::Image::Pointer data_image = itk::Image::New(); CastToItkImage(image, data_image); itk::MaskedStatisticsImageFilter>::Pointer statisticsImageFilter = itk::MaskedStatisticsImageFilter>::New(); statisticsImageFilter->SetInput(data_image); statisticsImageFilter->SetMask(mask); statisticsImageFilter->Update(); double mean = statisticsImageFilter->GetMean(); double stdev = std::sqrt(statisticsImageFilter->GetVariance()); std_values1.push_back(mean + stdev); std_values2.push_back(mean - stdev); mean_values.push_back(mean); clipboard_string += boost::lexical_cast(mean); clipboard_string += " "; clipboard_string += boost::lexical_cast(stdev); clipboard_string += "\n"; } clipboard_string += "\n"; data.push_back(mean_values); data.push_back(std_values1); data.push_back(std_values2); mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); lut->SetType( mitk::LookupTable::MULTILABEL ); mitk::LookupTableProperty::Pointer lut_prop = mitk::LookupTableProperty::New(); lut_prop->SetLookupTable( lut ); mitk::LevelWindow lw; lw.SetRangeMinMax(0, parcellator->GetNumParcels()); // mitk::DataNode::Pointer new_node = mitk::DataNode::New(); // new_node->SetData(seg_img); // new_node->SetName("tract parcellation"); // new_node->SetVisibility(true); // new_node->SetProperty("LookupTable", lut_prop ); // new_node->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( lw ) ); // node->SetVisibility(false); // GetDataStorage()->Add(new_node, node); mitk::DataNode::Pointer new_node2 = mitk::DataNode::New(); new_node2->SetData(seg_img_pp); new_node2->SetName("tract parcellation pp"); new_node2->SetVisibility(false); new_node2->SetProperty("LookupTable", lut_prop ); new_node2->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( lw ) ); GetDataStorage()->Add(new_node2, node); mitk::DataNode::Pointer new_node3 = mitk::DataNode::New(); auto working_fib = fib->GetDeepCopy(); working_fib->ColorFibersByScalarMap(seg_img, false, false, mitk::LookupTable::LookupTableType::MULTILABEL, 0.9); new_node3->SetData(working_fib); new_node3->SetName("centroids"); GetDataStorage()->Add(new_node3, node); } void QmitkTractometryView::StartTractometry() { - m_ReferencePolyData = nullptr; + m_ReferenceFib = dynamic_cast(m_CurrentSelection.at(0)->GetData())->GetDeepCopy(); + + MITK_INFO << "Resanmpling reference fibers"; + m_ReferenceFib->ResampleToNumPoints(m_Controls->m_SamplingPointsBox->value()); double color[3] = {0,0,0}; mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); lookupTable->SetType(mitk::LookupTable::MULTILABEL); mitk::Image::Pointer image = dynamic_cast(m_Controls->m_ImageBox->GetSelectedNode()->GetData()); this->m_Controls->m_ChartWidget->Clear(); std::string clipboardString = ""; int c = 1; for (auto node : m_CurrentSelection) { clipboardString += node->GetName() + "\n"; clipboardString += "mean stdev\n"; std::vector< std::vector< double > > data; switch (m_Controls->m_MethodBox->currentIndex()) { case 0: { StaticResamplingTractometry( image, node, data, clipboardString ); break; } case 1: { NearestCentroidPointTractometry( image, node, data, clipboardString ); break; } case 2: { AlongTractRadiomicsPreprocessing(image, node, data, clipboardString); break; } default: { StaticResamplingTractometry( image, node, data, clipboardString ); } } m_Controls->m_ChartWidget->AddData1D(data.at(0), node->GetName() + " Mean", QmitkChartWidget::ChartType::line); m_Controls->m_ChartWidget->SetLineStyle(node->GetName() + " Mean", QmitkChartWidget::LineStyle::solid); if (m_Controls->m_StDevBox->isChecked()) { m_Controls->m_ChartWidget->AddData1D(data.at(1), node->GetName() + " +STDEV", QmitkChartWidget::ChartType::line); m_Controls->m_ChartWidget->AddData1D(data.at(2), node->GetName() + " -STDEV", QmitkChartWidget::ChartType::line); m_Controls->m_ChartWidget->SetLineStyle(node->GetName() + " +STDEV", QmitkChartWidget::LineStyle::dashed); m_Controls->m_ChartWidget->SetLineStyle(node->GetName() + " -STDEV", QmitkChartWidget::LineStyle::dashed); } lookupTable->GetTableValue(c, color); this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " Mean", RGBToHexString(color)); if (m_Controls->m_StDevBox->isChecked()) { color[0] *= 0.5; color[1] *= 0.5; color[2] *= 0.5; this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " +STDEV", RGBToHexString(color)); this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " -STDEV", RGBToHexString(color)); } this->m_Controls->m_ChartWidget->Show(true); this->m_Controls->m_ChartWidget->SetShowDataPoints(false); ++c; } QApplication::clipboard()->setText(clipboardString.c_str(), QClipboard::Clipboard); } void QmitkTractometryView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes) { m_Controls->m_StartButton->setEnabled(false); if (!m_Visible) return; if (m_Controls->m_MethodBox->currentIndex()==0) m_Controls->m_ClusterFrame->setVisible(false); else m_Controls->m_ClusterFrame->setVisible(true); m_CurrentSelection.clear(); if(m_Controls->m_ImageBox->GetSelectedNode().IsNull()) return; for (auto node: nodes) if ( dynamic_cast(node->GetData()) ) m_CurrentSelection.push_back(node); if (!m_CurrentSelection.empty()) m_Controls->m_StartButton->setEnabled(true); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h index c0b5e23..618203d 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h @@ -1,84 +1,83 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkTractometryView_h #define QmitkTractometryView_h #include #include "ui_QmitkTractometryViewControls.h" #include #include #include #include #include #include /*! \brief Weight fibers by linearly fitting them to the image data. */ class QmitkTractometryView : public QmitkAbstractView, public mitk::ILifecycleAwarePart { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; QmitkTractometryView(); virtual ~QmitkTractometryView(); virtual void CreateQtPartControl(QWidget *parent) override; void StaticResamplingTractometry(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string); void NearestCentroidPointTractometry(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string); void AlongTractRadiomicsPreprocessing(mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector > &data, std::string &clipboard_string); virtual void SetFocus() override; virtual void Activated() override; virtual void Deactivated() override; virtual void Visible() override; virtual void Hidden() override; protected slots: void UpdateGui(); void StartTractometry(); protected: /// \brief called by QmitkAbstractView when DataManager's selection has changed virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override; Ui::QmitkTractometryViewControls* m_Controls; - bool Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer ref_poly=nullptr); std::string RGBToHexString(double *rgb); - vtkSmartPointer< vtkPolyData > m_ReferencePolyData; + mitk::FiberBundle::Pointer m_ReferenceFib; QList m_CurrentSelection; bool m_Visible; }; #endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryViewControls.ui index aac3a4d..a99b28f 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryViewControls.ui @@ -1,225 +1,225 @@ QmitkTractometryViewControls 0 0 484 951 Form QCommandLinkButton:disabled { border: none; } QGroupBox { background-color: transparent; } Qt::Vertical 20 40 Show STDEV true Show binned tract true 0 600 Centroid Options 0 9999 0 Cluster Size: Max. Number of Centroids: 15.000000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 6 - - - - 0 - - - 99999 - - - 0 + + + + Binning Method: Input Image: - - - - Sampling Points: - - - 2 Static Resampling Centroid Based Segment voting - - + + - Binning Method: + Sampling Points: + + + + + + + 0 + + + 99999 + + + 0 Start Tractometry QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
QmitkChartWidget QWidget
QmitkChartWidget.h