diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fde9427 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +Modules/FiberDissection/Interactor/mitkStreamlineInteractor (copy).cpp diff --git a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp index 828d2a6..db6cc0a 100644 --- a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp +++ b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp @@ -1,2847 +1,2908 @@ /*=================================================================== 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 "mitkFiberBundle.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 #include const char* mitk::FiberBundle::FIBER_ID_ARRAY = "Fiber_IDs"; mitk::FiberBundle::FiberBundle( vtkPolyData* fiberPolyData ) : m_NumFibers(0) { m_TrackVisHeader.hdr_size = 0; m_FiberWeights = vtkSmartPointer::New(); m_FiberWeights->SetName("FIBER_WEIGHTS"); m_FiberPolyData = vtkSmartPointer::New(); if (fiberPolyData != nullptr) m_FiberPolyData = fiberPolyData; else { this->m_FiberPolyData->SetPoints(vtkSmartPointer::New()); this->m_FiberPolyData->SetLines(vtkSmartPointer::New()); } this->UpdateFiberGeometry(); this->GenerateFiberIds(); this->ColorFibersByOrientation(); } mitk::FiberBundle::~FiberBundle() { } mitk::FiberBundle::Pointer mitk::FiberBundle::GetDeepCopy() { mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(m_FiberPolyData); newFib->SetFiberColors(this->m_FiberColors); newFib->SetFiberWeights(this->m_FiberWeights); newFib->SetTrackVisHeader(this->GetTrackVisHeader()); return newFib; } vtkSmartPointer mitk::FiberBundle::GeneratePolyDataByIds(std::vector fiberIds, vtkSmartPointer weights) { vtkSmartPointer newFiberPolyData = vtkSmartPointer::New(); vtkSmartPointer newLineSet = vtkSmartPointer::New(); vtkSmartPointer newPointSet = vtkSmartPointer::New(); weights->SetNumberOfValues(fiberIds.size()); int counter = 0; auto finIt = fiberIds.begin(); while ( finIt != fiberIds.end() ) { if (*finIt>GetNumFibers()){ MITK_INFO << "FiberID can not be negative or >NumFibers!!! check id Extraction!" << *finIt; break; } vtkSmartPointer fiber = m_FiberIdDataSet->GetCell(*finIt);//->DeepCopy(fiber); vtkSmartPointer fibPoints = fiber->GetPoints(); vtkSmartPointer newFiber = vtkSmartPointer::New(); newFiber->GetPointIds()->SetNumberOfIds( fibPoints->GetNumberOfPoints() ); for(int i=0; iGetNumberOfPoints(); i++) { newFiber->GetPointIds()->SetId(i, newPointSet->GetNumberOfPoints()); newPointSet->InsertNextPoint(fibPoints->GetPoint(i)[0], fibPoints->GetPoint(i)[1], fibPoints->GetPoint(i)[2]); } weights->InsertValue(counter, this->GetFiberWeight(*finIt)); newLineSet->InsertNextCell(newFiber); ++finIt; ++counter; } newFiberPolyData->SetPoints(newPointSet); newFiberPolyData->SetLines(newLineSet); return newFiberPolyData; } // merge two fiber bundles mitk::FiberBundle::Pointer mitk::FiberBundle::AddBundles(std::vector< mitk::FiberBundle::Pointer > fibs) { vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); vtkSmartPointer vNewLines = vtkSmartPointer::New(); vtkSmartPointer vNewPoints = vtkSmartPointer::New(); // add current fiber bundle vtkSmartPointer weights = vtkSmartPointer::New(); auto num_weights = this->GetNumFibers(); for (auto fib : fibs) num_weights += fib->GetNumFibers(); weights->SetNumberOfValues(num_weights); unsigned int counter = 0; for (unsigned int i=0; iGetNumberOfCells(); ++i) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (unsigned int j=0; jGetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, this->GetFiberWeight(i)); vNewLines->InsertNextCell(container); counter++; } for (auto fib : fibs) { // add new fiber bundle for (unsigned int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) { vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (unsigned int j=0; jGetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, fib->GetFiberWeight(i)); vNewLines->InsertNextCell(container); counter++; } } // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData); newFib->SetFiberWeights(weights); return newFib; } // merge two fiber bundles mitk::FiberBundle::Pointer mitk::FiberBundle::AddBundle(mitk::FiberBundle* fib) { if (fib==nullptr) return this->GetDeepCopy(); MITK_INFO << "Adding fibers"; vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); vtkSmartPointer vNewLines = vtkSmartPointer::New(); vtkSmartPointer vNewPoints = vtkSmartPointer::New(); // add current fiber bundle vtkSmartPointer weights = vtkSmartPointer::New(); weights->SetNumberOfValues(this->GetNumFibers()+fib->GetNumFibers()); unsigned int counter = 0; for (unsigned int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (unsigned int j=0; jGetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, this->GetFiberWeight(i)); vNewLines->InsertNextCell(container); counter++; } // add new fiber bundle for (unsigned int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) { vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (unsigned int j=0; jGetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, fib->GetFiberWeight(i)); vNewLines->InsertNextCell(container); counter++; } // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData); newFib->SetFiberWeights(weights); return newFib; } // Only retain fibers with a weight larger than the specified threshold mitk::FiberBundle::Pointer mitk::FiberBundle::FilterByWeights(float weight_thr, bool invert) { vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); vtkSmartPointer vNewLines = vtkSmartPointer::New(); vtkSmartPointer vNewPoints = vtkSmartPointer::New(); std::vector weights; for (unsigned int i=0; iGetNumFibers(); i++) { if ( (invert && this->GetFiberWeight(i)>weight_thr) || (!invert && this->GetFiberWeight(i)<=weight_thr)) continue; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); weights.push_back(this->GetFiberWeight(i)); } // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData); for (unsigned int i=0; iSetFiberWeight(i, weights.at(i)); newFib->SetTrackVisHeader(this->GetTrackVisHeader()); return newFib; } // Only retain a subsample of the fibers mitk::FiberBundle::Pointer mitk::FiberBundle::SubsampleFibers(float factor, bool random_seed) { vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); vtkSmartPointer vNewLines = vtkSmartPointer::New(); vtkSmartPointer vNewPoints = vtkSmartPointer::New(); unsigned int new_num_fibs = static_cast(std::round(this->GetNumFibers()*factor)); MITK_INFO << "Subsampling fibers with factor " << factor << "(" << new_num_fibs << "/" << this->GetNumFibers() << ")"; // add current fiber bundle vtkSmartPointer weights = vtkSmartPointer::New(); weights->SetNumberOfValues(new_num_fibs); std::vector< unsigned int > ids; for (unsigned int i=0; iGetNumFibers(); i++) ids.push_back(i); if (random_seed) std::srand(static_cast(std::time(nullptr))); else std::srand(0); std::random_device rd; std::mt19937 g(rd()); std::shuffle(ids.begin(), ids.end(), g); unsigned int counter = 0; for (unsigned int i=0; iGetCell(ids.at(i)); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j, p); vtkIdType id = vNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } weights->InsertValue(counter, this->GetFiberWeight(ids.at(i))); vNewLines->InsertNextCell(container); counter++; } // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData); newFib->SetFiberWeights(weights); newFib->SetTrackVisHeader(this->GetTrackVisHeader()); return newFib; } // subtract two fiber bundles mitk::FiberBundle::Pointer mitk::FiberBundle::SubtractBundle(mitk::FiberBundle* fib) { if (fib==nullptr) return this->GetDeepCopy(); MITK_INFO << "Subtracting fibers"; vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); vtkSmartPointer vNewLines = vtkSmartPointer::New(); vtkSmartPointer vNewPoints = vtkSmartPointer::New(); std::vector< std::vector< itk::Point > > points1; for(unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (points==nullptr || numPoints<=0) continue; itk::Point start = mitk::imv::GetItkPoint(points->GetPoint(0)); itk::Point end = mitk::imv::GetItkPoint(points->GetPoint(numPoints-1)); points1.push_back( {start, end} ); } std::vector< std::vector< itk::Point > > points2; for(unsigned int i=0; iGetNumFibers(); i++ ) { vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (points==nullptr || numPoints<=0) continue; itk::Point start =mitk::imv::GetItkPoint(points->GetPoint(0)); itk::Point end =mitk::imv::GetItkPoint(points->GetPoint(numPoints-1)); points2.push_back( {start, end} ); } // int progress = 0; std::vector< int > ids; #pragma omp parallel for for (int i=0; i(points1.size()); i++) { bool match = false; for (unsigned int j=0; j(i)); auto v2 = points2.at(j); float dist=0; for (unsigned int c=0; cGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (points==nullptr || numPoints<=0) continue; vtkSmartPointer container = vtkSmartPointer::New(); for( int j=0; jInsertNextPoint(points->GetPoint(j)); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); } if(vNewLines->GetNumberOfCells()==0) return mitk::FiberBundle::New(); // initialize PolyData vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); // initialize fiber bundle return mitk::FiberBundle::New(vNewPolyData); } /* * set PolyData (additional flag to recompute fiber geometry, default = true) */ void mitk::FiberBundle::SetFiberPolyData(vtkSmartPointer fiberPD, bool updateGeometry) { if (fiberPD == nullptr) this->m_FiberPolyData = vtkSmartPointer::New(); else { m_FiberPolyData->CopyStructure(fiberPD); // m_FiberPolyData->DeepCopy(fiberPD); } m_NumFibers = static_cast(m_FiberPolyData->GetNumberOfLines()); if (updateGeometry) UpdateFiberGeometry(); GenerateFiberIds(); ColorFibersByOrientation(); } /* * return vtkPolyData */ vtkSmartPointer mitk::FiberBundle::GetFiberPolyData() const { return m_FiberPolyData; } void mitk::FiberBundle::ColorFibersByLength(bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type) { if (m_MaxFiberLength<=0) return; auto numOfPoints = this->GetNumberOfPoints(); //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; m_FiberColors = vtkSmartPointer::New(); m_FiberColors->Allocate(numOfPoints * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); auto numOfFibers = m_FiberPolyData->GetNumberOfLines(); if (numOfFibers < 1) return; mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New(); mitkLookup->SetType(type); if (type!=mitk::LookupTable::MULTILABEL) mitkLookup->GetVtkLookupTable()->SetTableRange(m_MinFiberLength, m_MaxFiberLength); unsigned int count = 0; for (unsigned int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); float l = m_FiberLengths.at(i)/m_MaxFiberLength; double color[3]; mitkLookup->GetColor(m_FiberLengths.at(i), color); for (int j=0; j(255.0 * color[0]); rgba[1] = static_cast(255.0 * color[1]); rgba[2] = static_cast(255.0 * color[2]); if (opacity) rgba[3] = static_cast(255.0f * l); else rgba[3] = static_cast(255.0); m_FiberColors->InsertTypedTuple(cell->GetPointId(j), rgba); count++; } if (weight_fibers) this->SetFiberWeight(i, m_FiberLengths.at(i)); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorSinglePoint(int f_idx, int p_idx, double rgb[3]) { // vtkPoints* extrPoints = m_FiberPolyData->GetPoints(); // vtkIdType numOfPoints = 0; // if (extrPoints!=nullptr) // numOfPoints = extrPoints->GetNumberOfPoints(); // //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; // m_FiberColors = vtkSmartPointer::New(); // m_FiberColors->Allocate(numOfPoints * 4); // m_FiberColors->SetNumberOfComponents(4); // m_FiberColors->SetName("FIBER_COLORS"); // auto numOfFibers = m_FiberPolyData->GetNumberOfLines(); // if (numOfFibers < 1) // return; // /* extract single fibers of fiberBundle */ // vtkCellArray* fiberList = m_FiberPolyData->GetLines(); // fiberList->InitTraversal(); // for (int fi=0; fiGetNextCell(num_points, idList); // fiberList->GetCell(f_idx, num_points, idList); vtkCell* cell = m_FiberPolyData->GetCell(f_idx); // /* single fiber checkpoints: is number of points valid */ // if (p_idx < num_points) // { rgba[0] = static_cast(255.0 * rgb[0]); rgba[1] = static_cast(255.0 * rgb[1]); rgba[2] = static_cast(255.0 * rgb[2]); rgba[3] = 255; m_FiberColors->InsertTypedTuple(cell->GetPointId(p_idx), rgba); // } // } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorFibersByOrientation() { //===== 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 //================================================= vtkPoints* extrPoints = m_FiberPolyData->GetPoints(); vtkIdType numOfPoints = 0; if (extrPoints!=nullptr) numOfPoints = extrPoints->GetNumberOfPoints(); //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; m_FiberColors = vtkSmartPointer::New(); m_FiberColors->Allocate(numOfPoints * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); auto numOfFibers = m_FiberPolyData->GetNumberOfLines(); if (numOfFibers < 1) return; /* extract single fibers of fiberBundle */ vtkCellArray* fiberList = m_FiberPolyData->GetLines(); fiberList->InitTraversal(); for (int fi=0; fiGetNextCell(pointsPerFiber, idList); /* single fiber checkpoints: is number of points valid */ if (pointsPerFiber > 1) { /* operate on points of single fiber */ 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(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]); vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; vnl_vector_fixed< double, 3 > diff2; diff2 = currentPntvtk - prevPntvtk; vnl_vector_fixed< double, 3 > diff; diff = (diff1 - diff2) / 2.0; diff.normalize(); rgba[0] = static_cast(255.0 * std::fabs(diff[0])); rgba[1] = static_cast(255.0 * std::fabs(diff[1])); rgba[2] = static_cast(255.0 * std::fabs(diff[2])); rgba[3] = static_cast(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(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]); vnl_vector_fixed< double, 3 > diff1; diff1 = currentPntvtk - nextPntvtk; diff1.normalize(); rgba[0] = static_cast(255.0 * std::fabs(diff1[0])); rgba[1] = static_cast(255.0 * std::fabs(diff1[1])); rgba[2] = static_cast(255.0 * std::fabs(diff1[2])); rgba[3] = static_cast(255.0); } else if (i==pointsPerFiber-1) { /* Last point has no next point, therefore only diff2 is taken */ vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]); vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]); vnl_vector_fixed< double, 3 > diff2; diff2 = currentPntvtk - prevPntvtk; diff2.normalize(); rgba[0] = static_cast(255.0 * std::fabs(diff2[0])); rgba[1] = static_cast(255.0 * std::fabs(diff2[1])); rgba[2] = static_cast(255.0 * std::fabs(diff2[2])); rgba[3] = static_cast(255.0); } m_FiberColors->InsertTypedTuple(idList[i], rgba); } } else if (pointsPerFiber == 1) { /* a single point does not define a fiber (use vertex mechanisms instead */ continue; } else { MITK_DEBUG << "Fiber with 0 points detected... please check your tractography algorithm!" ; continue; } } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorFibersByCurvature(bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type) { double window = 5; //colors and alpha value for each single point, RGBA = 4 components unsigned char rgba[4] = {0,0,0,0}; m_FiberColors = vtkSmartPointer::New(); m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); std::vector< double > values; double min = 1; double max = 0; MITK_INFO << "Coloring fibers by curvature"; boost::timer::progress_display disp(static_cast(m_FiberPolyData->GetNumberOfCells())); for (int i=0; iGetNumberOfCells(); i++) { ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); double mean_curv = 0; // calculate curvatures for (int j=0; j > vectors; vnl_vector_fixed< double, 3 > meanV; meanV.fill(0.0); while(dist1) { double p1[3]; points->GetPoint(c-1, p1); double p2[3]; points->GetPoint(c, p2); vnl_vector_fixed< double, 3 > v; v[0] = p2[0]-p1[0]; v[1] = p2[1]-p1[1]; v[2] = p2[2]-p1[2]; dist += v.magnitude(); v.normalize(); vectors.push_back(v); meanV += v; c--; } c = j; dist = 0; while(distGetPoint(c, p1); double p2[3]; points->GetPoint(c+1, p2); vnl_vector_fixed< double, 3 > v; v[0] = p2[0]-p1[0]; v[1] = p2[1]-p1[1]; v[2] = p2[2]-p1[2]; dist += v.magnitude(); v.normalize(); vectors.push_back(v); meanV += v; c++; } meanV.normalize(); double dev = 0; for (unsigned int c=0; c1.0) angle = 1.0; if (angle<-1.0) angle = -1.0; dev += acos(angle)*180/itk::Math::pi; } if (vectors.size()>0) dev /= vectors.size(); if (weight_fibers) mean_curv += dev; dev = 1.0-dev/180.0; values.push_back(dev); if (devmax) max = dev; } if (weight_fibers) this->SetFiberWeight(i, mean_curv/numPoints); } mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New(); mitkLookup->SetType(type); if (type!=mitk::LookupTable::MULTILABEL) mitkLookup->GetVtkLookupTable()->SetTableRange(min, max); unsigned int count = 0; for (int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); for (int j=0; jGetColor(dev, color); rgba[0] = static_cast(255.0 * color[0]); rgba[1] = static_cast(255.0 * color[1]); rgba[2] = static_cast(255.0 * color[2]); if (opacity) rgba[3] = static_cast(255.0f * dev/max); else rgba[3] = static_cast(255.0); m_FiberColors->InsertTypedTuple(cell->GetPointId(j), rgba); count++; } } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::SetFiberOpacity(vtkDoubleArray* FAValArray) { for(long i=0; iGetNumberOfTuples(); i++) { double faValue = FAValArray->GetValue(i); faValue = faValue * 255.0; m_FiberColors->SetComponent(i,3, static_cast(faValue) ); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ResetFiberOpacity() { for(long i=0; iGetNumberOfTuples(); i++) m_FiberColors->SetComponent(i,3, 255.0 ); m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorFibersByScalarMap(mitk::Image::Pointer FAimage, bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type, double max_cap, bool interpolate) { if (FAimage->GetPixelType().GetComponentTypeAsString()=="unsigned char" || FAimage->GetPixelType().GetComponentTypeAsString()=="char" || FAimage->GetPixelType().GetComponentTypeAsString()=="long" || FAimage->GetPixelType().GetComponentTypeAsString()=="unsigned long" || FAimage->GetPixelType().GetComponentTypeAsString()=="short" || FAimage->GetPixelType().GetComponentTypeAsString()=="unsigned short" || FAimage->GetPixelType().GetComponentTypeAsString()=="unsigned int" || FAimage->GetPixelType().GetComponentTypeAsString()=="int") { typedef itk::Image ImageType; ImageType::Pointer itkImage = ImageType::New(); CastToItkImage(FAimage, itkImage); ColorFibersByScalarMap(itkImage, opacity, weight_fibers, type, max_cap, interpolate ); } else { typedef itk::Image ImageType; ImageType::Pointer itkImage = ImageType::New(); CastToItkImage(FAimage, itkImage); ColorFibersByScalarMap(itkImage, opacity, weight_fibers, type, max_cap, interpolate ); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } template void mitk::FiberBundle::ColorFibersByScalarMap(typename itk::Image::Pointer image, bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type, double max_cap, bool interpolate) { m_FiberColors = vtkSmartPointer::New(); m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); unsigned char rgba[4] = {0,0,0,0}; vtkPoints* pointSet = m_FiberPolyData->GetPoints(); if (type==mitk::LookupTable::MULTILABEL) interpolate = false; auto interpolator = itk::LinearInterpolateImageFunction< itk::Image, float >::New(); interpolator->SetInputImage(image); double min = 999999; double max = -999999; for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); double mean_val = 0; for (int j=0; jGetPoint(j, p); auto pixelValue = mitk::imv::GetImageValue(mitk::imv::GetItkPoint(p), interpolate, interpolator); if (pixelValue>max) max = pixelValue; if (pixelValueSetFiberWeight(i, mean_val/numPoints); } mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New(); mitkLookup->SetType(type); if (type!=mitk::LookupTable::MULTILABEL) mitkLookup->GetVtkLookupTable()->SetTableRange(min, max*max_cap); for(long i=0; iGetNumberOfPoints(); ++i) { itk::Point px; px[0] = pointSet->GetPoint(i)[0]; px[1] = pointSet->GetPoint(i)[1]; px[2] = pointSet->GetPoint(i)[2]; auto pixelValue = mitk::imv::GetImageValue(px, interpolate, interpolator); double color[3]; mitkLookup->GetColor(pixelValue, color); rgba[0] = static_cast(255.0 * color[0]); rgba[1] = static_cast(255.0 * color[1]); rgba[2] = static_cast(255.0 * color[2]); if (opacity) rgba[3] = static_cast(255.0 * pixelValue); else rgba[3] = static_cast(255.0); m_FiberColors->InsertTypedTuple(i, rgba); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::ColorFibersByFiberWeights(bool opacity, mitk::LookupTable::LookupTableType type) { m_FiberColors = vtkSmartPointer::New(); m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); unsigned char rgba[4] = {0,0,0,0}; unsigned int counter = 0; float max = -999999; float min = 999999; for (unsigned int i=0; iGetFiberWeight(i); if (weight>max) max = weight; if (weightSetType(type); if (type!=mitk::LookupTable::MULTILABEL) mitkLookup->GetVtkLookupTable()->SetTableRange(min, max); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); auto weight = this->GetFiberWeight(i); double color[3]; mitkLookup->GetColor(weight, color); for (int j=0; j(255.0 * color[0]); rgba[1] = static_cast(255.0 * color[1]); rgba[2] = static_cast(255.0 * color[2]); if (opacity) rgba[3] = static_cast(255.0f * weight/max); else rgba[3] = static_cast(255.0); m_FiberColors->InsertTypedTuple(counter, rgba); counter++; } } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } +void mitk::FiberBundle::SetSingleFiberColor(float r, float g, float b, unsigned int cellId, float alpha) +{ +// if (m_FiberColors==nullptr) + m_FiberColors = vtkSmartPointer::New(); + m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); + m_FiberColors->SetNumberOfComponents(4); + m_FiberColors->SetName("FIBER_COLORS"); + +// MITK_INFO << color->GetNumberOfTuples(); +// MITK_INFO << m_FiberColors->GetNumberOfTuples(); + + unsigned char rgba[4] = {0,0,0,0}; + unsigned int counter = 0; + + + for (unsigned int i=0; iGetNumberOfCells(); i++) + { + vtkCell* cell = m_FiberPolyData->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + + if (i==cellId) + { + for (int j=0; j(r); + rgba[1] = static_cast(b); + rgba[2] = static_cast(g); + rgba[3] = static_cast(alpha); +// m_FiberColors->InsertTypedTuple(j, rgba); + + m_FiberColors->InsertTypedTuple(counter, rgba); + counter++; + } + } + else { + for (int j=0; j(255); + rgba[1] = static_cast(255); + rgba[2] = static_cast(255); + rgba[3] = static_cast(alpha); +// m_FiberColors->InsertTypedTuple(j, rgba); + + m_FiberColors->InsertTypedTuple(counter, rgba); + counter++; + } + } + + } + +// MITK_INFO << m_FiberColors->GetNumberOfTuples(); + m_UpdateTime3D.Modified(); + m_UpdateTime2D.Modified(); +} + void mitk::FiberBundle::SetFiberColors(float r, float g, float b, float alpha) { m_FiberColors = vtkSmartPointer::New(); m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); m_FiberColors->SetNumberOfComponents(4); m_FiberColors->SetName("FIBER_COLORS"); unsigned char rgba[4] = {0,0,0,0}; for(long i=0; iGetNumberOfPoints(); ++i) { rgba[0] = static_cast(r); rgba[1] = static_cast(g); rgba[2] = static_cast(b); rgba[3] = static_cast(alpha); m_FiberColors->InsertTypedTuple(i, rgba); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } void mitk::FiberBundle::GenerateFiberIds() { if (m_FiberPolyData == nullptr) return; vtkSmartPointer idFiberFilter = vtkSmartPointer::New(); idFiberFilter->SetInputData(m_FiberPolyData); idFiberFilter->CellIdsOn(); // idFiberFilter->PointIdsOn(); // point id's are not needed idFiberFilter->SetCellIdsArrayName(FIBER_ID_ARRAY); idFiberFilter->FieldDataOn(); idFiberFilter->Update(); m_FiberIdDataSet = idFiberFilter->GetOutput(); } float mitk::FiberBundle::GetNumEpFractionInMask(ItkUcharImgType* mask, bool different_label) { vtkSmartPointer PolyData = m_FiberPolyData; MITK_INFO << "Calculating EP-Fraction"; boost::timer::progress_display disp(m_NumFibers); unsigned int in_mask = 0; for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); itk::Point startVertex =mitk::imv::GetItkPoint(points->GetPoint(0)); itk::Index<3> startIndex; mask->TransformPhysicalPointToIndex(startVertex, startIndex); itk::Point endVertex =mitk::imv::GetItkPoint(points->GetPoint(numPoints-1)); itk::Index<3> endIndex; mask->TransformPhysicalPointToIndex(endVertex, endIndex); if (mask->GetLargestPossibleRegion().IsInside(startIndex) && mask->GetLargestPossibleRegion().IsInside(endIndex)) { float v1 = mask->GetPixel(startIndex); if (v1 < 0.5f) continue; float v2 = mask->GetPixel(startIndex); if (v2 < 0.5f) continue; if (!different_label) ++in_mask; else if (fabs(v1-v2)>0.00001f) ++in_mask; } } return float(in_mask)/m_NumFibers; } std::tuple mitk::FiberBundle::GetDirectionalOverlap(ItkUcharImgType* mask, mitk::PeakImage::ItkPeakImageType* peak_image) { vtkSmartPointer PolyData = m_FiberPolyData; MITK_INFO << "Calculating overlap"; auto spacing = mask->GetSpacing(); boost::timer::progress_display disp(m_NumFibers); double length_sum = 0; double in_mask_length = 0; double aligned_length = 0; for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j startVertex =mitk::imv::GetItkPoint(points->GetPoint(j)); itk::Index<3> startIndex; itk::ContinuousIndex startIndexCont; mask->TransformPhysicalPointToIndex(startVertex, startIndex); mask->TransformPhysicalPointToContinuousIndex(startVertex, startIndexCont); itk::Point endVertex =mitk::imv::GetItkPoint(points->GetPoint(j + 1)); itk::Index<3> endIndex; itk::ContinuousIndex endIndexCont; mask->TransformPhysicalPointToIndex(endVertex, endIndex); mask->TransformPhysicalPointToContinuousIndex(endVertex, endIndexCont); vnl_vector_fixed< float, 3 > fdir; fdir[0] = endVertex[0] - startVertex[0]; fdir[1] = endVertex[1] - startVertex[1]; fdir[2] = endVertex[2] - startVertex[2]; fdir.normalize(); std::vector< std::pair< itk::Index<3>, double > > segments = mitk::imv::IntersectImage(spacing, startIndex, endIndex, startIndexCont, endIndexCont); for (std::pair< itk::Index<3>, double > segment : segments) { if ( mask->GetLargestPossibleRegion().IsInside(segment.first) && mask->GetPixel(segment.first) > 0 ) { in_mask_length += segment.second; mitk::PeakImage::ItkPeakImageType::IndexType idx4; idx4[0] = segment.first[0]; idx4[1] = segment.first[1]; idx4[2] = segment.first[2]; vnl_vector_fixed< float, 3 > peak; idx4[3] = 0; peak[0] = peak_image->GetPixel(idx4); idx4[3] = 1; peak[1] = peak_image->GetPixel(idx4); idx4[3] = 2; peak[2] = peak_image->GetPixel(idx4); if (std::isnan(peak[0]) || std::isnan(peak[1]) || std::isnan(peak[2]) || peak.magnitude()<0.0001f) continue; peak.normalize(); double f = 1.0 - std::acos(std::fabs(static_cast(dot_product(fdir, peak)))) * 2.0/itk::Math::pi; aligned_length += segment.second * f; } length_sum += segment.second; } } } if (length_sum<=0.0001) { MITK_INFO << "Fiber length sum is zero!"; return std::make_tuple(0,0); } return std::make_tuple(aligned_length/length_sum, in_mask_length/length_sum); } float mitk::FiberBundle::GetOverlap(ItkUcharImgType* mask) { vtkSmartPointer PolyData = m_FiberPolyData; MITK_INFO << "Calculating overlap"; auto spacing = mask->GetSpacing(); boost::timer::progress_display disp(m_NumFibers); double length_sum = 0; double in_mask_length = 0; for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; j startVertex =mitk::imv::GetItkPoint(points->GetPoint(j)); itk::Index<3> startIndex; itk::ContinuousIndex startIndexCont; mask->TransformPhysicalPointToIndex(startVertex, startIndex); mask->TransformPhysicalPointToContinuousIndex(startVertex, startIndexCont); itk::Point endVertex =mitk::imv::GetItkPoint(points->GetPoint(j + 1)); itk::Index<3> endIndex; itk::ContinuousIndex endIndexCont; mask->TransformPhysicalPointToIndex(endVertex, endIndex); mask->TransformPhysicalPointToContinuousIndex(endVertex, endIndexCont); std::vector< std::pair< itk::Index<3>, double > > segments = mitk::imv::IntersectImage(spacing, startIndex, endIndex, startIndexCont, endIndexCont); for (std::pair< itk::Index<3>, double > segment : segments) { if ( mask->GetLargestPossibleRegion().IsInside(segment.first) && mask->GetPixel(segment.first) > 0 ) in_mask_length += segment.second; length_sum += segment.second; } } } if (length_sum<=0.000001) { MITK_INFO << "Fiber length sum is zero!"; return 0; } return static_cast(in_mask_length/length_sum); } mitk::FiberBundle::Pointer mitk::FiberBundle::RemoveFibersOutside(ItkUcharImgType* mask, bool invert) { vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); std::vector< float > fib_weights; MITK_INFO << "Cutting fibers"; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); int newNumPoints = 0; if (numPoints>1) { for (int j=0; j itkP =mitk::imv::GetItkPoint(points->GetPoint(j)); itk::Index<3> idx; mask->TransformPhysicalPointToIndex(itkP, idx); bool inside = false; if ( mask->GetLargestPossibleRegion().IsInside(idx) && mask->GetPixel(idx)!=0 ) inside = true; if (inside && !invert) { vtkIdType id = vtkNewPoints->InsertNextPoint(itkP.GetDataPointer()); container->GetPointIds()->InsertNextId(id); newNumPoints++; } else if ( !inside && invert ) { vtkIdType id = vtkNewPoints->InsertNextPoint(itkP.GetDataPointer()); container->GetPointIds()->InsertNextId(id); newNumPoints++; } else if (newNumPoints>1) { fib_weights.push_back(this->GetFiberWeight(i)); vtkNewCells->InsertNextCell(container); newNumPoints = 0; container = vtkSmartPointer::New(); } else { newNumPoints = 0; container = vtkSmartPointer::New(); } } if (newNumPoints>1) { fib_weights.push_back(this->GetFiberWeight(i)); vtkNewCells->InsertNextCell(container); } } } vtkSmartPointer newFiberWeights = vtkSmartPointer::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(static_cast(fib_weights.size())); if (vtkNewCells->GetNumberOfCells()<=0) return nullptr; for (unsigned int i=0; iGetNumberOfValues(); i++) newFiberWeights->SetValue(i, fib_weights.at(i)); // vtkSmartPointer newFiberColors = vtkSmartPointer::New(); // newFiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4); // newFiberColors->SetNumberOfComponents(4); // newFiberColors->SetName("FIBER_COLORS"); // unsigned char rgba[4] = {0,0,0,0}; // for(long i=0; iGetNumberOfPoints(); ++i) // { // rgba[0] = (unsigned char) r; // rgba[1] = (unsigned char) g; // rgba[2] = (unsigned char) b; // rgba[3] = (unsigned char) alpha; // m_FiberColors->InsertTypedTuple(i, rgba); // } vtkSmartPointer newPolyData = vtkSmartPointer::New(); newPolyData->SetPoints(vtkNewPoints); newPolyData->SetLines(vtkNewCells); mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(newPolyData); newFib->SetFiberWeights(newFiberWeights); // newFib->Compress(0.1); newFib->SetTrackVisHeader(this->GetTrackVisHeader()); return newFib; } mitk::FiberBundle::Pointer mitk::FiberBundle::ExtractFiberSubset(DataNode* roi, DataStorage* storage) { if (roi==nullptr || !(dynamic_cast(roi->GetData()) || dynamic_cast(roi->GetData())) ) return nullptr; std::vector tmp = ExtractFiberIdSubset(roi, storage); if (tmp.size()<=0) return mitk::FiberBundle::New(); vtkSmartPointer weights = vtkSmartPointer::New(); vtkSmartPointer pTmp = GeneratePolyDataByIds(tmp, weights); mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(pTmp); fib->SetFiberWeights(weights); fib->SetTrackVisHeader(this->GetTrackVisHeader()); return fib; } std::vector mitk::FiberBundle::ExtractFiberIdSubset(DataNode *roi, DataStorage* storage) { std::vector result; if (roi==nullptr || roi->GetData()==nullptr) return result; mitk::PlanarFigureComposite::Pointer pfc = dynamic_cast(roi->GetData()); if (!pfc.IsNull()) // handle composite { DataStorage::SetOfObjects::ConstPointer children = storage->GetDerivations(roi); if (children->size()==0) return result; switch (pfc->getOperationType()) { case 0: // AND { MITK_INFO << "AND"; result = this->ExtractFiberIdSubset(children->ElementAt(0), storage); std::vector::iterator it; for (unsigned int i=1; iSize(); ++i) { std::vector inRoi = this->ExtractFiberIdSubset(children->ElementAt(i), storage); std::vector rest(std::min(result.size(),inRoi.size())); it = std::set_intersection(result.begin(), result.end(), inRoi.begin(), inRoi.end(), rest.begin() ); rest.resize( static_cast(it - rest.begin()) ); result = rest; } break; } case 1: // OR { MITK_INFO << "OR"; result = ExtractFiberIdSubset(children->ElementAt(0), storage); std::vector::iterator it; for (unsigned int i=1; iSize(); ++i) { it = result.end(); std::vector inRoi = ExtractFiberIdSubset(children->ElementAt(i), storage); result.insert(it, inRoi.begin(), inRoi.end()); } // remove duplicates sort(result.begin(), result.end()); it = unique(result.begin(), result.end()); result.resize( static_cast(it - result.begin()) ); break; } case 2: // NOT { MITK_INFO << "NOT"; for(unsigned int i=0; iGetNumFibers(); i++) result.push_back(i); std::vector::iterator it; for (unsigned int i=0; iSize(); ++i) { std::vector inRoi = ExtractFiberIdSubset(children->ElementAt(i), storage); std::vector rest(result.size()-inRoi.size()); it = std::set_difference(result.begin(), result.end(), inRoi.begin(), inRoi.end(), rest.begin() ); rest.resize( static_cast(it - rest.begin()) ); result = rest; } break; } } } else if ( dynamic_cast(roi->GetData()) ) // actual extraction { if ( dynamic_cast(roi->GetData()) ) { mitk::PlanarFigure::Pointer planarPoly = dynamic_cast(roi->GetData()); //create vtkPolygon using controlpoints from planarFigure polygon vtkSmartPointer polygonVtk = vtkSmartPointer::New(); for (unsigned int i=0; iGetNumberOfControlPoints(); ++i) { itk::Point p = planarPoly->GetWorldControlPoint(i); vtkIdType id = polygonVtk->GetPoints()->InsertNextPoint(p[0], p[1], p[2] ); polygonVtk->GetPointIds()->InsertNextId(id); } MITK_INFO << "Extracting with polygon"; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; jGetPoint(j, p1); double p2[3] = {0,0,0}; points->GetPoint(j+1, p2); double tolerance = 0.001; // Outputs double t = 0; // Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2)) double x[3] = {0,0,0}; // The coordinate of the intersection double pcoords[3] = {0,0,0}; int subId = 0; int iD = polygonVtk->IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId); if (iD!=0) { result.push_back(i); break; } } } } else if ( dynamic_cast(roi->GetData()) ) { mitk::PlanarFigure::Pointer planarFigure = dynamic_cast(roi->GetData()); Vector3D planeNormal = planarFigure->GetPlaneGeometry()->GetNormal(); planeNormal.Normalize(); //calculate circle radius mitk::Point3D V1w = planarFigure->GetWorldControlPoint(0); //centerPoint mitk::Point3D V2w = planarFigure->GetWorldControlPoint(1); //radiusPoint double radius = V1w.EuclideanDistanceTo(V2w); radius *= radius; MITK_INFO << "Extracting with circle"; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; jGetPoint(j, p1); double p2[3] = {0,0,0}; points->GetPoint(j+1, p2); // Outputs double t = 0; // Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2)) double x[3] = {0,0,0}; // The coordinate of the intersection int iD = vtkPlane::IntersectWithLine(p1,p2,planeNormal.GetDataPointer(),V1w.GetDataPointer(),t,x); if (iD!=0) { double dist = (x[0]-V1w[0])*(x[0]-V1w[0])+(x[1]-V1w[1])*(x[1]-V1w[1])+(x[2]-V1w[2])*(x[2]-V1w[2]); if( dist <= radius) { result.push_back(i); break; } } } } } return result; } return result; } void mitk::FiberBundle::UpdateFiberGeometry() { vtkSmartPointer cleaner = vtkSmartPointer::New(); cleaner->SetInputData(m_FiberPolyData); cleaner->PointMergingOff(); cleaner->Update(); m_FiberPolyData = cleaner->GetOutput(); m_FiberLengths.clear(); m_MeanFiberLength = 0; m_MedianFiberLength = 0; m_LengthStDev = 0; m_NumFibers = static_cast(m_FiberPolyData->GetNumberOfCells()); if (m_FiberColors==nullptr || m_FiberColors->GetNumberOfTuples()!=m_FiberPolyData->GetNumberOfPoints()) this->ColorFibersByOrientation(); if (m_FiberWeights->GetNumberOfValues()!=m_NumFibers) { m_FiberWeights = vtkSmartPointer::New(); m_FiberWeights->SetName("FIBER_WEIGHTS"); m_FiberWeights->SetNumberOfValues(m_NumFibers); this->SetFiberWeights(1); } if (m_NumFibers<=0) // no fibers present; apply default geometry { m_MinFiberLength = 0; m_MaxFiberLength = 0; mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->SetImageGeometry(false); float b[] = {0, 1, 0, 1, 0, 1}; geometry->SetFloatBounds(b); SetGeometry(geometry); return; } double b[6]; m_FiberPolyData->GetBounds(b); // calculate statistics for (int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); auto p = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); float length = 0; for (int j=0; jGetPoint(j, p1); double p2[3]; points->GetPoint(j+1, p2); double dist = std::sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2])); length += static_cast(dist); } m_FiberLengths.push_back(length); m_MeanFiberLength += length; if (i==0) { m_MinFiberLength = length; m_MaxFiberLength = length; } else { if (lengthm_MaxFiberLength) m_MaxFiberLength = length; } } m_MeanFiberLength /= m_NumFibers; std::vector< float > sortedLengths = m_FiberLengths; std::sort(sortedLengths.begin(), sortedLengths.end()); for (unsigned int i=0; i1) m_LengthStDev /= (m_NumFibers-1); else m_LengthStDev = 0; m_LengthStDev = std::sqrt(m_LengthStDev); m_MedianFiberLength = sortedLengths.at(m_NumFibers/2); mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New(); geometry->SetFloatBounds(b); this->SetGeometry(geometry); GetTrackVisHeader(); m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } float mitk::FiberBundle::GetFiberWeight(unsigned int fiber) const { return m_FiberWeights->GetValue(fiber); } void mitk::FiberBundle::SetFiberWeights(float newWeight) { for (int i=0; iGetNumberOfValues(); i++) m_FiberWeights->SetValue(i, newWeight); } void mitk::FiberBundle::SetFiberWeights(vtkSmartPointer weights) { if (m_NumFibers!=weights->GetNumberOfValues()) { MITK_INFO << "Weights array not equal to number of fibers! " << weights->GetNumberOfValues() << " vs " << m_NumFibers; return; } for (int i=0; iGetNumberOfValues(); i++) m_FiberWeights->SetValue(i, weights->GetValue(i)); m_FiberWeights->SetName("FIBER_WEIGHTS"); } void mitk::FiberBundle::SetFiberWeight(unsigned int fiber, float weight) { m_FiberWeights->SetValue(fiber, weight); } void mitk::FiberBundle::SetFiberColors(vtkSmartPointer fiberColors) { for(long i=0; iGetNumberOfPoints(); ++i) { unsigned char source[4] = {0,0,0,0}; fiberColors->GetTypedTuple(i, source); unsigned char target[4] = {0,0,0,0}; target[0] = source[0]; target[1] = source[1]; target[2] = source[2]; target[3] = source[3]; m_FiberColors->InsertTypedTuple(i, target); } m_UpdateTime3D.Modified(); m_UpdateTime2D.Modified(); } itk::Matrix< double, 3, 3 > mitk::FiberBundle::TransformMatrix(itk::Matrix< double, 3, 3 > m, double rx, double ry, double rz) { rx = rx*itk::Math::pi/180; ry = ry*itk::Math::pi/180; rz = rz*itk::Math::pi/180; itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity(); rotX[1][1] = cos(rx); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(rx); rotX[2][1] = -rotX[1][2]; itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity(); rotY[0][0] = cos(ry); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(ry); rotY[2][0] = -rotY[0][2]; itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity(); rotZ[0][0] = cos(rz); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(rz); rotZ[1][0] = -rotZ[0][1]; itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX; m = rot*m; return m; } void mitk::FiberBundle::TransformFibers(itk::ScalableAffineTransform< mitk::ScalarType >::Pointer transform) { vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; j p =mitk::imv::GetItkPoint(points->GetPoint(j)); p = transform->TransformPoint(p); vtkIdType id = vtkNewPoints->InsertNextPoint(p.GetDataPointer()); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::TransformFibers(double rx, double ry, double rz, double tx, double ty, double tz) { vnl_matrix_fixed< double, 3, 3 > rot = mitk::imv::GetRotationMatrixVnl(rx, ry, rz); mitk::BaseGeometry::Pointer geom = this->GetGeometry(); mitk::Point3D center = geom->GetCenter(); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vnl_vector_fixed< double, 3 > dir; dir[0] = p[0]-center[0]; dir[1] = p[1]-center[1]; dir[2] = p[2]-center[2]; dir = rot*dir; dir[0] += center[0]+tx; dir[1] += center[1]+ty; dir[2] += center[2]+tz; vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block()); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::RotateAroundAxis(double x, double y, double z) { x = x*itk::Math::pi/180; y = y*itk::Math::pi/180; z = z*itk::Math::pi/180; vnl_matrix_fixed< double, 3, 3 > rotX; rotX.set_identity(); rotX[1][1] = cos(x); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(x); rotX[2][1] = -rotX[1][2]; vnl_matrix_fixed< double, 3, 3 > rotY; rotY.set_identity(); rotY[0][0] = cos(y); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(y); rotY[2][0] = -rotY[0][2]; vnl_matrix_fixed< double, 3, 3 > rotZ; rotZ.set_identity(); rotZ[0][0] = cos(z); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(z); rotZ[1][0] = -rotZ[0][1]; mitk::BaseGeometry::Pointer geom = this->GetGeometry(); mitk::Point3D center = geom->GetCenter(); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vnl_vector_fixed< double, 3 > dir; dir[0] = p[0]-center[0]; dir[1] = p[1]-center[1]; dir[2] = p[2]-center[2]; dir = rotZ*rotY*rotX*dir; dir[0] += center[0]; dir[1] += center[1]; dir[2] += center[2]; vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block()); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::ScaleFibers(double x, double y, double z, bool subtractCenter) { MITK_INFO << "Scaling fibers"; boost::timer::progress_display disp(m_NumFibers); mitk::BaseGeometry* geom = this->GetGeometry(); mitk::Point3D c = geom->GetCenter(); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); if (subtractCenter) { p[0] -= c[0]; p[1] -= c[1]; p[2] -= c[2]; } p[0] *= x; p[1] *= y; p[2] *= z; if (subtractCenter) { p[0] += c[0]; p[1] += c[1]; p[2] += c[2]; } vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::TranslateFibers(double x, double y, double z) { vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); p[0] += x; p[1] += y; p[2] += z; vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::MirrorFibers(unsigned int axis) { if (axis>2) return; MITK_INFO << "Mirroring fibers"; boost::timer::progress_display disp(m_NumFibers); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); p[axis] = -p[axis]; vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::RemoveDir(vnl_vector_fixed dir, double threshold) { dir.normalize(); vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); boost::timer::progress_display disp(static_cast(m_FiberPolyData->GetNumberOfCells())); for (int i=0; iGetNumberOfCells(); i++) { ++disp ; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); // calculate curvatures vtkSmartPointer container = vtkSmartPointer::New(); bool discard = false; for (int j=0; jGetPoint(j, p1); double p2[3]; points->GetPoint(j+1, p2); vnl_vector_fixed< double, 3 > v1; v1[0] = p2[0]-p1[0]; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; if (v1.magnitude()>0.001) { v1.normalize(); if (fabs(dot_product(v1,dir))>threshold) { discard = true; break; } } } if (!discard) { for (int j=0; jGetPoint(j, p1); vtkIdType id = vtkNewPoints->InsertNextPoint(p1); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); // UpdateColorCoding(); // UpdateFiberGeometry(); } bool mitk::FiberBundle::ApplyCurvatureThreshold(float minRadius, bool deleteFibers) { if (minRadius<0) return true; vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); MITK_INFO << "Applying curvature threshold"; boost::timer::progress_display disp(static_cast(m_FiberPolyData->GetNumberOfCells())); for (int i=0; iGetNumberOfCells(); i++) { ++disp ; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); // calculate curvatures vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j, p1); double p2[3]; points->GetPoint(j+1, p2); double p3[3]; points->GetPoint(j+2, p3); vnl_vector_fixed< float, 3 > v1, v2, v3; v1[0] = static_cast(p2[0]-p1[0]); v1[1] = static_cast(p2[1]-p1[1]); v1[2] = static_cast(p2[2]-p1[2]); v2[0] = static_cast(p3[0]-p2[0]); v2[1] = static_cast(p3[1]-p2[1]); v2[2] = static_cast(p3[2]-p2[2]); v3[0] = static_cast(p1[0]-p3[0]); v3[1] = static_cast(p1[1]-p3[1]); v3[2] = static_cast(p1[2]-p3[2]); float a = v1.magnitude(); float b = v2.magnitude(); float c = v3.magnitude(); float r = a*b*c/std::sqrt((a+b+c)*(a+b-c)*(b+c-a)*(a-b+c)); // radius of triangle via Heron's formula (area of triangle) vtkIdType id = vtkNewPoints->InsertNextPoint(p1); container->GetPointIds()->InsertNextId(id); if (deleteFibers && rInsertNextCell(container); container = vtkSmartPointer::New(); } else if (j==numPoints-3) { id = vtkNewPoints->InsertNextPoint(p2); container->GetPointIds()->InsertNextId(id); id = vtkNewPoints->InsertNextPoint(p3); container->GetPointIds()->InsertNextId(id); vtkNewCells->InsertNextCell(container); } } } if (vtkNewCells->GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); return true; } bool mitk::FiberBundle::RemoveShortFibers(float lengthInMM) { MITK_INFO << "Removing short fibers"; if (lengthInMM<=0 || lengthInMMm_MaxFiberLength) // can't remove all fibers { MITK_WARN << "Process aborted. No fibers would be left!"; return false; } vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); float min = m_MaxFiberLength; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (m_FiberLengths.at(i)>=lengthInMM) { vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); if (m_FiberLengths.at(i)GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); return true; } bool mitk::FiberBundle::RemoveLongFibers(float lengthInMM) { if (lengthInMM<=0 || lengthInMM>m_MaxFiberLength) return true; if (lengthInMM vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); MITK_INFO << "Removing long fibers"; boost::timer::progress_display disp(m_NumFibers); for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (m_FiberLengths.at(i)<=lengthInMM) { vtkSmartPointer container = vtkSmartPointer::New(); for (int j=0; jGetPoint(j); vtkIdType id = vtkNewPoints->InsertNextPoint(p); container->GetPointIds()->InsertNextId(id); } vtkNewCells->InsertNextCell(container); } } if (vtkNewCells->GetNumberOfCells()<=0) return false; m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); return true; } void mitk::FiberBundle::ResampleSpline(float pointDistance, double tension, double continuity, double bias ) { if (pointDistance<=0) return; vtkSmartPointer vtkSmoothPoints = vtkSmartPointer::New(); //in smoothpoints the interpolated points representing a fiber are stored. //in vtkcells all polylines are stored, actually all id's of them are stored vtkSmartPointer vtkSmoothCells = vtkSmartPointer::New(); //cellcontainer for smoothed lines MITK_INFO << "Smoothing fibers"; vtkSmartPointer newFiberWeights = vtkSmartPointer::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(m_NumFibers); std::vector< vtkSmartPointer > resampled_streamlines; resampled_streamlines.resize(m_NumFibers); boost::timer::progress_display disp(m_NumFibers); #pragma omp parallel for for (int i=0; i(m_NumFibers); i++) { vtkSmartPointer newPoints = vtkSmartPointer::New(); float length = 0; #pragma omp critical { length = m_FiberLengths.at(static_cast(i)); ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; jInsertNextPoint(points->GetPoint(j)); } int sampling = static_cast(std::ceil(length/pointDistance)); vtkSmartPointer xSpline = vtkSmartPointer::New(); vtkSmartPointer ySpline = vtkSmartPointer::New(); vtkSmartPointer zSpline = vtkSmartPointer::New(); xSpline->SetDefaultBias(bias); xSpline->SetDefaultTension(tension); xSpline->SetDefaultContinuity(continuity); ySpline->SetDefaultBias(bias); ySpline->SetDefaultTension(tension); ySpline->SetDefaultContinuity(continuity); zSpline->SetDefaultBias(bias); zSpline->SetDefaultTension(tension); zSpline->SetDefaultContinuity(continuity); vtkSmartPointer spline = vtkSmartPointer::New(); spline->SetXSpline(xSpline); spline->SetYSpline(ySpline); spline->SetZSpline(zSpline); spline->SetPoints(newPoints); vtkSmartPointer functionSource = vtkSmartPointer::New(); functionSource->SetParametricFunction(spline); functionSource->SetUResolution(sampling); functionSource->SetVResolution(sampling); functionSource->SetWResolution(sampling); functionSource->Update(); vtkPolyData* outputFunction = functionSource->GetOutput(); vtkPoints* tmpSmoothPnts = outputFunction->GetPoints(); //smoothPoints of current fiber vtkSmartPointer smoothLine = vtkSmartPointer::New(); #pragma omp critical { for (int j=0; jGetNumberOfPoints(); j++) { vtkIdType id = vtkSmoothPoints->InsertNextPoint(tmpSmoothPnts->GetPoint(j)); smoothLine->GetPointIds()->InsertNextId(id); } resampled_streamlines[static_cast(i)] = smoothLine; } } for (auto container : resampled_streamlines) { vtkSmoothCells->InsertNextCell(container); } m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkSmoothPoints); m_FiberPolyData->SetLines(vtkSmoothCells); this->SetFiberPolyData(m_FiberPolyData, true); } void mitk::FiberBundle::ResampleSpline(float pointDistance) { ResampleSpline(pointDistance, 0, 0, 0 ); } unsigned int mitk::FiberBundle::GetNumberOfPoints() const { unsigned int points = 0; for (int i=0; iGetNumberOfCells(); i++) { vtkCell* cell = m_FiberPolyData->GetCell(i); points += cell->GetNumberOfPoints(); } return points; } void mitk::FiberBundle::Compress(float error) { vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); MITK_INFO << "Compressing fibers with max. error " << error << "mm"; unsigned int numRemovedPoints = 0; boost::timer::progress_display disp(static_cast(m_FiberPolyData->GetNumberOfCells())); vtkSmartPointer newFiberWeights = vtkSmartPointer::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(m_NumFibers); #pragma omp parallel for for (int i=0; i(m_FiberPolyData->GetNumberOfCells()); i++) { std::vector< vnl_vector_fixed< double, 3 > > vertices; float weight = 1; #pragma omp critical { ++disp; weight = m_FiberWeights->GetValue(i); vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; jGetPoint(j, cand); vnl_vector_fixed< double, 3 > candV; candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; vertices.push_back(candV); } } // calculate curvatures auto numPoints = vertices.size(); std::vector< int > removedPoints; removedPoints.resize(numPoints, 0); removedPoints[0]=-1; removedPoints[numPoints-1]=-1; vtkSmartPointer container = vtkSmartPointer::New(); unsigned int remCounter = 0; bool pointFound = true; while (pointFound) { pointFound = false; double minError = static_cast(error); unsigned int removeIndex = 0; for (unsigned int j=0; j candV = vertices.at(j); int validP = -1; vnl_vector_fixed< double, 3 > pred; for (int k=static_cast(j)-1; k>=0; k--) if (removedPoints[static_cast(k)]<=0) { pred = vertices.at(static_cast(k)); validP = k; break; } int validS = -1; vnl_vector_fixed< double, 3 > succ; for (unsigned int k=j+1; k(k); break; } if (validP>=0 && validS>=0) { double a = (candV-pred).magnitude(); double b = (candV-succ).magnitude(); double c = (pred-succ).magnitude(); double s=0.5*(a+b+c); double hc=(2.0/c)*sqrt(fabs(s*(s-a)*(s-b)*(s-c))); if (hcInsertNextPoint(vertices.at(j).data_block()); container->GetPointIds()->InsertNextId(id); } } } #pragma omp critical { newFiberWeights->SetValue(vtkNewCells->GetNumberOfCells(), weight); numRemovedPoints += remCounter; vtkNewCells->InsertNextCell(container); } } if (vtkNewCells->GetNumberOfCells()>0) { MITK_INFO << "Removed points: " << numRemovedPoints; SetFiberWeights(newFiberWeights); m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } } void mitk::FiberBundle::ResampleToNumPoints(unsigned int targetPoints) { if (targetPoints<2) mitkThrow() << "Minimum two points required for resampling!"; MITK_INFO << "Resampling fibers (number of points " << targetPoints << ")"; bool unequal_fibs = true; while (unequal_fibs) { vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); vtkSmartPointer newFiberWeights = vtkSmartPointer::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(m_NumFibers); unequal_fibs = false; + MITK_INFO << "Start"; +// cv::parallel_for_(cv::Range(0, m_FiberPolyData->GetNumberOfCells()), [&](const cv::Range &range) +// { +// for (int i = range.start; i < range.end; i++) for (unsigned int i=0; iGetNumberOfCells(); i++) { std::vector< vnl_vector_fixed< double, 3 > > vertices; float weight = 1; double seg_len = 0; { weight = m_FiberWeights->GetValue(i); vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); if (numPoints!=targetPoints) seg_len = static_cast(this->GetFiberLength(i)/(targetPoints-1)); vtkPoints* points = cell->GetPoints(); for (int j=0; jGetPoint(j, cand); vnl_vector_fixed< double, 3 > candV; candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; vertices.push_back(candV); } } vtkSmartPointer container = vtkSmartPointer::New(); vnl_vector_fixed< double, 3 > lastV = vertices.at(0); { vtkIdType id = vtkNewPoints->InsertNextPoint(lastV.data_block()); container->GetPointIds()->InsertNextId(id); } for (unsigned int j=1; j vec = vertices.at(j) - lastV; double new_dist = vec.magnitude(); if (new_dist >= seg_len && seg_len>0) { vnl_vector_fixed< double, 3 > newV = lastV; if ( new_dist-seg_len <= mitk::eps ) { vec.normalize(); newV += vec * seg_len; } else { // intersection between sphere (radius 'pointDistance', center 'lastV') and line (direction 'd' and point 'p') vnl_vector_fixed< double, 3 > p = vertices.at(j-1); vnl_vector_fixed< double, 3 > d = vertices.at(j) - p; double a = d[0]*d[0] + d[1]*d[1] + d[2]*d[2]; double b = 2 * (d[0] * (p[0] - lastV[0]) + d[1] * (p[1] - lastV[1]) + d[2] * (p[2] - lastV[2])); double c = (p[0] - lastV[0])*(p[0] - lastV[0]) + (p[1] - lastV[1])*(p[1] - lastV[1]) + (p[2] - lastV[2])*(p[2] - lastV[2]) - seg_len*seg_len; double v1 =(-b + std::sqrt(b*b-4*a*c))/(2*a); double v2 =(-b - std::sqrt(b*b-4*a*c))/(2*a); if (v1>0) newV = p + d * v1; else if (v2>0) newV = p + d * v2; else MITK_INFO << "ERROR1 - linear resampling"; j--; } //#pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(newV.data_block()); container->GetPointIds()->InsertNextId(id); } lastV = newV; } else if ( (j==vertices.size()-1 && new_dist>0.0001) || seg_len<=0.0000001) { //#pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(vertices.at(j).data_block()); container->GetPointIds()->InsertNextId(id); } } } //#pragma omp critical { newFiberWeights->SetValue(vtkNewCells->GetNumberOfCells(), weight); vtkNewCells->InsertNextCell(container); if (container->GetNumberOfPoints()!=targetPoints) unequal_fibs = true; } } +// }); +// MITK_INFO << "Done"; if (vtkNewCells->GetNumberOfCells()>0) { SetFiberWeights(newFiberWeights); m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } } } void mitk::FiberBundle::ResampleLinear(double pointDistance) { vtkSmartPointer vtkNewPoints = vtkSmartPointer::New(); vtkSmartPointer vtkNewCells = vtkSmartPointer::New(); MITK_INFO << "Resampling fibers (linear)"; boost::timer::progress_display disp(static_cast(m_FiberPolyData->GetNumberOfCells())); vtkSmartPointer newFiberWeights = vtkSmartPointer::New(); newFiberWeights->SetName("FIBER_WEIGHTS"); newFiberWeights->SetNumberOfValues(m_NumFibers); std::vector< vtkSmartPointer > resampled_streamlines; resampled_streamlines.resize(static_cast(m_FiberPolyData->GetNumberOfCells())); #pragma omp parallel for for (int i=0; i(m_FiberPolyData->GetNumberOfCells()); i++) { std::vector< vnl_vector_fixed< double, 3 > > vertices; #pragma omp critical { ++disp; vtkCell* cell = m_FiberPolyData->GetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); for (int j=0; jGetPoint(j, cand); vnl_vector_fixed< double, 3 > candV; candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; vertices.push_back(candV); } } vtkSmartPointer container = vtkSmartPointer::New(); vnl_vector_fixed< double, 3 > lastV = vertices.at(0); #pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(lastV.data_block()); container->GetPointIds()->InsertNextId(id); } for (unsigned int j=1; j vec = vertices.at(j) - lastV; double new_dist = vec.magnitude(); if (new_dist >= pointDistance) { vnl_vector_fixed< double, 3 > newV = lastV; if ( new_dist-pointDistance <= mitk::eps ) { vec.normalize(); newV += vec * pointDistance; } else { // intersection between sphere (radius 'pointDistance', center 'lastV') and line (direction 'd' and point 'p') vnl_vector_fixed< double, 3 > p = vertices.at(j-1); vnl_vector_fixed< double, 3 > d = vertices.at(j) - p; double a = d[0]*d[0] + d[1]*d[1] + d[2]*d[2]; double b = 2 * (d[0] * (p[0] - lastV[0]) + d[1] * (p[1] - lastV[1]) + d[2] * (p[2] - lastV[2])); double c = (p[0] - lastV[0])*(p[0] - lastV[0]) + (p[1] - lastV[1])*(p[1] - lastV[1]) + (p[2] - lastV[2])*(p[2] - lastV[2]) - pointDistance*pointDistance; double v1 =(-b + std::sqrt(b*b-4*a*c))/(2*a); double v2 =(-b - std::sqrt(b*b-4*a*c))/(2*a); if (v1>0) newV = p + d * v1; else if (v2>0) newV = p + d * v2; else MITK_INFO << "ERROR1 - linear resampling"; j--; } #pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(newV.data_block()); container->GetPointIds()->InsertNextId(id); } lastV = newV; } else if (j==vertices.size()-1 && new_dist>0.0001) { #pragma omp critical { vtkIdType id = vtkNewPoints->InsertNextPoint(vertices.at(j).data_block()); container->GetPointIds()->InsertNextId(id); } } } #pragma omp critical { resampled_streamlines[static_cast(i)] = container; } } for (auto container : resampled_streamlines) { vtkNewCells->InsertNextCell(container); } if (vtkNewCells->GetNumberOfCells()>0) { m_FiberPolyData = vtkSmartPointer::New(); m_FiberPolyData->SetPoints(vtkNewPoints); m_FiberPolyData->SetLines(vtkNewCells); this->SetFiberPolyData(m_FiberPolyData, true); } } // reapply selected colorcoding in case PolyData structure has changed bool mitk::FiberBundle::Equals(mitk::FiberBundle* fib, double eps) { if (fib==nullptr) { MITK_INFO << "Reference bundle is nullptr!"; return false; } if (m_NumFibers!=fib->GetNumFibers()) { MITK_INFO << "Unequal number of fibers!"; MITK_INFO << m_NumFibers << " vs. " << fib->GetNumFibers(); return false; } for (unsigned int i=0; iGetCell(i); auto numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); vtkCell* cell2 = fib->GetFiberPolyData()->GetCell(i); auto numPoints2 = cell2->GetNumberOfPoints(); vtkPoints* points2 = cell2->GetPoints(); if (numPoints2!=numPoints) { MITK_INFO << "Unequal number of points in fiber " << i << "!"; MITK_INFO << numPoints2 << " vs. " << numPoints; return false; } for (int j=0; jGetPoint(j); double* p2 = points2->GetPoint(j); if (fabs(p1[0]-p2[0])>eps || fabs(p1[1]-p2[1])>eps || fabs(p1[2]-p2[2])>eps) { MITK_INFO << "Unequal points in fiber " << i << " at position " << j << "!"; MITK_INFO << "p1: " << p1[0] << ", " << p1[1] << ", " << p1[2]; MITK_INFO << "p2: " << p2[0] << ", " << p2[1] << ", " << p2[2]; return false; } } } return true; } void mitk::FiberBundle::PrintSelf(std::ostream &os, itk::Indent indent) const { os << indent << "Number of fibers: " << this->GetNumFibers() << std::endl; os << indent << "Min. fiber length: " << this->GetMinFiberLength() << std::endl; os << indent << "Max. fiber length: " << this->GetMaxFiberLength() << std::endl; os << indent << "Mean fiber length: " << this->GetMeanFiberLength() << std::endl; os << indent << "Median fiber length: " << this->GetMedianFiberLength() << std::endl; os << indent << "STDEV fiber length: " << this->GetLengthStDev() << std::endl; os << indent << "Number of points: " << this->GetNumberOfPoints() << std::endl; os << indent << "Extent x: " << this->GetGeometry()->GetExtentInMM(0) << "mm" << std::endl; os << indent << "Extent y: " << this->GetGeometry()->GetExtentInMM(1) << "mm" << std::endl; os << indent << "Extent z: " << this->GetGeometry()->GetExtentInMM(2) << "mm" << std::endl; os << indent << "Diagonal: " << this->GetGeometry()->GetDiagonalLength() << "mm" << std::endl; os << "\nReference geometry:" << std::endl; os << indent << "Size: [" << std::defaultfloat << m_TrackVisHeader.dim[0] << " " << m_TrackVisHeader.dim[1] << " " << m_TrackVisHeader.dim[2] << "]" << std::endl; os << indent << "Voxel size: [" << m_TrackVisHeader.voxel_size[0] << " " << m_TrackVisHeader.voxel_size[1] << " " << m_TrackVisHeader.voxel_size[2] << "]" << std::endl; os << indent << "Origin: [" << m_TrackVisHeader.origin[0] << " " << m_TrackVisHeader.origin[1] << " " << m_TrackVisHeader.origin[2] << "]" << std::endl; os << indent << "Matrix: " << std::scientific << std::endl; os << indent << "[[" << m_TrackVisHeader.vox_to_ras[0][0] << ", " << m_TrackVisHeader.vox_to_ras[0][1] << ", " << m_TrackVisHeader.vox_to_ras[0][2] << ", " << m_TrackVisHeader.vox_to_ras[0][3] << "]" << std::endl; os << indent << " [" << m_TrackVisHeader.vox_to_ras[1][0] << ", " << m_TrackVisHeader.vox_to_ras[1][1] << ", " << m_TrackVisHeader.vox_to_ras[1][2] << ", " << m_TrackVisHeader.vox_to_ras[1][3] << "]" << std::endl; os << indent << " [" << m_TrackVisHeader.vox_to_ras[2][0] << ", " << m_TrackVisHeader.vox_to_ras[2][1] << ", " << m_TrackVisHeader.vox_to_ras[2][2] << ", " << m_TrackVisHeader.vox_to_ras[2][3] << "]" << std::endl; os << indent << " [" << m_TrackVisHeader.vox_to_ras[3][0] << ", " << m_TrackVisHeader.vox_to_ras[3][1] << ", " << m_TrackVisHeader.vox_to_ras[3][2] << ", " << m_TrackVisHeader.vox_to_ras[3][3] << "]]" << std::defaultfloat << std::endl; if (m_FiberWeights!=nullptr) { std::vector< float > weights; for (int i=0; iGetSize(); i++) weights.push_back(m_FiberWeights->GetValue(i)); std::sort(weights.begin(), weights.end()); os << "\nFiber weight statistics" << std::endl; os << indent << "Min: " << weights.front() << std::endl; os << indent << "1% quantile: " << weights.at(static_cast(weights.size()*0.01)) << std::endl; os << indent << "5% quantile: " << weights.at(static_cast(weights.size()*0.05)) << std::endl; os << indent << "25% quantile: " << weights.at(static_cast(weights.size()*0.25)) << std::endl; os << indent << "Median: " << weights.at(static_cast(weights.size()*0.5)) << std::endl; os << indent << "75% quantile: " << weights.at(static_cast(weights.size()*0.75)) << std::endl; os << indent << "95% quantile: " << weights.at(static_cast(weights.size()*0.95)) << std::endl; os << indent << "99% quantile: " << weights.at(static_cast(weights.size()*0.99)) << std::endl; os << indent << "Max: " << weights.back() << std::endl; } else os << indent << "\n\nNo fiber weight array found." << std::endl; Superclass::PrintSelf(os, 0); } mitk::FiberBundle::TrackVis_header mitk::FiberBundle::GetTrackVisHeader() { if (m_TrackVisHeader.hdr_size==0) { mitk::Geometry3D::Pointer geom = dynamic_cast(this->GetGeometry()); SetTrackVisHeader(geom); } return m_TrackVisHeader; } void mitk::FiberBundle::SetTrackVisHeader(const mitk::FiberBundle::TrackVis_header &TrackVisHeader) { m_TrackVisHeader = TrackVisHeader; } void mitk::FiberBundle::SetTrackVisHeader(mitk::BaseGeometry* geometry) { vtkSmartPointer< vtkMatrix4x4 > matrix = vtkSmartPointer< vtkMatrix4x4 >::New(); matrix->Identity(); if (geometry==nullptr) return; for(int i=0; i<3 ;i++) { m_TrackVisHeader.dim[i] = geometry->GetExtent(i); m_TrackVisHeader.voxel_size[i] = geometry->GetSpacing()[i]; m_TrackVisHeader.origin[i] = geometry->GetOrigin()[i]; matrix = geometry->GetVtkMatrix(); } for (int i=0; i<4; ++i) for (int j=0; j<4; ++j) m_TrackVisHeader.vox_to_ras[i][j] = matrix->GetElement(i, j); m_TrackVisHeader.n_scalars = 0; m_TrackVisHeader.n_properties = 0; sprintf(m_TrackVisHeader.voxel_order,"LPS"); m_TrackVisHeader.image_orientation_patient[0] = 1.0; m_TrackVisHeader.image_orientation_patient[1] = 0.0; m_TrackVisHeader.image_orientation_patient[2] = 0.0; m_TrackVisHeader.image_orientation_patient[3] = 0.0; m_TrackVisHeader.image_orientation_patient[4] = 1.0; m_TrackVisHeader.image_orientation_patient[5] = 0.0; m_TrackVisHeader.pad1[0] = 0; m_TrackVisHeader.pad1[1] = 0; m_TrackVisHeader.pad2[0] = 0; m_TrackVisHeader.pad2[1] = 0; m_TrackVisHeader.invert_x = 0; m_TrackVisHeader.invert_y = 0; m_TrackVisHeader.invert_z = 0; m_TrackVisHeader.swap_xy = 0; m_TrackVisHeader.swap_yz = 0; m_TrackVisHeader.swap_zx = 0; m_TrackVisHeader.n_count = 0; m_TrackVisHeader.version = 2; m_TrackVisHeader.hdr_size = 1000; std::string id = "TRACK"; strcpy(m_TrackVisHeader.id_string, id.c_str()); } /* ESSENTIAL IMPLEMENTATION OF SUPERCLASS METHODS */ void mitk::FiberBundle::UpdateOutputInformation() { } void mitk::FiberBundle::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::FiberBundle::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::FiberBundle::VerifyRequestedRegion() { return true; } void mitk::FiberBundle::SetRequestedRegion(const itk::DataObject* ) { } diff --git a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h index c6bbdf1..75a2008 100644 --- a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h +++ b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h @@ -1,247 +1,252 @@ /*=================================================================== 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 _MITK_FiberBundle_H #define _MITK_FiberBundle_H //includes for MITK datastructure #include #include #include #include #include #include #include #include //includes storing fiberdata #include #include #include #include #include #include #include #include #include +#include +#include +#include + namespace mitk { /** * \brief Base Class for Fiber Bundles; */ class MITKDIFFUSIONCORE_EXPORT FiberBundle : public BaseData { public: typedef itk::Image ItkUcharImgType; // fiber colorcodings static const char* FIBER_ID_ARRAY; void UpdateOutputInformation() override; void SetRequestedRegionToLargestPossibleRegion() override; bool RequestedRegionIsOutsideOfTheBufferedRegion() override; bool VerifyRequestedRegion() override; void SetRequestedRegion(const itk::DataObject*) override; mitkClassMacro( FiberBundle, BaseData ) itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkNewMacro1Param(Self, vtkSmartPointer) // custom constructor // colorcoding related methods void ColorSinglePoint(int f_idx, int p_idx, double rgb[3]); void ColorFibersByFiberWeights(bool opacity, LookupTable::LookupTableType type); void ColorFibersByCurvature(bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type); void ColorFibersByLength(bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type); void ColorFibersByScalarMap(mitk::Image::Pointer, bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type, double max_cap, bool interpolate=true); template void ColorFibersByScalarMap(typename itk::Image::Pointer, bool opacity, bool weight_fibers, mitk::LookupTable::LookupTableType type, double max_cap, bool interpolate=true); void ColorFibersByOrientation(); void SetFiberOpacity(vtkDoubleArray *FAValArray); void ResetFiberOpacity(); void SetFiberColors(vtkSmartPointer fiberColors); void SetFiberColors(float r, float g, float b, float alpha=255); + void SetSingleFiberColor(float r, float g, float b, unsigned int cellId, float alpha=255); vtkSmartPointer GetFiberColors() const { return m_FiberColors; } // fiber compression void Compress(float error = 0.0); // fiber resampling void ResampleSpline(float pointDistance=1); void ResampleSpline(float pointDistance, double tension, double continuity, double bias ); void ResampleLinear(double pointDistance=1); void ResampleToNumPoints(unsigned int targetPoints); mitk::FiberBundle::Pointer FilterByWeights(float weight_thr, bool invert=false); bool RemoveShortFibers(float lengthInMM); bool RemoveLongFibers(float lengthInMM); bool ApplyCurvatureThreshold(float minRadius, bool deleteFibers); void MirrorFibers(unsigned int axis); void RotateAroundAxis(double x, double y, double z); void TranslateFibers(double x, double y, double z); void ScaleFibers(double x, double y, double z, bool subtractCenter=true); void TransformFibers(double rx, double ry, double rz, double tx, double ty, double tz); void TransformFibers(itk::ScalableAffineTransform< mitk::ScalarType >::Pointer transform); void RemoveDir(vnl_vector_fixed dir, double threshold); template< class TType=float > void TransformPoint(itk::Point& point, itk::Matrix< TType, 3, 3>& rot, TType& tx, TType& ty, TType& tz) { mitk::Point3D center = this->GetGeometry()->GetCenter(); point[0] -= center[0]; point[1] -= center[1]; point[2] -= center[2]; point = rot*point; point[0] += center[0]+tx; point[1] += center[1]+ty; point[2] += center[2]+tz; } template< class TType=float > void TransformPoint(itk::Point& point, TType rx, TType ry, TType rz, TType tx, TType ty, TType tz) { auto rot = mitk::imv::GetRotationMatrixItk(rx, ry, rz); mitk::Point3D center = this->GetGeometry()->GetCenter(); point[0] -= center[0]; point[1] -= center[1]; point[2] -= center[2]; point = rot*point; point[0] += center[0]+tx; point[1] += center[1]+ty; point[2] += center[2]+tz; } itk::Matrix< double, 3, 3 > TransformMatrix(itk::Matrix< double, 3, 3 > m, double rx, double ry, double rz); // add/subtract fibers FiberBundle::Pointer AddBundle(FiberBundle* fib); mitk::FiberBundle::Pointer AddBundles(std::vector< mitk::FiberBundle::Pointer > fibs); FiberBundle::Pointer SubtractBundle(FiberBundle* fib); // fiber subset extraction FiberBundle::Pointer ExtractFiberSubset(DataNode *roi, DataStorage* storage); std::vector ExtractFiberIdSubset(DataNode* roi, DataStorage* storage); FiberBundle::Pointer RemoveFibersOutside(ItkUcharImgType* mask, bool invert=false); float GetOverlap(ItkUcharImgType* mask); std::tuple GetDirectionalOverlap(ItkUcharImgType* mask, mitk::PeakImage::ItkPeakImageType* peak_image); float GetNumEpFractionInMask(ItkUcharImgType* mask, bool different_label); mitk::FiberBundle::Pointer SubsampleFibers(float factor, bool random_seed); // get/set data float GetFiberLength(unsigned int index) const { return m_FiberLengths.at(index); } vtkSmartPointer GetFiberWeights() const { return m_FiberWeights; } float GetFiberWeight(unsigned int fiber) const; void SetFiberWeights(float newWeight); void SetFiberWeight(unsigned int fiber, float weight); void SetFiberWeights(vtkSmartPointer weights); void SetFiberPolyData(vtkSmartPointer, bool updateGeometry = true); vtkSmartPointer GetFiberPolyData() const; itkGetConstMacro( NumFibers, unsigned int) //itkGetMacro( FiberSampling, int) itkGetConstMacro( MinFiberLength, float ) itkGetConstMacro( MaxFiberLength, float ) itkGetConstMacro( MeanFiberLength, float ) itkGetConstMacro( MedianFiberLength, float ) itkGetConstMacro( LengthStDev, float ) itkGetConstMacro( UpdateTime2D, itk::TimeStamp ) itkGetConstMacro( UpdateTime3D, itk::TimeStamp ) void RequestUpdate2D(){ m_UpdateTime2D.Modified(); } void RequestUpdate3D(){ m_UpdateTime3D.Modified(); } void RequestUpdate(){ m_UpdateTime2D.Modified(); m_UpdateTime3D.Modified(); } unsigned int GetNumberOfPoints() const; // copy fiber bundle mitk::FiberBundle::Pointer GetDeepCopy(); // compare fiber bundles bool Equals(FiberBundle* fib, double eps=0.01); vtkSmartPointer GeneratePolyDataByIds(std::vector fiberIds, vtkSmartPointer weights); // Structure to hold metadata of a TrackVis file struct TrackVis_header { char id_string[6]; short int dim[3]; float voxel_size[3]; float origin[3]; short int n_scalars; char scalar_name[10][20]; short int n_properties; char property_name[10][20]; float vox_to_ras[4][4]; char reserved[444]; char voxel_order[4]; char pad2[4]; float image_orientation_patient[6]; char pad1[2]; unsigned char invert_x; unsigned char invert_y; unsigned char invert_z; unsigned char swap_xy; unsigned char swap_yz; unsigned char swap_zx; int n_count; int version; int hdr_size; }; TrackVis_header GetTrackVisHeader(); void SetTrackVisHeader(const TrackVis_header &TrackVisHeader); void SetTrackVisHeader(BaseGeometry *geometry); void PrintSelf(std::ostream &os, itk::Indent indent) const override; protected: FiberBundle( vtkPolyData* fiberPolyData = nullptr ); ~FiberBundle() override; void GenerateFiberIds(); void UpdateFiberGeometry(); private: // actual fiber container vtkSmartPointer m_FiberPolyData; // contains fiber ids vtkSmartPointer m_FiberIdDataSet; unsigned int m_NumFibers; vtkSmartPointer m_FiberColors; vtkSmartPointer m_FiberWeights; std::vector< float > m_FiberLengths; float m_MinFiberLength; float m_MaxFiberLength; float m_MeanFiberLength; float m_MedianFiberLength; float m_LengthStDev; itk::TimeStamp m_UpdateTime2D; itk::TimeStamp m_UpdateTime3D; TrackVis_header m_TrackVisHeader; }; } // namespace mitk #endif /* _MITK_FiberBundle_H */ diff --git a/Modules/FiberDissection/CMakeLists.txt b/Modules/FiberDissection/CMakeLists.txt new file mode 100644 index 0000000..9b030ee --- /dev/null +++ b/Modules/FiberDissection/CMakeLists.txt @@ -0,0 +1,5 @@ +MITK_CREATE_MODULE( + SUBPROJECTS MITK-Diffusion + INCLUDE_DIRS Interactor MachineLearning ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS MitkDiffusionCore +) diff --git a/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.cpp b/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.cpp new file mode 100644 index 0000000..e885d79 --- /dev/null +++ b/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.cpp @@ -0,0 +1,1207 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#include "mitkStreamlineInteractor.h" +//#include "mitkStreamlineMapper2D.h" + +// MITK includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// VTK includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +mitk::StreamlineInteractor::StreamlineInteractor() +{ + m_ColorForHighlight[0] = 1.0; + m_ColorForHighlight[1] = 0.5; + m_ColorForHighlight[2] = 0.0; + m_ColorForHighlight[3] = 1.0; + + // TODO if we want to get this configurable, the this is the recipe: + // - make the 2D mapper add corresponding properties to control "enabled" and "color" + // - make the interactor evaluate those properties + // - in an ideal world, modify the state machine on the fly and skip mouse move handling +} + +mitk::StreamlineInteractor::~StreamlineInteractor() +{ +} + +void mitk::StreamlineInteractor::ConnectActionsAndFunctions() +{ +// CONNECT_CONDITION("isoverstreamline", HasPickedHandle); + CONNECT_CONDITION("isoverstreamline", CheckSelection); + CONNECT_FUNCTION("selectstreamline", SelectStreamline); + + CONNECT_FUNCTION("addnegstreamline", AddStreamlineNegBundle); + CONNECT_FUNCTION("addposstreamline", AddStreamlinePosBundle); + CONNECT_FUNCTION("addnegtolabelstreamline", AddNegStreamlinetolabelsBundle); + CONNECT_FUNCTION("addpostolabelstreamline", AddPosStreamlinetolabelsBundle); +// CONNECT_FUNCTION("FeedUndoStack", FeedUndoStack); +} + +void mitk::StreamlineInteractor::SetNegativeNode(DataNode *node) +{ + +// DataInteractor::SetDataNode(node); + m_NegStreamlineNode = node; + m_NegStreamline= dynamic_cast(node->GetData()); + MITK_INFO << "Negative Node added"; +} + +void mitk::StreamlineInteractor::SetToLabelNode(DataNode *node) +{ + m_manStreamlineNode = node; + DataInteractor::SetDataNode(m_manStreamlineNode); + m_manStreamline = dynamic_cast(node->GetData()); + MITK_INFO << "Label node added"; +// m_init = false; + +} + +void mitk::StreamlineInteractor::SetPositiveNode(DataNode *node) +{ + + // DataInteractor::SetDataNode(node); + m_PosStreamlineNode = node; + m_PosStreamline= dynamic_cast(node->GetData()); + MITK_INFO << "Positive Node added"; +} + +void mitk::StreamlineInteractor::LabelfromPrediction(bool predlabeling) +{ + m_predlabeling = predlabeling; + +} + +bool mitk::StreamlineInteractor::CheckSelection(const InteractionEvent *interactionEvent) +{ + /* Save Colorvector here*/ + + const auto *positionEvent = dynamic_cast(interactionEvent); + if (positionEvent != nullptr) + { + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + + + if (picker->GetCellId()==-1 && m_predlabeling==false) + { +// m_manStreamline->SetFiberColors(255, 255, 255); +// vtkSmartPointer FiberColors = m_manStreamline->m_FiberColors; + + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + else + { + + return true; + } + } + else { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + + + if (picker->GetCellId()==-1 && m_predlabeling==false) + { +// m_manStreamline->SetFiberColors(255, 255, 255); + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + else + { + + return true; + } + + } + + + } + else { +// m_manStreamline->SetFiberColors(255, 255, 255); + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + +} + +void mitk::StreamlineInteractor::SelectStreamline(StateMachineAction *, InteractionEvent *interactionEvent) +{ + auto *positionEvent = dynamic_cast(interactionEvent); + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + // } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + if (m_predlabeling==false) + { + vtkIdType pickedCellID = picker->GetCellId(); + m_manStreamline->SetSingleFiberColor(0.0, 255.0, 0.0, pickedCellID); +// m_manStreamline->SetFloatProperty("shape.tuberadius", 1.0) + } + } + else { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + // } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + if (m_predlabeling==false) + { + vtkIdType pickedCellID = picker->GetCellId(); + m_manStreamline->SetSingleFiberColor(0.0, 255.0, 0.0, pickedCellID); +// m_manStreamline->SetFloatProperty("shape.tuberadius", 1.0); + } + } + + + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void mitk::StreamlineInteractor::AddStreamlinePosBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "PositiveBundle clicked"; + DataInteractor::SetDataNode(m_manStreamlineNode); + + auto positionEvent = dynamic_cast(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_PosStreamline = mitk::FiberBundle::New(vNewPolyData); + m_PosStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_PosStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_PosStreamline->SetFiberColors(0, 255, 0); +// m_PosStreamline->SetFiberWeights(m_PosStreamline->GetFiberWeights()); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + if (m_predlabeling==false) + { + vtkSmartPointer vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + + counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_PosStreamline = mitk::FiberBundle::New(vNewPolyData); + m_PosStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_PosStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_PosStreamline->SetFiberColors(0, 255, 0); +// m_PosStreamline->SetFiberWeights(m_PosStreamline->GetFiberWeights()); + + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + + counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractor::AddStreamlineNegBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "NegativeBundle clicked"; + + DataInteractor::SetDataNode(m_manStreamlineNode); + + auto positionEvent = dynamic_cast(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_NegStreamline = mitk::FiberBundle::New(vNewPolyData); + m_NegStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_NegStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_NegStreamline->SetFiberColors(255, 0, 0); +// m_NegStreamline->SetFiberWeights(m_NegStreamline->GetFiberWeights()); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + + counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_NegStreamline = mitk::FiberBundle::New(vNewPolyData); + m_NegStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_NegStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_NegStreamline->SetFiberColors(255, 0, 0); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + + counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractor::AddNegStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "TolabelBundle clicked"; + DataInteractor::SetDataNode(m_NegStreamlineNode); + + + auto positionEvent = dynamic_cast(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); +// m_manStreamline->SetFiberWeights(m_manStreamline->GetFiberWeights()); + + m_NegStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_NegStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); + + m_NegStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_NegStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractor::AddPosStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "TolabelBundle clicked"; + DataInteractor::SetDataNode(m_PosStreamlineNode); + + + auto positionEvent = dynamic_cast(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); +// m_manStreamline->SetFiberWeights(m_manStreamline->GetFiberWeights()); + + m_PosStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_PosStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); + + m_PosStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_PosStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + diff --git a/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.h b/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.h new file mode 100644 index 0000000..3b43f1e --- /dev/null +++ b/Modules/FiberDissection/Interactor/mitkStreamlineInteractor.h @@ -0,0 +1,123 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#ifndef mitkStreamlineInteractor_h +#define mitkStreamlineInteractor_h + + +#include "MitkFiberDissectionExports.h" + +// MITK includes +#include +#include +#include +#include + +// VTK includes +#include +#include + +// System includes +#include + + +namespace mitk +{ + class InteractionPositionEvent; + + //! Data interactor to pick streamlines via interaction + //! with a mitk::Streamline. + //! + //! + //! To determine what parts of the object are clicked during interaction, + //! the mappers (2D: custom mapper, 3D: regular surface mapper) are asked + //! for their VTK objects, picking is performed, and the picked point is + //! forwarded to the Streamline object for interpretation. + //! + //! The interactor fills the undo/redo stack with operations on the modified geometry. + //! + //! \sa Streamline + class MITKFIBERDISSECTION_EXPORT StreamlineInteractor : public DataInteractor + { + public: + mitkClassMacro(StreamlineInteractor, DataInteractor); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + //! The node holding the Fiberbundle for visual feedback. + //! This is the node that the interactor is primarily working on + //! (calls DataInteractor::SetDataNode). + + void SetNegativeNode(DataNode *node); + void SetToLabelNode(DataNode *node); + void SetPositiveNode(DataNode *node); + void LabelfromPrediction(bool predlabeling); + + protected: + + void AddStreamlineNegBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddStreamlinePosBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddNegStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddPosStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + bool CheckSelection(const InteractionEvent *interactionEvent); + + void SelectStreamline(StateMachineAction *, InteractionEvent *); + + + std::map> m_Picker; + + private: + StreamlineInteractor(); + ~StreamlineInteractor() override; + + //! Setup the relation between the XML state machine and this object's methods. + void ConnectActionsAndFunctions() override; + + //! State machine condition: successful Streamline picking + //! \return true when any part of the Streamline has been picked. +// bool HasPickedHandle(const InteractionEvent *); + +// void DecideInteraction(StateMachineAction *, InteractionEvent *interactionEvent); + +// //! Pick a Streamline handle from a 2D event (passing by the 2D mapper) +// Streamline::HandleType PickFrom2D(const InteractionPositionEvent *positionEvent); + +// //! Pick a Streamline handle from a 3D event +// //! (passing by the general surface mapper and the Streamline object) +// Streamline::HandleType PickFrom3D(const InteractionPositionEvent *positionEvent); + +// void UpdateHandleHighlight(); + + //! the Streamline used for visual feedback and picking + mitk::FiberBundle::Pointer m_NegStreamline; + mitk::FiberBundle::Pointer m_PosStreamline; + mitk::FiberBundle::Pointer m_manStreamline; + bool m_predlabeling; +// mitk::FiberBundle::Pointer m_visualStreamline; + mitk::DataNode::Pointer m_NegStreamlineNode; + mitk::DataNode::Pointer m_PosStreamlineNode; + mitk::DataNode::Pointer m_manStreamlineNode; +// mitk::DataNode::Pointer m_visualStreamlineNode; + + + + vtkSmartPointer m_extracted_streamline; + + double m_ColorForHighlight[4]; + + }; +} +#endif diff --git a/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.cpp b/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.cpp new file mode 100644 index 0000000..335500e --- /dev/null +++ b/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.cpp @@ -0,0 +1,1207 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#include "mitkStreamlineInteractorBrush.h" +//#include "mitkStreamlineMapper2D.h" + +// MITK includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// VTK includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +mitk::StreamlineInteractorBrush::StreamlineInteractorBrush() +{ + m_ColorForHighlight[0] = 1.0; + m_ColorForHighlight[1] = 0.5; + m_ColorForHighlight[2] = 0.0; + m_ColorForHighlight[3] = 1.0; + + // TODO if we want to get this configurable, the this is the recipe: + // - make the 2D mapper add corresponding properties to control "enabled" and "color" + // - make the interactor evaluate those properties + // - in an ideal world, modify the state machine on the fly and skip mouse move handling +} + +mitk::StreamlineInteractorBrush::~StreamlineInteractorBrush() +{ +} + +void mitk::StreamlineInteractorBrush::ConnectActionsAndFunctions() +{ +// CONNECT_CONDITION("isoverstreamline", HasPickedHandle); + CONNECT_CONDITION("isoverstreamline", CheckSelection); + CONNECT_FUNCTION("selectstreamline", SelectStreamline); + + CONNECT_FUNCTION("addnegstreamline", AddStreamlineNegBundle); + CONNECT_FUNCTION("addposstreamline", AddStreamlinePosBundle); + CONNECT_FUNCTION("addnegtolabelstreamline", AddNegStreamlinetolabelsBundle); + CONNECT_FUNCTION("addpostolabelstreamline", AddPosStreamlinetolabelsBundle); +// CONNECT_FUNCTION("FeedUndoStack", FeedUndoStack); +} + +void mitk::StreamlineInteractorBrush::SetNegativeNode(DataNode *node) +{ + +// DataInteractor::SetDataNode(node); + m_NegStreamlineNode = node; + m_NegStreamline= dynamic_cast(node->GetData()); + MITK_INFO << "Negative Node added"; +} + +void mitk::StreamlineInteractorBrush::SetToLabelNode(DataNode *node) +{ + m_manStreamlineNode = node; + DataInteractor::SetDataNode(m_manStreamlineNode); + m_manStreamline = dynamic_cast(node->GetData()); + MITK_INFO << "Label node added"; +// m_init = false; + +} + +void mitk::StreamlineInteractorBrush::SetPositiveNode(DataNode *node) +{ + + // DataInteractor::SetDataNode(node); + m_PosStreamlineNode = node; + m_PosStreamline= dynamic_cast(node->GetData()); + MITK_INFO << "Positive Node added"; +} + +void mitk::StreamlineInteractorBrush::LabelfromPrediction(bool predlabeling) +{ + m_predlabeling = predlabeling; + +} + +bool mitk::StreamlineInteractorBrush::CheckSelection(const InteractionEvent *interactionEvent) +{ + /* Save Colorvector here*/ + + const auto *positionEvent = dynamic_cast(interactionEvent); + if (positionEvent != nullptr) + { + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + + + if (picker->GetCellId()==-1 && m_predlabeling==false) + { +// m_manStreamline->SetFiberColors(255, 255, 255); +// vtkSmartPointer FiberColors = m_manStreamline->m_FiberColors; + + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + else + { + + return true; + } + } + else { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + + + if (picker->GetCellId()==-1 && m_predlabeling==false) + { +// m_manStreamline->SetFiberColors(255, 255, 255); + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + else + { + + return true; + } + + } + + + } + else { +// m_manStreamline->SetFiberColors(255, 255, 255); + RenderingManager::GetInstance()->RequestUpdateAll(); + return false; + } + +} + +void mitk::StreamlineInteractorBrush::SelectStreamline(StateMachineAction *, InteractionEvent *interactionEvent) +{ + auto *positionEvent = dynamic_cast(interactionEvent); + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + // } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + if (m_predlabeling==false) + { + vtkIdType pickedCellID = picker->GetCellId(); + m_manStreamline->SetSingleFiberColor(0.0, 255.0, 0.0, pickedCellID); +// m_manStreamline->SetFloatProperty("shape.tuberadius", 1.0) + } + } + else { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } + // } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + if (m_predlabeling==false) + { + vtkIdType pickedCellID = picker->GetCellId(); + m_manStreamline->SetSingleFiberColor(0.0, 255.0, 0.0, pickedCellID); +// m_manStreamline->SetFloatProperty("shape.tuberadius", 1.0); + } + } + + + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void mitk::StreamlineInteractorBrush::AddStreamlinePosBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "PositiveBundle clicked"; + DataInteractor::SetDataNode(m_manStreamlineNode); + + auto positionEvent = dynamic_cast(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_PosStreamline = mitk::FiberBundle::New(vNewPolyData); + m_PosStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_PosStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_PosStreamline->SetFiberColors(0, 255, 0); +// m_PosStreamline->SetFiberWeights(m_PosStreamline->GetFiberWeights()); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + if (m_predlabeling==false) + { + vtkSmartPointer vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + + counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_PosStreamline = mitk::FiberBundle::New(vNewPolyData); + m_PosStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_PosStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_PosStreamline->SetFiberColors(0, 255, 0); +// m_PosStreamline->SetFiberWeights(m_PosStreamline->GetFiberWeights()); + + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + + counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractorBrush::AddStreamlineNegBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "NegativeBundle clicked"; + + DataInteractor::SetDataNode(m_manStreamlineNode); + + auto positionEvent = dynamic_cast(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_NegStreamline = mitk::FiberBundle::New(vNewPolyData); + m_NegStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_NegStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_NegStreamline->SetFiberColors(255, 0, 0); +// m_NegStreamline->SetFiberWeights(m_NegStreamline->GetFiberWeights()); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + + counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_NegStreamline = mitk::FiberBundle::New(vNewPolyData); + m_NegStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_NegStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_NegStreamline->SetFiberColors(255, 0, 0); + + m_manStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_manStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + if (m_predlabeling==false) + { + vtkSmartPointer vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + + counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines2->InsertNextCell(container); + counter++; + + } + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints2); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines2); + m_manStreamline->SetFiberColors(255, 255, 255); + } + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractorBrush::AddNegStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "TolabelBundle clicked"; + DataInteractor::SetDataNode(m_NegStreamlineNode); + + + auto positionEvent = dynamic_cast(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); +// m_manStreamline->SetFiberWeights(m_manStreamline->GetFiberWeights()); + + m_NegStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_NegStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_NegStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); + + m_NegStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_NegStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + +void mitk::StreamlineInteractorBrush::AddPosStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent) +{ + MITK_INFO << "TolabelBundle clicked"; + DataInteractor::SetDataNode(m_PosStreamlineNode); + + + auto positionEvent = dynamic_cast(interactionEvent); + if (positionEvent == nullptr) + { + MITK_INFO << "no position"; + } + + if (interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D) + { +// m_PickedHandle = PickFrom2D(positionEvent); + + MITK_INFO << "2D"; + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard2D); + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else { + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(pickedCellID); + + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); +// m_manStreamline->SetFiberWeights(m_manStreamline->GetFiberWeights()); + + m_PosStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_PosStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + + + + + } + } + else + { + BaseRenderer *renderer = positionEvent->GetSender(); + + auto &picker = m_Picker[renderer]; +// if (picker == nullptr) +// { + + + picker = vtkSmartPointer::New(); + picker->SetTolerance(0.01); + auto mapper = GetDataNode()->GetMapper(BaseRenderer::Standard3D); + + + auto vtk_mapper = dynamic_cast(mapper); + if (vtk_mapper) + { // doing this each time is bizarre + picker->AddPickList(vtk_mapper->GetVtkProp(renderer)); + picker->PickFromListOn(); + } +// } + + auto displayPosition = positionEvent->GetPointerPositionOnScreen(); + + picker->Pick(displayPosition[0], displayPosition[1], 0, positionEvent->GetSender()->GetVtkRenderer()); + + vtkIdType pickedCellID = picker->GetCellId(); + + + if (picker->GetCellId()==-1) + { + MITK_INFO << "Nothing picked"; + } + else + { + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + unsigned int counter = 0; + for ( int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = m_manStreamline->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + // weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vtkCell* cell = m_PosStreamline->GetFiberPolyData()->GetCell(pickedCellID); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + // m_manStreamline = mitk::FiberBundle::New(vNewPolyData); + m_manStreamline->GetFiberPolyData()->SetPoints(vNewPoints); + m_manStreamline->GetFiberPolyData()->SetLines(vNewLines); + m_manStreamline->SetFiberColors(255, 255, 255); + + m_PosStreamline->GetFiberPolyData()->DeleteCell(pickedCellID); + m_PosStreamline->GetFiberPolyData()->RemoveDeletedCells(); + + } + } + RenderingManager::GetInstance()->RequestUpdateAll(); + } + diff --git a/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.h b/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.h new file mode 100644 index 0000000..deb5b8f --- /dev/null +++ b/Modules/FiberDissection/Interactor/mitkStreamlineInteractorBrush.h @@ -0,0 +1,123 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#ifndef mitkStreamlineInteractorBrush_h +#define mitkStreamlineInteractorBrush_h + + +#include "MitkFiberDissectionExports.h" + +// MITK includes +#include +#include +#include +#include + +// VTK includes +#include +#include + +// System includes +#include + + +namespace mitk +{ + class InteractionPositionEvent; + + //! Data interactor to pick streamlines via interaction + //! with a mitk::Streamline. + //! + //! + //! To determine what parts of the object are clicked during interaction, + //! the mappers (2D: custom mapper, 3D: regular surface mapper) are asked + //! for their VTK objects, picking is performed, and the picked point is + //! forwarded to the Streamline object for interpretation. + //! + //! The interactor fills the undo/redo stack with operations on the modified geometry. + //! + //! \sa Streamline + class MITKFIBERDISSECTION_EXPORT StreamlineInteractorBrush : public DataInteractor + { + public: + mitkClassMacro(StreamlineInteractorBrush, DataInteractor); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + //! The node holding the Fiberbundle for visual feedback. + //! This is the node that the interactor is primarily working on + //! (calls DataInteractor::SetDataNode). + + void SetNegativeNode(DataNode *node); + void SetToLabelNode(DataNode *node); + void SetPositiveNode(DataNode *node); + void LabelfromPrediction(bool predlabeling); + + protected: + + void AddStreamlineNegBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddStreamlinePosBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddNegStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + void AddPosStreamlinetolabelsBundle(StateMachineAction *, InteractionEvent *interactionEvent); + + bool CheckSelection(const InteractionEvent *interactionEvent); + + void SelectStreamline(StateMachineAction *, InteractionEvent *); + + + std::map> m_Picker; + + private: + StreamlineInteractorBrush(); + ~StreamlineInteractorBrush() override; + + //! Setup the relation between the XML state machine and this object's methods. + void ConnectActionsAndFunctions() override; + + //! State machine condition: successful Streamline picking + //! \return true when any part of the Streamline has been picked. +// bool HasPickedHandle(const InteractionEvent *); + +// void DecideInteraction(StateMachineAction *, InteractionEvent *interactionEvent); + +// //! Pick a Streamline handle from a 2D event (passing by the 2D mapper) +// Streamline::HandleType PickFrom2D(const InteractionPositionEvent *positionEvent); + +// //! Pick a Streamline handle from a 3D event +// //! (passing by the general surface mapper and the Streamline object) +// Streamline::HandleType PickFrom3D(const InteractionPositionEvent *positionEvent); + +// void UpdateHandleHighlight(); + + //! the Streamline used for visual feedback and picking + mitk::FiberBundle::Pointer m_NegStreamline; + mitk::FiberBundle::Pointer m_PosStreamline; + mitk::FiberBundle::Pointer m_manStreamline; + bool m_predlabeling; +// mitk::FiberBundle::Pointer m_visualStreamline; + mitk::DataNode::Pointer m_NegStreamlineNode; + mitk::DataNode::Pointer m_PosStreamlineNode; + mitk::DataNode::Pointer m_manStreamlineNode; +// mitk::DataNode::Pointer m_visualStreamlineNode; + + + + vtkSmartPointer m_extracted_streamline; + + double m_ColorForHighlight[4]; + + }; +} +#endif diff --git a/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.cpp b/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.cpp new file mode 100644 index 0000000..309c41f --- /dev/null +++ b/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.cpp @@ -0,0 +1,981 @@ +/*=================================================================== + +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 "mitkStreamlineFeatureExtractor.h" + +#define _USE_MATH_DEFINES +#include +#include +#include +#include + +namespace mitk{ + +StreamlineFeatureExtractor::StreamlineFeatureExtractor() + : m_NumPoints(40) +{ + +} + +StreamlineFeatureExtractor::~StreamlineFeatureExtractor() +{ + +} + +void StreamlineFeatureExtractor::SetTractogramPrediction(const mitk::FiberBundle::Pointer &TractogramPrediction) +{ + m_TractogramPrediction= TractogramPrediction; +} + +void StreamlineFeatureExtractor::SetTractogramGroundtruth(const mitk::FiberBundle::Pointer &TractogramGroundtruth) +{ + m_TractogramGroundtruth= TractogramGroundtruth; +} + +void StreamlineFeatureExtractor::SetTractogramPlus(const mitk::FiberBundle::Pointer &TractogramPlus) +{ + m_TractogramPlus = TractogramPlus; +} + +void StreamlineFeatureExtractor::SetTractogramMinus(const mitk::FiberBundle::Pointer &TractogramMinus) +{ + m_TractogramMinus = TractogramMinus; +} + +void StreamlineFeatureExtractor::SetTractogramPrototypes(const mitk::FiberBundle::Pointer &TractogramPrototypes, bool standard) +{ + if (standard) + { + MITK_INFO << "Use Standard Prototypes..."; + m_inputPrototypes = mitk::IOUtil::Load("/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/prototypes_599671_40.trk"); + } + else { + MITK_INFO << "Use individual Prototypes..."; + m_inputPrototypes = TractogramPrototypes; + } + + +} + +void StreamlineFeatureExtractor::SetActiveCycle(int &activeCycle) +{ + m_activeCycle= activeCycle; +} + + +void StreamlineFeatureExtractor::SetTractogramTest(const mitk::FiberBundle::Pointer &TractogramTest, std::string TractogramTestName) +{ +// std::string path = "/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/storage/"; +// path.append(TractogramTestName); + MITK_INFO << TractogramTestName; + m_TractogramTest= TractogramTest; +// auto s = std::to_string(m_NumPoints); +// m_DistancesTestName= path.append("_distances" + std::to_string(m_NumPoints) + "_" + std::to_string(m_activeCycle) + ".csv"); +} + +std::vector > StreamlineFeatureExtractor::ResampleFibers(mitk::FiberBundle::Pointer tractogram) +{ + MITK_INFO << "Infunction"; +// mitk::FiberBundle::Pointer temp_fib = tractogram->GetDeepCopy(); +// temp_fib->ResampleToNumPoints(m_NumPoints); + MITK_INFO << "Resampling Done"; + + std::vector< vnl_matrix > out_fib(tractogram->GetFiberPolyData()->GetNumberOfCells()); +//#pragma omp parallel for + for (int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = tractogram->GetFiberPolyData()->GetCell(i); + int numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vnl_matrix streamline; + streamline.set_size(3, m_NumPoints); + streamline.fill(0.0); + + for (int j=0; jGetPoint(j, cand); + + vnl_vector_fixed< float, 3 > candV; + candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; + streamline.set_column(j, candV); + } + +// out_fib.push_back(streamline); + out_fib.at(i)=streamline; + } +// }); + + + + return out_fib; +} + +std::vector > StreamlineFeatureExtractor::CalculateDmdf(std::vector > tractogram, + std::vector > prototypes) +{ + + std::vector< vnl_matrix > dist_vec(tractogram.size());// + MITK_INFO << "Start Calculating Dmdf"; +// cv::parallel_for_(cv::Range(0, tractogram.size()), [&](const cv::Range &range) +// { +// for (int i = range.start; i < range.end; i++) +#pragma omp parallel for + for (unsigned int i=0; i distances; + distances.set_size(1, prototypes.size()); + distances.fill(0.0); + for (unsigned int j=0; j single_distances; + single_distances.set_size(1, tractogram.at(0).cols()); + single_distances.fill(0.0); + vnl_matrix single_distances_flip; + single_distances_flip.set_size(1, tractogram.at(0).cols()); + single_distances_flip.fill(0.0); + for (unsigned int ik=0; ik single_distances.mean()) + { + distances.put(0,j, single_distances.mean()); + } + else { + distances.put(0,j, single_distances_flip.mean()); + } + } + dist_vec.at(i) = distances; + } +// }); + MITK_INFO << "Done Calculation"; + MITK_INFO << dist_vec.at(0).size(); + + return dist_vec; +} + +std::vector > StreamlineFeatureExtractor::MergeTractogram(std::vector > prototypes, + std::vector > positive_local_prototypes, + std::vector > negative_local_prototypes) +{ + unsigned int pos_locals; + unsigned int neg_locals; + + if (positive_local_prototypes.size() >= 50) + { + pos_locals= 50; + } + else { + pos_locals= positive_local_prototypes.size(); + } + + if (negative_local_prototypes.size() >= 50) + { + neg_locals = 50; + } + else { + neg_locals= negative_local_prototypes.size(); + } + + + + std::vector< vnl_matrix > merged_prototypes; + + for (unsigned int k=0; k StreamlineFeatureExtractor::Sort(std::vector sortingVector, int lengths, int start) +{ + std::vector index; + std::priority_queue> q; + + for (unsigned int i = 0; i < sortingVector.size(); ++i) + { + q.push(std::pair(sortingVector[i], i)); + } + + + for (int i = 0; i < lengths; ++i) + { + int ki = q.top().second; + if (i>=start) + { + index.push_back(ki); + } + q.pop(); + } + return index; +} + + +std::vector> StreamlineFeatureExtractor::GetData() +{ + MITK_INFO << "Start Function Get Data"; + + /*Vector which saves Prediction and Fibers to label based on uncertainty*/ + std::vector> index_vec; + +// int labels_arr [m_DistancesPlus.size()+m_DistancesMinus.size()]; + cv::Mat data; + cv::Mat labels_arr_vec; + + int size_plus = 0; + + + /*Create Trainingdata: Go through positive and negative Bundle and save distances as cv::Mat and create vector with labels*/ + for ( unsigned int i=0; i seeds; + for (int cont = 0; cont < labels_arr_vec.rows; cont++) + { + seeds.push_back(cont); + } + + cv::randShuffle(seeds); + cv::Mat labels_shuffled; + cv::Mat samples_shuffled; + + + + + for (int cont = 0; cont < labels_arr_vec.rows; cont++) + { + labels_shuffled.push_back(labels_arr_vec.row(seeds[cont])); + } + + for (int cont = 0; cont < labels_arr_vec.rows; cont++) + { + samples_shuffled.push_back(data.row(seeds[cont])); + } + + +// std::ofstream labelsfile; +// labelsfile.open("/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/storage/Labels_" + std::to_string(m_activeCycle) + ".csv"); +// labelsfile<< cv::format(labels_shuffled, cv::Formatter::FMT_CSV) << std::endl; +// labelsfile.close(); + +// std::ofstream featuresfile; +// featuresfile.open("/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/storage/Features_" + std::to_string(m_activeCycle) + ".csv"); +// featuresfile<< cv::format(samples_shuffled, cv::Formatter::FMT_CSV) << std::endl; +// featuresfile.close(); + + /*Create Dataset and initialize Classifier*/ + cv::Ptr m_traindata = cv::ml::TrainData::create(samples_shuffled, cv::ml::ROW_SAMPLE, labels_shuffled); + + + + + statistic_model= cv::ml::RTrees::create(); + auto criteria = cv::TermCriteria(); + criteria.type = cv::TermCriteria::MAX_ITER; +// criteria.epsilon = 1e-8; + criteria.maxCount = 400; + + statistic_model->setMaxDepth(10); //set to three +// statistic_model->setMinSampleCount(m_traindata->getNTrainSamples()*0.01); + statistic_model->setMinSampleCount(2); + statistic_model->setTruncatePrunedTree(false); + statistic_model->setUse1SERule(false); + statistic_model->setUseSurrogates(false); + statistic_model->setTermCriteria(criteria); + statistic_model->setCVFolds(1); + statistic_model->setPriors(newweight); + + + /*Train Classifier*/ + MITK_INFO << "Start Training"; + statistic_model->train(m_traindata); + + + /*Predict on Test Data*/ + MITK_INFO << "Predicting"; + + /*Create Dataset as cv::Mat*/ + cv::Mat dataTest; + for ( unsigned int i=0; i indexPrediction; + std::vector e(m_DistancesTest.size()); + std::vector pred(m_DistancesTest.size()); + + + /*For every Sample/Streamline get Prediction and entropy (=based on counts of Random Forest)*/ + MITK_INFO << "Predicting on all cores"; +#pragma omp parallel for + for (unsigned int i=0; ipredict(dataTest.row(i)); + pred.at(i)=val; + + #pragma omp critical + if (val==1) + { + indexPrediction.push_back(i); + } + + + cv::Mat vote; + statistic_model->getVotes(dataTest.row(i), vote, 0); + e.at(i) = ( -(vote.at(1,0)*1.0)/ (vote.at(1,0)+vote.at(1,1)) * log2((vote.at(1,0)*1.0)/ (vote.at(1,0)+vote.at(1,1))) - + (vote.at(1,1)*1.0)/ (vote.at(1,0)+vote.at(1,1))* log2((vote.at(1,1)*1.0)/ (vote.at(1,0)+vote.at(1,1)))); + + if (isnan(e.at(i))) + { + e.at(i)=0; + } + + } + MITK_INFO << "Done"; + + /*Save entropy values for analysis*/ + std::ofstream entropyfile; + entropyfile.open("/home/r948e/mycsv/entropydata_" + std::to_string(m_activeCycle) + ".csv"); + for (unsigned int i = 0; i < e.size(); i++) + { + entropyfile << e.at(i) << ' '; + } + entropyfile.close(); + + std::ofstream predictionfile; + predictionfile.open("/home/r948e/mycsv/predictiondata_" + std::to_string(m_activeCycle) + ".csv"); + for (unsigned int i = 0; i < pred.size(); i++) + { + predictionfile << pred.at(i) << ' '; + } + predictionfile.close(); + + + + + MITK_INFO << "--------------"; + MITK_INFO << "Prediction vector size:"; + MITK_INFO << indexPrediction.size(); + MITK_INFO << "Entropy vector size:"; + entropy_vector = e; + MITK_INFO << e.size(); + + MITK_INFO << "--------------"; + + /*Get index of most unertain data (lengths defines how many data is saved)*/ +// int lengths=500; + int lengths = std::count_if(e.begin(), e.end(),[&](auto const& val){ return val >= 0.95; }); + if (lengths>1500) + { + lengths=1500; + } +// else if (lengths>3000) +// { +// lengths=3000; +// } + + int lengthsCertain = std::count_if(e.begin(), e.end(),[&](auto const& val){ return val < 0.1; }); + + std::vector indexUnc = Sort(e, lengths, 0); + + std::vector indexCertain = Sort(e, e.size() , e.size()-lengthsCertain ); + +// std::vector indexCertainBetween = Sort(e, e.size()-lengthsCertain , lengths); + + MITK_INFO << "Index Certainty Vector size"; + MITK_INFO << indexCertain.size(); + +// for (unsigned int i=indexCertain.size(); i>=0; --i) + std::vector indexCertainNeg; + std::vector indexCertainPos; + + for (unsigned int i=0; i=0; --i) +// std::vector indexCertainBetweenNeg; +// std::vector indexCertainBetweenPos; + +// for (unsigned int i=0; i distances_matrix; + +// distances_matrix.set_size(lengths, lengths); +// distances_matrix.fill(0.0); + +// std::vector distances_matrix_mean; + + +// for (int i=0; i diff = m_DistancesTest.at(indexUnc.at(i)) - m_DistancesTest.at(indexUnc.at(k)); + +// /*Into the eucledean difference matrix, put the distance in Feature Space between every sample pair*/ +// distances_matrix.put(i,k,diff.absolute_value_sum()/m_DistancesTest.at(0).size()); + +// } +// /*For every Sample/Streamline get the mean eucledean distance to all other Samples => one value for every Sample*/ +//// distances_matrix_mean.push_back(distances_matrix.get_row(i).mean()); +//// MITK_INFO << meanval.at(i); + +// } + + + +// /*Index to find values in distancematrix*/ +// std::vector myidx; +// /*Index to find actual streamlines using indexUnc*/ +// std::vector indexUncDist; +// /*Start with the Streamline of the highest entropy, which is in distance_matrix at idx 0*/ +// myidx.push_back(0); +// indexUncDist.push_back(indexUnc.at(myidx.at(0))); + +// /*Vecotr that stores minvalues of current iteration*/ +// vnl_matrix cur_vec; +// cur_vec.set_size(1,lengths); +// cur_vec.fill(0.0); +// for (int i=0; i sum_matrix; +// sum_matrix.set_size(myidx.size(), lengths); +// sum_matrix.fill(0); +// for (unsigned int ii=0; ii> StreamlineFeatureExtractor::GetDistanceData(float &value) +{ + /*Vector which saves Fibers to be labeled based on fft subset uncertainty*/ + std::vector> index_vec; + + /*Get index of most unertain data (lengths defines how many data is saved)*/ +// int lengths=500; + MITK_INFO << entropy_vector.size(); + int lengths = std::count_if(entropy_vector.begin(), entropy_vector.end(),[&](auto const& val){ return val >= value; }); + if (lengths>1500) + { + lengths=1500; + } + MITK_INFO << lengths; + /*Maybe shuffling of length so not the most uncertain values are chosen*/ + std::vector indexUnc = Sort(entropy_vector, lengths, 0); + + vnl_matrix distances_matrix; + + distances_matrix.set_size(lengths, lengths); + distances_matrix.fill(0.0); + + std::vector distances_matrix_mean; + + + for (int i=0; i diff = m_DistancesTest.at(indexUnc.at(i)) - m_DistancesTest.at(indexUnc.at(k)); + + /*Into the eucledean difference matrix, put the distance in Feature Space between every sample pair*/ + distances_matrix.put(i,k,diff.absolute_value_sum()/m_DistancesTest.at(0).size()); + + } + /*For every Sample/Streamline get the mean eucledean distance to all other Samples => one value for every Sample*/ +// distances_matrix_mean.push_back(distances_matrix.get_row(i).mean()); +// MITK_INFO << meanval.at(i); + + } + + MITK_INFO << "Distance Matrix Calculated"; + + /*Index to find values in distancematrix*/ + std::vector myidx; + /*Index to find actual streamlines using indexUnc*/ + std::vector indexUncDist; + /*Start with the Streamline of the highest entropy, which is in distance_matrix at idx 0*/ + myidx.push_back(0); + indexUncDist.push_back(indexUnc.at(myidx.at(0))); + + /*Vecotr that stores minvalues of current iteration*/ + vnl_matrix cur_vec; + cur_vec.set_size(1,lengths); + cur_vec.fill(0.0); + for (int i=0; i sum_matrix; + sum_matrix.set_size(myidx.size(), lengths); + sum_matrix.fill(0); + for (unsigned int ii=0; ii &index, bool removefrompool) +{ + mitk::FiberBundle::Pointer Prediction; + MITK_INFO << "Create Bundle"; + + vtkSmartPointer FibersData; + FibersData = vtkSmartPointer::New(); + FibersData->SetPoints(vtkSmartPointer::New()); + FibersData->SetLines(vtkSmartPointer::New()); + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + +// vtkSmartPointer weights = vtkSmartPointer::New(); +// weights->SetNumberOfValues(this->GetNumFibers()+fib->GetNumFibers()); + + unsigned int indexSize = index.size(); + unsigned int counter = 0; + MITK_INFO << "Start Loop"; + for (unsigned int i=0; iGetFiberPolyData()->GetCell(index[i]); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } +// weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + if (removefrompool) + { + for (unsigned int i=0; iGetFiberPolyData()->DeleteCell(index[i]); + } + } + + + + + MITK_INFO << "Counter"; + MITK_INFO << counter; + + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + FibersData = vtkSmartPointer::New(); + FibersData->SetPoints(vtkSmartPointer::New()); + FibersData->SetLines(vtkSmartPointer::New()); + FibersData->SetPoints(vNewPoints); + FibersData->SetLines(vNewLines); + + Prediction = mitk::FiberBundle::New(vNewPolyData); + +// Bundle->SetFiberColors(255, 255, 255); + MITK_INFO << "Cells Prediciton"; + MITK_INFO << Prediction->GetFiberPolyData()->GetNumberOfCells(); + MITK_INFO << "Cells Tractorgram"; + MITK_INFO << m_TractogramTest->GetFiberPolyData()->GetNumberOfCells(); + + return Prediction; +} + +std::vector StreamlineFeatureExtractor::CreateLabels(std::vector > Testdata, + std::vector > Prediction) +{ +// vnl_vector labels; +// vnl_vector.set_size(Testdata.size()); +// vnl_vector.fill(0); + std::vector labels(Testdata.size(), 0); + + +#pragma omp parallel for + for (unsigned int i=0; i("/home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/data/Synt_tract_40_prototypes.trk"); + + std::vector > T_Prototypes; + std::vector > T_TractogramPlus; + std::vector > T_TractogramMinus; + std::vector > T_TractogramTest; + std::vector > T_mergedPrototypes; + + + MITK_INFO << "Resample Input Prototypes"; + T_Prototypes = ResampleFibers(m_inputPrototypes); + MITK_INFO << "Resample Input Tractogram Minus"; + T_TractogramMinus= ResampleFibers(m_TractogramMinus); + MITK_INFO << "Resample Input Tractogram Plus"; + T_TractogramPlus= ResampleFibers(m_TractogramPlus); + + /* Merge T_Prototypes, T_TractogramMinus and T_TractogramPlus for extra Features*/ + MITK_INFO << "Merging Prototypes"; + T_mergedPrototypes = MergeTractogram(T_Prototypes, T_TractogramPlus, T_TractogramMinus); + + + + + MITK_INFO << "Calculate Features"; + MITK_INFO << "Calculate Minus Features"; + m_DistancesMinus = CalculateDmdf(T_TractogramMinus, T_mergedPrototypes); + MITK_INFO << "Calculate Plus Features"; + m_DistancesPlus = CalculateDmdf(T_TractogramPlus, T_mergedPrototypes); + + MITK_INFO << "Resample Test Data"; + T_TractogramTest= ResampleFibers(m_TractogramTest); + MITK_INFO << "Calculate Features of Test Data"; + m_DistancesTest= CalculateDmdf(T_TractogramTest, T_mergedPrototypes); + + + + + MITK_INFO << "Done with Datacreation"; + m_index =GetData(); + +} + +vnl_vector StreamlineFeatureExtractor::ValidationPipe() +{ + std::vector > T_Prototypes; + std::vector > T_TractogramPrediction; + std::vector > T_TractogramGroundtruth; + std::vector > T_TractogramTest; + std::vector > DistancesPrediction; + std::vector > DistancesGroundtruth; + std::vector > DistancesTest; + std::vector LabelsPrediction; + std::vector LabelsGroundtruth; + + MITK_INFO << "Start Resampling"; + T_Prototypes = ResampleFibers(m_inputPrototypes); + T_TractogramPrediction= ResampleFibers(m_TractogramPrediction); + T_TractogramGroundtruth= ResampleFibers(m_TractogramGroundtruth); + T_TractogramTest= ResampleFibers(m_TractogramTest); + + + + MITK_INFO << "Calculate Features"; + DistancesPrediction = CalculateDmdf(T_TractogramPrediction, T_Prototypes); + DistancesGroundtruth = CalculateDmdf(T_TractogramGroundtruth, T_Prototypes); + DistancesTest = CalculateDmdf(T_TractogramTest, T_Prototypes); + + LabelsGroundtruth = CreateLabels(DistancesTest, DistancesGroundtruth); + LabelsPrediction = CreateLabels(DistancesTest, DistancesPrediction); + + std::ofstream LabelsPredictionFile; + LabelsPredictionFile.open("/home/r948e/mycsv/predictionlabels_" + std::to_string(m_activeCycle) + ".csv"); + for (unsigned int i = 0; i < LabelsPrediction.size(); i++) + { + LabelsPredictionFile << LabelsPrediction.at(i) << ' '; + } + LabelsPredictionFile.close(); + + std::ofstream LabelsGroundtruthFile; + LabelsGroundtruthFile.open("/home/r948e/mycsv/groundtruthlabels_" + std::to_string(m_activeCycle) + ".csv"); + for (unsigned int i = 0; i < LabelsGroundtruth.size(); i++) + { + LabelsGroundtruthFile << LabelsGroundtruth.at(i) << ' '; + } + LabelsGroundtruthFile.close(); + + float FP = 0.0; + float FN = 0.0; + float TP = 0.0; + float TN = 0.0; + std::vector indexfp; +//#pragma omp parallel for + for (unsigned int i=0; i metrics(7); + + metrics.put(0, TP); + metrics.put(1, FP); + metrics.put(2, TN); + metrics.put(3, FN); + metrics.put(4, Precision); + metrics.put(5, Recall); + metrics.put(6, F1_score); + + + + + return metrics; + +} + + +} + + + diff --git a/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.h b/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.h new file mode 100644 index 0000000..c39865e --- /dev/null +++ b/Modules/FiberDissection/MachineLearning/mitkStreamlineFeatureExtractor.h @@ -0,0 +1,129 @@ +/*=================================================================== + +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 StreamlineFeatureExtractor_h +#define StreamlineFeatureExtractor_h + + +#include "MitkFiberDissectionExports.h" +// MITK +#include +#include + +// ITK +#include + +// VTK +#include +#include +#include +#include +#include + +// OpenCV +#include +#include +#include + +namespace mitk{ + +/** +* \brief */ + +class MITKFIBERDISSECTION_EXPORT StreamlineFeatureExtractor +{ +public: + + + StreamlineFeatureExtractor(); + ~StreamlineFeatureExtractor(); + + typedef itk::Image< float, 3 > FloatImageType; + typedef itk::Image< unsigned char, 3 > UcharImageType; + + void Update(){ + this->GenerateData(); + } + +// void Validate(){ +// this->ValidationPipe(); +// } + + + + void SetTractogramGroundtruth(const mitk::FiberBundle::Pointer &Tractogram); + void SetTractogramPrediction(const mitk::FiberBundle::Pointer &Tractogram); + void SetTractogramPlus(const mitk::FiberBundle::Pointer &Tractogram); + void SetTractogramMinus(const mitk::FiberBundle::Pointer &Tractogram); + void SetTractogramTest(const mitk::FiberBundle::Pointer &Tractogram, std::string TractogramTestName); + void SetTractogramPrototypes(const mitk::FiberBundle::Pointer &TractogramPrototypes, bool standard); + void SetActiveCycle(int &activeCycle); + void SetInitRandom(int &initRandom); +// void SetRandomThreshold(int &threshold); + vnl_vector ValidationPipe(); + + + void CreateClassifier(); + std::vector> GetData(); + +// void CreatePrediction(std::vector &index); + mitk::FiberBundle::Pointer CreatePrediction(std::vector &index, bool removefrompool); + std::vector> GetDistanceData(float &value); + + mitk::FiberBundle::Pointer m_Prediction; + mitk::FiberBundle::Pointer m_ToLabel; + + std::vector> m_index; + std::vector entropy_vector; + cv::Ptr statistic_model; + + +protected: + + void GenerateData(); +// void ValidationPipe(); + + std::vector CreateLabels(std::vector > Testdata, + std::vector > Prediction); + std::vector< vnl_matrix > ResampleFibers(FiberBundle::Pointer tractogram); + std::vector > CalculateDmdf(std::vector > tractogram, + std::vector > prototypes); + std::vector< vnl_matrix > MergeTractogram(std::vector > prototypes, + std::vector > positive_local_prototypes, + std::vector > negative_local_prototypes); + std::vector Sort(std::vector sortingVector, int lengths, int start); + + + + + unsigned int m_NumPoints; + int m_activeCycle; + int m_initRandom; + int m_thresh; + mitk::FiberBundle::Pointer m_TractogramPrediction; + mitk::FiberBundle::Pointer m_TractogramGroundtruth; + mitk::FiberBundle::Pointer m_TractogramPlus; + mitk::FiberBundle::Pointer m_TractogramMinus; + mitk::FiberBundle::Pointer m_TractogramTest; + mitk::FiberBundle::Pointer m_inputPrototypes; + std::string m_DistancesTestName; + std::vector > m_DistancesPlus; + std::vector > m_DistancesMinus; + std::vector > m_DistancesTest; + cv::Ptr m_traindata; +}; +} + +#endif diff --git a/Modules/FiberDissection/files.cmake b/Modules/FiberDissection/files.cmake new file mode 100644 index 0000000..397bf16 --- /dev/null +++ b/Modules/FiberDissection/files.cmake @@ -0,0 +1,27 @@ +set(H_FILES + + #Interactor + Interactor/mitkStreamlineInteractor.h + Interactor/mitkStreamlineInteractorBrush.h + + #MachineLearning + MachineLearning/mitkStreamlineFeatureExtractor.h +) + +set(CPP_FILES + + #Interactor + Interactor/mitkStreamlineInteractor.cpp + Interactor/mitkStreamlineInteractorBrush.cpp + + #MachineLearning + MachineLearning/mitkStreamlineFeatureExtractor.cpp +) + +set(RESOURCE_FILES + # "Interactions" prefix forced by mitk::StateMachine + Interactions/Streamline3DStates.xml + Interactions/Streamline3DConfig.xml + Interactions/StreamlineBrush3DStates.xml + Interactions/StreamlineBrush3DConfig.xml +) diff --git a/Modules/FiberDissection/resource/Interactions/Streamline3DConfig.xml b/Modules/FiberDissection/resource/Interactions/Streamline3DConfig.xml new file mode 100644 index 0000000..e01f2f2 --- /dev/null +++ b/Modules/FiberDissection/resource/Interactions/Streamline3DConfig.xml @@ -0,0 +1,19 @@ + + + + + addtolabelstreamline + + + + + + + + + + + + + + diff --git a/Modules/FiberDissection/resource/Interactions/Streamline3DStates.xml b/Modules/FiberDissection/resource/Interactions/Streamline3DStates.xml new file mode 100644 index 0000000..5b4f97f --- /dev/null +++ b/Modules/FiberDissection/resource/Interactions/Streamline3DStates.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DConfig.xml b/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DConfig.xml new file mode 100644 index 0000000..0890749 --- /dev/null +++ b/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DConfig.xml @@ -0,0 +1,19 @@ + + + + + addtolabelstreamline + + + + + + + + + + + + + + diff --git a/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DStates.xml b/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DStates.xml new file mode 100644 index 0000000..5b4f97f --- /dev/null +++ b/Modules/FiberDissection/resource/Interactions/StreamlineBrush3DStates.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index ac97051..926de49 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,8 +1,9 @@ set(MITK_MODULES DiffusionCore FiberTracking Connectomics MriSimulation DiffusionIO DiffusionCmdApps + FiberDissection ) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt index 8462ed4..6a48682 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt @@ -1,10 +1,10 @@ # The project name must correspond to the directory name of your plug-in # and must not contain periods. project(org_mitk_gui_qt_diffusionimaging_fiberprocessing) mitk_create_plugin( SUBPROJECTS MITK-Diffusion EXPORT_DIRECTIVE DIFFUSIONIMAGING_FIBERPROCESSING_EXPORT EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkFiberTracking MitkMriSimulation MitkChart MitkMultilabel MitkModelFit + MODULE_DEPENDS MitkFiberTracking MitkMriSimulation MitkChart MitkMultilabel MitkModelFit MitkQtWidgetsExt MitkFiberDissection ) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt.user b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt.user new file mode 100644 index 0000000..ab39197 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/CMakeLists.txt.user @@ -0,0 +1,434 @@ + + + + + + EnvironmentId + {7fc4674f-cf78-4922-8cee-e8273e158382} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + Builtin.BuildSystem + + true + true + Builtin.DefaultTidyAndClazy + 12 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Qt 5.12.12 GCC 64bit + Qt 5.12.12 GCC 64bit + {696d7eab-256e-4d8a-89bd-eaa6ae60deb2} + 1 + 0 + 0 + + Debug + -GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/repo_mitk_diff/mitk-diffusion/Plugins/build-org.mitk.gui.qt.diffusionimaging.fiberprocessing-Qt_5_12_12_GCC_64bit_temporary-Debug + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + + + Release + -GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/repo_mitk_diff/mitk-diffusion/Plugins/build-org.mitk.gui.qt.diffusionimaging.fiberprocessing-Qt_5_12_12_GCC_64bit_temporary-Release + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release + CMakeProjectManager.CMakeBuildConfiguration + + + RelWithDebInfo + -GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/repo_mitk_diff/mitk-diffusion/Plugins/build-org.mitk.gui.qt.diffusionimaging.fiberprocessing-Qt_5_12_12_GCC_64bit_temporary-RelWithDebInfo + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release with Debug Information + CMakeProjectManager.CMakeBuildConfiguration + + + MinSizeRel + -GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=MinSizeRel +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/repo_mitk_diff/mitk-diffusion/Plugins/build-org.mitk.gui.qt.diffusionimaging.fiberprocessing-Qt_5_12_12_GCC_64bit_temporary-MinSizeRel + + + + all + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Minimum Size Release + CMakeProjectManager.CMakeBuildConfiguration + + + Release + -GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/mitk + /home/r948e/MITK_Diff/git_build + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release2 + CMakeProjectManager.CMakeBuildConfiguration + + + Release + -GUnix Makefiles +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%{IDE:ResourcePath}/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + /home/r948e/E132-Projekte/Projects/2022_Peretzke_Interactive_Fiber_Dissection/mitk_diff/mitk + /home/r948e/MITK_Diff/qt_build + + + + all + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release3 + CMakeProjectManager.CMakeBuildConfiguration + + 6 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 2 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/files.cmake b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/files.cmake index 0f586c9..3a42839 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/files.cmake +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/files.cmake @@ -1,63 +1,70 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp QmitkFiberQuantificationView.cpp QmitkFiberProcessingView.cpp QmitkFiberClusteringView.cpp + QmitkInteractiveFiberDissectionView.cpp QmitkFiberFitView.cpp QmitkTractometryView.cpp Perspectives/QmitkFiberProcessingPerspective.cpp ) set(UI_FILES src/internal/QmitkFiberQuantificationViewControls.ui src/internal/QmitkFiberProcessingViewControls.ui src/internal/QmitkFiberClusteringViewControls.ui + src/internal/QmitkInteractiveFiberDissectionViewControls.ui src/internal/QmitkFiberFitViewControls.ui src/internal/QmitkTractometryViewControls.ui ) set(MOC_H_FILES src/internal/mitkPluginActivator.h src/internal/QmitkFiberQuantificationView.h src/internal/QmitkFiberProcessingView.h src/internal/QmitkFiberClusteringView.h + src/internal/QmitkInteractiveFiberDissectionView.h src/internal/QmitkFiberFitView.h src/internal/QmitkTractometryView.h src/internal/Perspectives/QmitkFiberProcessingPerspective.h ) set(CACHED_RESOURCE_FILES plugin.xml resources/FiberBundleOperations.png resources/FiberQuantification.png resources/FiberClustering.png resources/FiberFit.png resources/Tractometry.png resources/circle.png resources/polygon.png + resources/eraze.png + resources/brush.png + resources/highlighter.png ) set(QRC_FILES resources/QmitkFiberprocessing.qrc + resources/QmitkInteractiveFiberDissection.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml index 4150004..4a46258 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/plugin.xml @@ -1,163 +1,171 @@ + + + + This perspective contains all views necessary to post process fibers. diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/QmitkInteractiveFiberDissection.qrc b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/QmitkInteractiveFiberDissection.qrc new file mode 100644 index 0000000..047b9e6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/QmitkInteractiveFiberDissection.qrc @@ -0,0 +1,9 @@ + + + FiberBundle.png + circle.png + polygon.png + eraze.png + highlighter.png + + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png new file mode 100644 index 0000000..4fdb238 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png new file mode 100644 index 0000000..d4ac1c0 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/highlighter.png b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/highlighter.png new file mode 100644 index 0000000..4fa7514 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/highlighter.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp index 038ed58..4ad19e7 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp @@ -1,52 +1,53 @@ /*=================================================================== 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 "QmitkFiberProcessingPerspective.h" #include "berryIViewLayout.h" void QmitkFiberProcessingPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout) { ///////////////////////////////////////////////////// // all di-app perspectives should have the following: ///////////////////////////////////////////////////// QString editorArea = layout->GetEditorArea(); layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false); layout->AddStandaloneView("org.mitk.views.datamanager", false, berry::IPageLayout::LEFT, 0.3f, editorArea); layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview", false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager"); berry::IFolderLayout::Pointer left = layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols", berry::IPageLayout::BOTTOM, 0.15f, "org.mitk.views.controlvisualizationpropertiesview"); layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator", berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false); ///////////////////////////////////////////// // here goes the perspective specific stuff ///////////////////////////////////////////// left->AddView("org.mitk.views.fiberprocessing"); left->AddView("org.mitk.views.fiberquantification"); + left->AddView("org.mitk.views.interactivefiberdissection"); left->AddView("org.mitk.views.fiberclustering"); left->AddView("org.mitk.views.fiberfit"); left->AddView("org.mitk.views.tractometry"); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.cpp new file mode 100644 index 0000000..4cf6a57 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.cpp @@ -0,0 +1,1767 @@ +/*=================================================================== + +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. + +===================================================================*/ + + + +// Blueberry +#include +#include +#include + +// Qmitk +#include "QmitkInteractiveFiberDissectionView.h" +#include //Pointset +#include //Pointset + +#include + +#include +#include +#include +#include +#include +#include +#include "mitkNodePredicateDataType.h" +#include +#include +#include +#include +//#include + +#include +#include "usModuleRegistry.h" +//#include + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +const std::string QmitkInteractiveFiberDissectionView::VIEW_ID = "org.mitk.views.interactivefiberdissection"; +const std::string id_DataManager = "org.mitk.views.datamanager"; +using namespace mitk; + +QmitkInteractiveFiberDissectionView::QmitkInteractiveFiberDissectionView() + : QmitkAbstractView() + , m_Controls( 0 ) + , m_IterationCounter(0) + , m_RandomExtractionCounter(0) + , m_activeCycleCounter(0) + , m_createdStreamlineCounter(0) + , m_StreamlineInteractor(nullptr) +{ + +} + +// Destructor +QmitkInteractiveFiberDissectionView::~QmitkInteractiveFiberDissectionView() +{ + //disable interactor + if (m_StreamlineInteractor != nullptr) + { +// m_StreamlineInteractor->SetStreamlineNode(nullptr); + m_StreamlineInteractor->EnableInteraction(false); + } +} + + +void QmitkInteractiveFiberDissectionView::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::QmitkInteractiveFiberDissectionViewControls; + m_Controls->setupUi( parent ); + m_Controls->m_selectedPointSetWidget->SetDataStorage(GetDataStorage());//pointset + m_Controls->m_selectedPointSetWidget->SetNodePredicate(mitk::NodePredicateAnd::New(//pointset + mitk::TNodePredicateDataType::New(),//pointset + mitk::NodePredicateNot::New(mitk::NodePredicateOr::New(//pointset + mitk::NodePredicateProperty::New("helper object"),//pointset + mitk::NodePredicateProperty::New("hidden object")))));//pointset + + m_Controls->m_selectedPointSetWidget->SetSelectionIsOptional(true);//pointset + m_Controls->m_selectedPointSetWidget->SetAutoSelectNewNodes(true);//pointset + m_Controls->m_selectedPointSetWidget->SetEmptyInfo(QString("Please select a point set"));//pointset + m_Controls->m_selectedPointSetWidget->SetPopUpTitel(QString("Select point set"));//pointsett + + m_Controls->m_BundleBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType::Pointer isBundle= mitk::TNodePredicateDataType::New(); + m_Controls->m_BundleBox->SetPredicate( isBundle ); + + m_Controls->m_PrototypeBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType::Pointer isPrototype = mitk::TNodePredicateDataType::New(); + m_Controls->m_PrototypeBox->SetPredicate( isPrototype ); + + m_Controls->m_PredictionBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType::Pointer isPrediction = mitk::TNodePredicateDataType::New(); + m_Controls->m_PredictionBox->SetPredicate( isPrediction ); + + m_Controls->m_GroundtruthBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType::Pointer isGroundtruth = mitk::TNodePredicateDataType::New(); + m_Controls->m_GroundtruthBox->SetPredicate( isGroundtruth ); + + m_Controls->m_TestBundleBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType::Pointer isTestBundle = mitk::TNodePredicateDataType::New(); + m_Controls->m_TestBundleBox->SetPredicate( isTestBundle); + + + + + connect(m_Controls->m_ErazorButton, SIGNAL(toggled(bool)), this, SLOT( RemovefromBundle(bool) ) ); + connect(m_Controls->m_BrushButton, SIGNAL(toggled(bool)), this, SLOT( RemovefromBundleBrush(bool) ) ); + + connect(m_Controls->m_StreamlineCreation, SIGNAL( clicked() ), this, SLOT( CreateStreamline())); + + connect(m_Controls->m_AddRandomFibers, SIGNAL( clicked() ), this, SLOT( ExtractRandomFibersFromTractogram() ) ); //need + + connect(m_Controls->m_TrainClassifier, SIGNAL( clicked() ), this, SLOT( StartAlgorithm( ))); + + connect(m_Controls->m_CreatePrediction, SIGNAL( clicked() ), this, SLOT( CreatePredictionNode( ))); + + connect(m_Controls->m_certainData, SIGNAL( clicked() ), this, SLOT( CreateCertainNode( ))); + + connect(m_Controls->m_AddUncertainFibers, SIGNAL( clicked() ), this, SLOT( CreateUncertaintySampleNode( ))); + + connect(m_Controls->m_AddDistanceFibers, SIGNAL( clicked() ), this, SLOT( CreateDistanceSampleNode( ))); + + connect(m_Controls->m_unclabeling, SIGNAL(toggled(bool)), this, SLOT( RemovefromUncertainty(bool) ) ); //need + + connect(m_Controls->m_unclabelingBrush, SIGNAL(toggled(bool)), this, SLOT( RemovefromUncertaintyBrush(bool) ) ); //need + + connect(m_Controls->m_distlabeling, SIGNAL(toggled(bool)), this, SLOT( RemovefromDistance(bool) ) ); //need + + connect(m_Controls->m_predlabeling, SIGNAL(toggled(bool)), this, SLOT( RemovefromPrediction(bool) ) ); //need + + connect(m_Controls->m_predlabelingBrush, SIGNAL(toggled(bool)), this, SLOT( RemovefromPredictionBrush(bool) ) ); //need + + connect(m_Controls->m_sellabeling, SIGNAL(toggled(bool)), this, SLOT( RemovefromSelection(bool) ) ); //need + + connect(m_Controls->m_ResampleButton, SIGNAL( clicked() ), this, SLOT( ResampleTractogram( ) ) ); + + connect(m_Controls->m_RandomPrototypesButton, SIGNAL( clicked() ), this, SLOT( RandomPrototypes( ) ) ); + + connect(m_Controls->m_SFFPrototypesButton, SIGNAL( clicked() ), this, SLOT( SFFPrototypes( ) ) ); + + connect(m_Controls->m_validate, SIGNAL( clicked() ), this, SLOT( StartValidation( ) ) ); + + connect(m_Controls->m_automaticLabelling, SIGNAL( clicked() ), this, SLOT( AutomaticLabelling( ) ) ); + + connect(m_Controls->m_RemoveCertainData, SIGNAL( clicked() ), this, SLOT( RemoveCertainData( ) ) ); + + connect(m_Controls->m_resetClassifier, SIGNAL( clicked() ), this, SLOT( ResetClassifier( ) ) ); + + + + connect(m_Controls->m_addPointSetPushButton, &QPushButton::clicked,//pointset + this, &QmitkInteractiveFiberDissectionView::OnAddPointSetClicked);//pointset + connect(m_Controls->m_selectedPointSetWidget, &QmitkSingleNodeSelectionWidget::CurrentSelectionChanged,//pointset + this, &QmitkInteractiveFiberDissectionView::OnCurrentSelectionChanged);//pointset + + + + + auto renderWindowPart = this->GetRenderWindowPart();//pointset + if (nullptr != renderWindowPart)//pointset + this->RenderWindowPartActivated(renderWindowPart);//pointset + this->OnCurrentSelectionChanged(m_Controls->m_selectedPointSetWidget->GetSelectedNodes());//pointset + + } + + UpdateGui(); +} + + +void QmitkInteractiveFiberDissectionView::SetFocus() +{ + m_Controls->toolBoxx->setFocus(); + //m_Controls->m_addPointSetPushButton->setFocus();//pointset + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::UpdateGui() +{ + m_Controls->m_FibLabel->setText("nothing selected"); + m_Controls->m_InputData->setTitle("Please Select Input Data"); + + // disable alle frames + + m_Controls->m_ErazorButton->setCheckable(true); + m_Controls->m_ErazorButton->setEnabled(false); + m_Controls->m_BrushButton->setCheckable(true); + m_Controls->m_BrushButton->setEnabled(false); + m_Controls->m_unclabeling->setCheckable(true); + m_Controls->m_unclabeling->setEnabled(false); + m_Controls->m_predlabeling->setCheckable(true); + m_Controls->m_predlabeling->setEnabled(false); + m_Controls->m_unclabelingBrush->setCheckable(true); + m_Controls->m_unclabelingBrush->setEnabled(false); + m_Controls->m_predlabelingBrush->setCheckable(true); + m_Controls->m_predlabelingBrush->setEnabled(false); + m_Controls->m_distlabeling->setCheckable(true); + m_Controls->m_distlabeling->setEnabled(false); + m_Controls->m_sellabeling->setCheckable(true); + m_Controls->m_sellabeling->setEnabled(false); + + + + m_Controls->m_addPointSetPushButton->setEnabled(false); + m_Controls->m_StreamlineCreation->setEnabled(false); + m_Controls->m_TrainClassifier->setEnabled(false); + m_Controls->m_CreatePrediction->setEnabled(false); + m_Controls->m_CreateUncertantyMap->setEnabled(false); + m_Controls->m_Numtolabel->setEnabled(false); + m_Controls->m_Numtolabel2->setEnabled(false); + m_Controls->m_addPointSetPushButton->setEnabled(false); + m_Controls->m_AddRandomFibers->setEnabled(false); + m_Controls->m_AddDistanceFibers->setEnabled(false); + m_Controls->m_AddUncertainFibers->setEnabled(false); +// m_Controls->m_PrototypeBox->setEditable(false); +// m_Controls->m_useStandardP-> + + mitk::DataNode::Pointer curtestnode = m_Controls->m_TestBundleBox->GetSelectedNode(); + bool testnodeSelected = curtestnode.IsNotNull(); + MITK_INFO << testnodeSelected; + bool fibSelected = !m_SelectedFB.empty(); + bool multipleFibsSelected = (m_SelectedFB.size()>1); + bool sthSelected = m_SelectedImageNode.IsNotNull(); + bool psSelected = m_SelectedPS.IsNotNull(); +// bool nfibSelected = !m_newfibersBundleNode.empty(); +// bool posSelected = !m_positiveBundleNode.empty(); + bool nfibSelected = m_newfibersBundleNode.IsNotNull(); +// bool posSelected = !m_positiveBundleNode.IsNotNull(); +// bool negSelected = !m_negativeBundleNode.IsNotNull(); + bool posSelected = this->GetDataStorage()->Exists(m_positiveBundleNode); + bool negSelected = this->GetDataStorage()->Exists(m_negativeBundleNode); + bool indexSelected = !m_index.empty(); + bool uncertaintySelected = this->GetDataStorage()->Exists(m_UncertaintyLabelNode); +// bool distanceSelected = this->GetDataStorage()->Exists(m_DistanceLabelNode); + bool predictionSelected = this->GetDataStorage()->Exists(m_PredictionNode); + + + + // toggle visibility of elements according to selected method + + + // are fiber bundles selected? + if ( testnodeSelected ) + { + m_Controls->m_addPointSetPushButton->setEnabled(true); + m_Controls->m_AddRandomFibers->setEnabled(true); + m_Controls->m_sellabeling->setEnabled(true); + } + + if (fibSelected) + { + m_Controls->m_FibLabel->setText(QString(m_SelectedFB.at(0)->GetName().c_str())); + // more than two bundles needed to join/subtract + if (multipleFibsSelected ) + { + m_Controls->m_FibLabel->setText("multiple bundles selected"); + } + + + + } + + + // is image selected + if ((sthSelected) || (testnodeSelected)) + { + m_Controls->m_addPointSetPushButton->setEnabled(true); + } + + if (psSelected) + { + m_Controls->m_StreamlineCreation->setEnabled(true); + } + + if (nfibSelected && posSelected) + { + m_Controls->m_ErazorButton->setEnabled(true); + m_Controls->m_BrushButton->setEnabled(true); + } + + + if (posSelected && negSelected) + { + m_Controls->m_TrainClassifier->setEnabled(true); + } + + if (indexSelected) + { + m_Controls->m_CreatePrediction->setEnabled(true); + m_Controls->m_AddUncertainFibers->setEnabled(true); + m_Controls->m_Numtolabel->setEnabled(true); + m_Controls->m_AddDistanceFibers->setEnabled(true); + m_Controls->m_Numtolabel2->setEnabled(true); + } + + if (uncertaintySelected) + { + m_Controls->m_unclabeling->setEnabled(true); + m_Controls->m_unclabelingBrush->setEnabled(true); + } + + if (predictionSelected) + { + m_Controls->m_predlabeling->setEnabled(true); + m_Controls->m_predlabelingBrush->setEnabled(true); + } + +// if (distanceSelected) +// { + m_Controls->m_distlabeling->setEnabled(true); +// } + +// if (m_Controls->m_useStandardP->isChecked()) +// { +// m_Controls->m_PrototypeBox->setEditable(true); +// } + + + + + + +} + +void QmitkInteractiveFiberDissectionView::OnEndInteraction() +{ + +} + +void QmitkInteractiveFiberDissectionView::ResampleTractogram() +{ + mitk::DataNode::Pointer node = m_Controls->m_BundleBox->GetSelectedNode(); + auto tractogram = dynamic_cast(node->GetData()); + mitk::FiberBundle::Pointer tempfib = tractogram->GetDeepCopy(); + + std::vector myvec; + for (unsigned int k=0; kGetNumFibers(); k++) + { + myvec.push_back(k); + } +// auto rng = std::default_random_engine {}; + std::random_shuffle(std::begin(myvec), std::end(myvec)); + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + vtkSmartPointer weights = vtkSmartPointer::New(); + + /* Check wether all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + unsigned int counter = 0; + + for (unsigned int i=0; iGetNumFibers(); i++) + { + vtkCell* cell = tempfib->GetFiberPolyData()->GetCell(myvec.at(i)); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, tempfib->GetFiberWeight(myvec.at(i))); + vNewLines->InsertNextCell(container); + counter++; + + } + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + mitk::FiberBundle::Pointer ShuffledBundle = mitk::FiberBundle::New(vNewPolyData); + ShuffledBundle->SetFiberWeights(weights); + + ShuffledBundle->ResampleToNumPoints(40); + MITK_INFO << "Resampling Done"; + + mitk::DataNode::Pointer newnode = mitk::DataNode::New(); + newnode->SetData( ShuffledBundle ); + newnode->SetName( node->GetName() + "_" + std::to_string(40) ); + this->GetDataStorage()->Add(newnode); + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::RandomPrototypes() +{ + + + MITK_INFO << "Number of Fibers to use as Prototypes: "; + MITK_INFO << m_Controls->m_NumPrototypes->value(); + + mitk::FiberBundle::Pointer fib = dynamic_cast(m_Controls->m_BundleBox->GetSelectedNode()->GetData()); + + MITK_INFO << fib->GetNumFibers(); + std::vector myvec; + for (unsigned int k=0; kGetNumFibers(); k++) + { + myvec.push_back(k); + } +// auto rng = std::default_random_engine {}; + std::random_shuffle(std::begin(myvec), std::end(myvec)); + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + vtkSmartPointer weights = vtkSmartPointer::New(); + + /* Check wether all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + unsigned int counter = 0; + + for (int i=0; im_NumPrototypes->value(); i++) + { + vtkCell* cell = fib->GetFiberPolyData()->GetCell(myvec.at(i)); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib->GetFiberWeight(myvec.at(i))); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + mitk::FiberBundle::Pointer PrototypesBundle = mitk::FiberBundle::New(vNewPolyData); + PrototypesBundle->SetFiberWeights(weights); + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(PrototypesBundle); + node->SetName("Random_Prototypes"); + +// MITK_INFO << "Number of Streamlines in first function"; +// MITK_INFO << m_newfibersBundleNode->GetData()->GetFiberPolyData()->GetNumberOfCells(); + m_Controls->m_PrototypeBox->SetAutoSelectNewItems (true); + this->GetDataStorage()->Add(node); + m_Controls->m_PrototypeBox->SetAutoSelectNewItems (false); + m_Controls->m_useStandardP->setChecked(false); + node->SetVisibility(false); + + +} + +void QmitkInteractiveFiberDissectionView::SFFPrototypes() +{ + + + MITK_INFO << "Number of Fibers to use as Prototypes: "; + MITK_INFO << m_Controls->m_NumPrototypes->value(); + MITK_INFO << "Start Creating Prototypes based on SFF"; + + mitk::FiberBundle::Pointer fib = dynamic_cast(m_Controls->m_BundleBox->GetSelectedNode()->GetData()); + + /* Get Subset of Tractogram*/ + int size_subset = std::max(1.0, ceil(3.0 * m_Controls->m_NumPrototypes->value() * std::log(m_Controls->m_NumPrototypes->value()))); + + MITK_INFO << fib->GetNumFibers(); + std::vector myvec; + for (unsigned int k=0; kGetNumFibers(); k++) + { + myvec.push_back(k); + } + +// std::random_shuffle(std::begin(myvec), std::end(myvec)); + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + vtkSmartPointer weights = vtkSmartPointer::New(); + + + unsigned int counter = 0; + + for (int i=0; iGetFiberPolyData()->GetCell(myvec.at(i)); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib->GetFiberWeight(myvec.at(i))); + vNewLines->InsertNextCell(container); + counter++; + + } + + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + mitk::FiberBundle::Pointer temp_fib = mitk::FiberBundle::New(vNewPolyData); + temp_fib->SetFiberWeights(weights); + + MITK_INFO << temp_fib->GetFiberPolyData()->GetNumberOfCells(); + /* Create std::vector of the SubsetBundle*/ + std::vector< vnl_matrix > out_fib(temp_fib->GetFiberPolyData()->GetNumberOfCells()); + + for (int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = temp_fib->GetFiberPolyData()->GetCell(i); + int numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vnl_matrix streamline; + streamline.set_size(3, cell->GetNumberOfPoints()); + streamline.fill(0.0); + + for (int j=0; jGetPoint(j, cand); + + vnl_vector_fixed< float, 3 > candV; + candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2]; + streamline.set_column(j, candV); + } + + // out_fib.push_back(streamline); + out_fib.at(i)=streamline; + } + + + /* Calculate the distancematrix of Subset*/ + std::vector< vnl_matrix > dist_vec(out_fib.size());// + cv::parallel_for_(cv::Range(0, out_fib.size()), [&](const cv::Range &range) + { + for (int i = range.start; i < range.end; i++) + + // for (unsigned int i=0; i distances; + distances.set_size(1, out_fib.size()); + distances.fill(0.0); + + + for (unsigned int j=0; j single_distances; + single_distances.set_size(1, out_fib.at(0).cols()); + single_distances.fill(0.0); + vnl_matrix single_distances_flip; + single_distances_flip.set_size(1, out_fib.at(0).cols()); + single_distances_flip.fill(0.0); + for (unsigned int ik=0; ik single_distances.mean()) + { + distances.put(0,j, single_distances.mean()); + } + else { + distances.put(0,j, single_distances_flip.mean()); + } + + + + } + // dist_vec.push_back(distances); + dist_vec.at(i) = distances; + } + }); + + + /*Index to find values in distancematrix*/ + std::vector myidx; + /*Index to find actual streamlines using indexUnc*/ + std::vector indexUncDist; + /*Start with the Streamline of the highest entropy, which is in distance_matrix at idx 0*/ + myidx.push_back(0); + + /*Vecotr that stores minvalues of current iteration*/ + vnl_matrix cur_vec; + cur_vec.set_size(1, size_subset); + cur_vec.fill(0.0); + for (int i=0; im_NumPrototypes->value(); i++) + { + + // unsigned int cur_i = indexUnc.at(myidx.at(i)); + + /*Save mean distance of all used Samples*/ + + vnl_matrix sum_matrix; + sum_matrix.set_size(myidx.size(), size_subset); + sum_matrix.fill(0); + for (unsigned int ii=0; ii vNewPolyData2 = vtkSmartPointer::New(); + vtkSmartPointer vNewLines2 = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints2 = vtkSmartPointer::New(); + + vtkSmartPointer weights2 = vtkSmartPointer::New(); + + /* Check wether all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + counter = 0; + + for (int i=0; im_NumPrototypes->value(); i++) + { + + vtkCell* cell = fib->GetFiberPolyData()->GetCell(myidx.at(i)); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints2->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights2->InsertValue(counter, fib->GetFiberWeight(myvec.at(i))); + vNewLines2->InsertNextCell(container); + counter++; + + } + + vNewPolyData2->SetLines(vNewLines2); + vNewPolyData2->SetPoints(vNewPoints2); + + mitk::FiberBundle::Pointer PrototypesBundle = mitk::FiberBundle::New(vNewPolyData2); + PrototypesBundle->SetFiberWeights(weights2); + MITK_INFO << PrototypesBundle->GetFiberPolyData()->GetNumberOfCells(); + + + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(PrototypesBundle); + node->SetName("SFF_Prototypes"); + +//// MITK_INFO << "Number of Streamlines in first function"; +//// MITK_INFO << m_newfibersBundleNode->GetData()->GetFiberPolyData()->GetNumberOfCells(); + m_Controls->m_PrototypeBox->SetAutoSelectNewItems (true); + this->GetDataStorage()->Add(node); + m_Controls->m_PrototypeBox->SetAutoSelectNewItems (false); + m_Controls->m_useStandardP->setChecked(false); + node->SetVisibility(false); + + + +} + +void QmitkInteractiveFiberDissectionView::OnAddPointSetClicked()//pointset +{ + // ask for the name of the point set + bool ok = false; + QString name = QInputDialog::getText(QApplication::activeWindow(), + tr("Add point set..."), tr("Enter name for the new point set"), QLineEdit::Normal, tr("PointSet").arg(++m_IterationCounter), &ok); +// QString name = "PointSet"; + if (!ok || name.isEmpty()) + { + return; + } + mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); + mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New(); + pointSetNode->SetData(pointSet); + pointSetNode->SetProperty("name", mitk::StringProperty::New(name.toStdString())); + pointSetNode->SetProperty("opacity", mitk::FloatProperty::New(1)); + pointSetNode->SetColor(1.0, 1.0, 0.0); + m_testnode = m_Controls->m_TestBundleBox->GetSelectedNode(); + this->GetDataStorage()->Add(pointSetNode, m_testnode); + + + m_Controls->m_selectedPointSetWidget->SetCurrentSelectedNode(pointSetNode); +} + +void QmitkInteractiveFiberDissectionView::OnCurrentSelectionChanged(QmitkSingleNodeSelectionWidget::NodeList /*nodes*/)//pointset +{ + + m_Controls->m_poinSetListWidget->SetPointSetNode(m_Controls->m_selectedPointSetWidget->GetSelectedNode()); + m_SelectedPS = m_Controls->m_selectedPointSetWidget->GetSelectedNode(); + +// m_Controls->m_trainbundleWidget->SetPointSetNode(m_Controls->m_trainbundleWidget->GetSelectedNode()); +// m_trainbundle = m_Controls->m_trainbundleWidget->GetSelectedNode(); + + + UpdateGui(); + +} + +void QmitkInteractiveFiberDissectionView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes) +{ + + m_SelectedFB.clear(); + + if (nodes.empty() || nodes.front().IsNull()) + { + m_SelectedImageNode = nullptr; + } + else + { + m_SelectedImageNode = nodes.front(); + } + + + + for (auto node: nodes) + { + if (dynamic_cast(node->GetData())) + m_SelectedImage = dynamic_cast(node->GetData()); + else if ( dynamic_cast(node->GetData()) ) + m_SelectedFB.push_back(node); + } + + + + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)//pointset +{ + if (nullptr != m_Controls) + { + m_Controls->m_poinSetListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); + m_Controls->m_poinSetListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); + m_Controls->m_poinSetListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); + } +} + +void QmitkInteractiveFiberDissectionView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart)//pointset +{ + if (nullptr != m_Controls) + { + m_Controls->m_poinSetListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); + m_Controls->m_poinSetListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); + m_Controls->m_poinSetListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); + } +} + +void QmitkInteractiveFiberDissectionView::CreateStreamline() +{ + + if (m_positiveBundleNode.IsNull()) + { + mitk::DataNode::Pointer node = mitk::DataNode::New(); + + m_positiveFibersData = vtkSmartPointer::New(); + m_positiveFibersData->SetPoints(vtkSmartPointer::New()); + m_positiveFibersData->SetLines(vtkSmartPointer::New()); + m_positiveBundle = mitk::FiberBundle:: New(m_positiveFibersData); + + node->SetData( m_positiveBundle ); + node->SetData(m_negativeBundle); +// node->SetFloatProperty("shape.tuberadius", 0.5); +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + m_positiveBundleNode = node; + this->GetDataStorage()->Add(m_positiveBundleNode); + MITK_INFO << "Create Bundle"; + } + + if (!m_positiveBundleNode.IsNull()) + { + + this->GetDataStorage()->Remove(m_positiveBundleNode); + MITK_INFO << "Adding fibers"; + MITK_INFO << m_positiveBundle->GetFiberPolyData()->GetNumberOfCells(); + m_positiveFibersData = m_positiveBundle->GetFiberPolyData(); + } + + + + + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + + + unsigned int counter = 0; + for (unsigned int i=0; iGetNumberOfCells(); ++i) + { + MITK_INFO<< "New Line"; + vtkCell* cell = m_positiveFibersData->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + + vNewLines->InsertNextCell(container); + counter++; + } + + mitk::PointSet::Pointer pointSet = dynamic_cast(m_SelectedPS->GetData()); + + + vnl_matrix streamline; + streamline.set_size(3, pointSet->GetSize()); + streamline.fill(0.0); + + + mitk::PointSet::PointsIterator begin = pointSet->Begin(); + mitk::PointSet::PointsIterator end = pointSet->End(); + unsigned int i; + mitk::PointSet::PointsContainer::Iterator it; + + for (it = begin, i = 0; it != end; ++it, ++i) + { + PointSet::PointType pt = pointSet->GetPoint(it->Index()); + vnl_vector_fixed< float, 3 > candV; + candV[0]=pt[0]; candV[1]=pt[1]; candV[2]=pt[2]; + streamline.set_column(i, candV); + } + + // build Fiber + vtkSmartPointer container = vtkSmartPointer::New(); + + + for (unsigned int j=0; jInsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + MITK_INFO<< "Last Line from current pointset"; + vNewLines->InsertNextCell(container); + + vNewPolyData->SetPoints(vNewPoints); + vNewPolyData->SetLines(vNewLines); + + m_positiveFibersData = vtkSmartPointer::New(); + m_positiveFibersData->SetPoints(vtkSmartPointer::New()); + m_positiveFibersData->SetLines(vtkSmartPointer::New()); + m_positiveFibersData->SetPoints(vNewPoints); + m_positiveFibersData->SetLines(vNewLines); + + m_positiveBundle = mitk::FiberBundle::New(vNewPolyData); + m_positiveBundle->ResampleToNumPoints(40); + MITK_INFO << "Resampling Done"; + + + m_positiveBundle->SetFiberColors(0, 255, 0); + + + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_positiveBundle); + node->SetName("+Bundle"); +// node->SetFloatProperty("shape.tuberadius", 0.5); +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + m_positiveBundleNode= node; + + + + MITK_INFO << "The + Bundle has Streamlines:"; + auto m_PosStreamline= dynamic_cast(m_positiveBundleNode->GetData()); + MITK_INFO << m_PosStreamline->GetFiberPolyData()->GetNumberOfCells(); + + this->GetDataStorage()->Add(m_positiveBundleNode); +// m_Controls->m_selectedPointSetWidget->m_ToggleAddPoint->setEnabled(false); + + UpdateGui(); + m_createdStreamlineCounter +=1; + +} + +void QmitkInteractiveFiberDissectionView::ExtractRandomFibersFromTractogram() +{ + m_testnode = m_Controls->m_TestBundleBox->GetSelectedNode(); + m_testnode->SetVisibility(false); +// m_SelectedFB.at(0)->SetVisibility(false); + m_Controls->m_ErazorButton->setChecked(false); + m_Controls->m_BrushButton->setChecked(false); + + + MITK_INFO << "Number of Fibers to extract from Tractogram: "; + MITK_INFO << m_Controls->m_NumRandomFibers->value(); + if (this->GetDataStorage()->Exists(m_newfibersBundleNode)) + { + MITK_INFO << "To Label Bundle Exists"; + mitk::FiberBundle::Pointer Stack = dynamic_cast(m_newfibersBundleNode->GetData()); + this->GetDataStorage()->Remove(m_newfibersBundleNode); + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + + m_newfibersFibersData = vtkSmartPointer::New(); + m_newfibersFibersData->SetPoints(vtkSmartPointer::New()); + m_newfibersBundle = mitk::FiberBundle:: New(m_newfibersFibersData); + m_newfibersFibersData->SetLines(vtkSmartPointer::New()); + +// node->SetData( m_newfibersBundle ); +// m_newfibersBundleNode = node ; + + MITK_INFO << "Create Bundle"; + } + + mitk::FiberBundle::Pointer fib = dynamic_cast(m_testnode->GetData()); + // mitk::FiberBundle::Pointer fib = dynamic_cast(m_SelectedFB.at(0)->GetData()); +// mitk::FiberBundle::Pointer fib = dynamic_cast(m_trainbundle->GetData()); + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + vtkSmartPointer weights = vtkSmartPointer::New(); +// weights->SetNumberOfValues(this->GetNumFibers()+fib->GetNumFibers()); + +// MITK_INFO << fib->GetNumFibers(); +// std::vector myvec; +// for (unsigned int k=0; kGetNumFibers(); k++) +// { +// myvec.push_back(k); +// } +// std::random_shuffle(std::begin(myvec), std::end(myvec)); + + /* Check weather all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + unsigned int counter = 0; +// int thresh1; +// int thresh2; +// thresh2 = m_Controls->m_NumRandomFibers->value()*(m_RandomExtractionCounter+1); +// thresh1 = m_Controls->m_NumRandomFibers->value()*(m_RandomExtractionCounter); +// if (thresh1>fib->GetFiberPolyData()->GetNumberOfCells()) +// { +// thresh1=fib->GetFiberPolyData()->GetNumberOfCells(); +// } +// if (thresh2>fib->GetFiberPolyData()->GetNumberOfCells()) +// { +// thresh2=fib->GetFiberPolyData()->GetNumberOfCells(); +// } + +// if (thresh1!=fib->GetFiberPolyData()->GetNumberOfCells()) + if (m_Controls->m_NumRandomFibers->value()!=fib->GetFiberPolyData()->GetNumberOfCells()) + { +// for ( int i=thresh1; im_NumRandomFibers->value(); i++) + { + vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + + counter++; + + } + + for ( int i=0; im_NumRandomFibers->value(); i++) + { + fib->GetFiberPolyData()->DeleteCell(i); + } + fib->GetFiberPolyData()->RemoveDeletedCells(); + + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + +// m_SelectedFB.at(0)->SetData(fib); + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + m_newfibersFibersData = vtkSmartPointer::New(); + m_newfibersFibersData->SetPoints(vtkSmartPointer::New()); + m_newfibersFibersData->SetLines(vtkSmartPointer::New()); + m_newfibersFibersData->SetPoints(vNewPoints); + m_newfibersFibersData->SetLines(vNewLines); + + m_newfibersBundle = mitk::FiberBundle::New(vNewPolyData); + m_newfibersBundle->SetFiberColors(255, 255, 255); + m_newfibersBundle->SetFiberWeights(weights); + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_newfibersBundle); + node->SetName("ToLabel"); +// node->SetData(m_negativeBundle); +// node->SetFloatProperty("shape.tuberadius", 0.5); +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + m_newfibersBundleNode = node; + +// MITK_INFO << "Number of Streamlines in first function"; +// MITK_INFO << m_newfibersBundleNode->GetData()->GetFiberPolyData()->GetNumberOfCells(); + this->GetDataStorage()->Add(m_newfibersBundleNode); + + mitk::FiberBundle::Pointer m_negativeBundle = mitk::FiberBundle::New(); + mitk::DataNode::Pointer node2 = mitk::DataNode::New(); + node2->SetName("-Bundle"); + node2->SetData(m_negativeBundle); +// node->SetFloatProperty("shape.tuberadius", 0.5); +// mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + m_negativeBundleNode = node2; + this->GetDataStorage()->Add(m_negativeBundleNode); + + m_RandomExtractionCounter++; + } + +// m_Controls->m_ErazorButton->setChecked(true); + + + UpdateGui(); + + +} + +void QmitkInteractiveFiberDissectionView::RemovefromBundle( bool checked ) +{ + if (checked) + { + m_Controls->m_BrushButton->setChecked(false); + +// if (m_StreamlineInteractor.IsNull()) +// { + this->CreateStreamlineInteractorBrush(); + this->CreateStreamlineInteractor(); +// } + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(false); + m_StreamlineInteractor->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractor->SetToLabelNode(m_newfibersBundleNode); + m_StreamlineInteractor->EnableInteraction(true); + +// m_StreamlineInteractor->EnableInteraction(true); +// m_StreamlineInteractor->LabelfromPrediction(false); +// m_StreamlineInteractor->SetNegativeNode(m_negativeBundleNode); +// m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); +// m_StreamlineInteractor->SetToLabelNode(m_newfibersBundleNode); +// } +// else +// { +// m_StreamlineInteractor->EnableInteraction(true); +// m_StreamlineInteractor->LabelfromPrediction(false); +// m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); +// m_StreamlineInteractor->SetToLabelNode(m_newfibersBundleNode); +// } + } + else + { + m_StreamlineInteractor->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + + + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromBundleBrush( bool checked ) +{ + if (checked) + { + m_Controls->m_ErazorButton->setChecked(false); + +// if (m_StreamlineInteractorBrush.IsNull()) +// { + this->CreateStreamlineInteractor(); + this->CreateStreamlineInteractorBrush(); +// } + + + m_StreamlineInteractorBrush->EnableInteraction(true); + m_StreamlineInteractorBrush->LabelfromPrediction(false); + m_StreamlineInteractorBrush->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractorBrush->SetToLabelNode(m_newfibersBundleNode); + m_StreamlineInteractorBrush->EnableInteraction(true); +// m_StreamlineInteractorBrush->EnableInteraction(true); +// m_StreamlineInteractorBrush->LabelfromPrediction(false); +// m_StreamlineInteractorBrush->SetNegativeNode(m_negativeBundleNode); +// m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); +// m_StreamlineInteractorBrush->SetToLabelNode(m_newfibersBundleNode); +// } +// else +// { +// m_StreamlineInteractorBrush->EnableInteraction(true); +// m_StreamlineInteractorBrush->LabelfromPrediction(false); +// m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); +// m_StreamlineInteractorBrush->SetToLabelNode(m_newfibersBundleNode); +// } + } + else + { + m_StreamlineInteractorBrush->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + + + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::CreateStreamlineInteractor() +{ + + m_StreamlineInteractor = mitk::StreamlineInteractor::New(); + + m_StreamlineInteractor->LoadStateMachine("Streamline3DStates.xml", us::ModuleRegistry::GetModule("MitkFiberDissection")); + m_StreamlineInteractor->SetEventConfig("Streamline3DConfig.xml", us::ModuleRegistry::GetModule("MitkFiberDissection")); + +// m_StreamlineInteractor->SetRotationEnabled(rotationEnabled); +} + +void QmitkInteractiveFiberDissectionView::CreateStreamlineInteractorBrush() +{ + + m_StreamlineInteractorBrush = mitk::StreamlineInteractorBrush::New(); + + m_StreamlineInteractorBrush->LoadStateMachine("StreamlineBrush3DStates.xml", us::ModuleRegistry::GetModule("MitkFiberDissection")); + m_StreamlineInteractorBrush->SetEventConfig("StreamlineBrush3DConfig.xml", us::ModuleRegistry::GetModule("MitkFiberDissection")); + +// m_StreamlineInteractor->SetRotationEnabled(rotationEnabled); +} + +void QmitkInteractiveFiberDissectionView::StartAlgorithm() +{ + + m_negativeBundle = dynamic_cast(m_negativeBundleNode->GetData()); + m_positiveBundle = dynamic_cast(m_positiveBundleNode->GetData()); + + + this->GetDataStorage()->Remove(m_UncertaintyLabelNode); + this->GetDataStorage()->Remove(m_DistanceLabelNode); + + + MITK_INFO << "Clean Test Data"; + +// this->CleanTestArray(); + m_testnode = m_Controls->m_TestBundleBox->GetSelectedNode(); +// mitk::FiberBundle::Pointer fib = dynamic_cast(m_SelectedFB.at(0)->GetData()); + mitk::FiberBundle::Pointer fib = dynamic_cast(m_testnode->GetData()); + + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + fib->GetFiberPolyData()->RemoveDeletedCells(); + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + + + m_Controls->m_unclabeling->setChecked(false); + m_Controls->m_distlabeling->setChecked(false); + m_Controls->m_unclabelingBrush->setChecked(false); + m_Controls->m_predlabeling->setChecked(false); + m_Controls->m_predlabelingBrush->setChecked(false); + m_uncCounter = 0; + +// classifier.reset(); + MITK_INFO << "Extract Features"; + + classifier = std::make_shared(); + classifier->SetActiveCycle(m_activeCycleCounter); + classifier->SetTractogramPlus(m_positiveBundle); + classifier->SetTractogramMinus(m_negativeBundle); + classifier->SetTractogramPrototypes(dynamic_cast(m_Controls->m_PrototypeBox->GetSelectedNode()->GetData()), m_Controls->m_useStandardP->isChecked()); +// classifier->SetTractogramTest(dynamic_cast(m_SelectedFB.at(0)->GetData()), m_SelectedFB.at(0)->GetName()); + classifier->SetTractogramTest(dynamic_cast(m_testnode->GetData()), m_testnode->GetName()); +// classifier->SetTractogramTest(dynamic_cast(m_trainbundle->GetData()), m_trainbundle->GetName()); + + + + classifier->Update(); + + m_index = classifier->m_index; + MITK_INFO << "Number of Cycles"; + MITK_INFO << m_activeCycleCounter; + m_activeCycleCounter += 1; + + + MITK_INFO << "Algorithm run succesfully"; +// mitk::DataNode::Pointer node = mitk::DataNode::New(); +// this->GetDataStorage()->Add(node); + m_Controls->m_CreatePrediction->setEnabled(true); + UpdateGui(); + +} + +void QmitkInteractiveFiberDissectionView::CreatePredictionNode() +{ + MITK_INFO << "Create Prediction"; + + m_Prediction = classifier->CreatePrediction(m_index.at(0), false); + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_Prediction); + auto s = std::to_string(m_activeCycleCounter); + node->SetName("Prediction"+s); + m_PredictionNode = node; + this->GetDataStorage()->Add(m_PredictionNode); + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::CreateCertainNode() +{ + MITK_INFO << "Create Certain Data"; + + + m_CertainMinus = classifier->CreatePrediction(m_index.at(2), false); + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_CertainMinus); + auto s = std::to_string(m_activeCycleCounter); + node->SetName("m_CertainMinus"+s); + m_CertainMinusNode = node; + this->GetDataStorage()->Add(m_CertainMinusNode); + +// m_CertainPlus = classifier->CreatePrediction(m_index.at(4)); +// mitk::DataNode::Pointer node2= mitk::DataNode::New(); +// node2->SetData(m_CertainPlus); +// node2->SetName("m_CertainPlus"+s); +// m_CertainPlusNode = node2; +// this->GetDataStorage()->Add(m_CertainPlusNode); + + +// m_CertainBetweenMinus = classifier->CreatePrediction(m_index.at(4)); +// mitk::DataNode::Pointer node3 = mitk::DataNode::New(); +// node3->SetData(m_CertainBetweenMinus); +// node3->SetName("m_CertainBetweenMinus"+s); +// m_CertainBetweenMinusNode = node3; +// this->GetDataStorage()->Add(m_CertainBetweenMinusNode); + +// m_CertainBetweenPlus = classifier->CreatePrediction(m_index.at(6)); +// mitk::DataNode::Pointer node4= mitk::DataNode::New(); +// node4->SetData(m_CertainBetweenPlus); +// node4->SetName("m_CertainBetweenPlus"+s); +// m_CertainBetweenPlusNode = node4; +// this->GetDataStorage()->Add(m_CertainBetweenPlusNode); + +} + +void QmitkInteractiveFiberDissectionView::RemoveCertainData() +{ +// mitk::FiberBundle::Pointer fib = dynamic_cast(m_SelectedFB.at(0)->GetData()); + mitk::FiberBundle::Pointer fib = dynamic_cast(m_testnode->GetData()); + MITK_INFO << "Length of certain negativ data:"; + MITK_INFO << m_index.at(2).size(); + MITK_INFO << "Length of Testdata"; + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + for (unsigned int i=0; i< m_index.at(2).size(); i++) + { + fib->GetFiberPolyData()->DeleteCell(m_index.at(2).at(i)); + } +// fib->GetFiberPolyData()->RemoveDeletedCells(); + + MITK_INFO << "Length of Testdata"; + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); +} + +void QmitkInteractiveFiberDissectionView::CreateUncertaintySampleNode() +{ + this->GetDataStorage()->Remove(m_UncertaintyLabelNode); + MITK_INFO << "Create Fibers to label based on Uncertainty"; + + std::vector vec = m_index.at(1); + std::vector myvec = {vec.begin() + m_uncCounter, vec.begin() + m_uncCounter + m_Controls->m_Numtolabel->value()}; + m_uncCounter = m_uncCounter + m_Controls->m_Numtolabel->value(); + MITK_INFO << m_index.at(1).size(); + MITK_INFO << myvec.size(); + + + m_UncertaintyLabel = classifier->CreatePrediction(myvec, true); + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_UncertaintyLabel); + float d = 5.0; + + auto s = std::to_string(m_activeCycleCounter); + node->SetName("UncertaintyLabel"+s); + m_UncertaintyLabelNode = node; + m_UncertaintyLabelNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(d)); + this->GetDataStorage()->Add(m_UncertaintyLabelNode); + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::CreateDistanceSampleNode() +{ +// MITK_INFO << "Create Fibers to label based on Distance in Features-Space"; +// std::vector myvec = m_index.at(2); +// myvec.resize(m_Controls->m_Numtolabel2->value()); +// MITK_INFO << m_index.at(2).size(); +// MITK_INFO << myvec.size(); + + float myval = m_Controls->m_subsetfft->value() * 0.01; + MITK_INFO << myval; + std::vector> curidx; + curidx = classifier->GetDistanceData(myval); + std::vector myvec = curidx.at(0); + myvec.resize(m_Controls->m_Numtolabel2->value()); + MITK_INFO << m_index.at(2).size(); + MITK_INFO << myvec.size(); + m_DistanceLabel = classifier->CreatePrediction(myvec, true); + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(m_DistanceLabel); + auto s = std::to_string(m_activeCycleCounter); + node->SetName("DistanceLabel"+s); + m_DistanceLabelNode = node; + this->GetDataStorage()->Add(m_DistanceLabelNode); + UpdateGui(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromUncertainty( bool checked ) +{ + if (checked) + { + m_Controls->m_unclabelingBrush->setChecked(false); + m_Controls->m_predlabelingBrush->setChecked(false); + m_Controls->m_predlabeling->setChecked(false); + + + m_UncertaintyLabel->SetFiberColors(255, 255, 255); + this->CreateStreamlineInteractor(); + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(false); + m_StreamlineInteractor->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractor->SetToLabelNode(m_UncertaintyLabelNode); + } + else + { + m_StreamlineInteractor->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromUncertaintyBrush( bool checked ) +{ + if (checked) + { + m_Controls->m_unclabeling->setChecked(false); + m_Controls->m_predlabelingBrush->setChecked(false); + m_Controls->m_predlabeling->setChecked(false); + + m_UncertaintyLabel->SetFiberColors(255, 255, 255); + this->CreateStreamlineInteractorBrush(); + m_StreamlineInteractorBrush->EnableInteraction(true); + m_StreamlineInteractorBrush->LabelfromPrediction(false); + m_StreamlineInteractorBrush->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractorBrush->SetToLabelNode(m_UncertaintyLabelNode); + } + else + { + m_StreamlineInteractorBrush->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromDistance( bool checked ) +{ + if (checked) + { + + m_DistanceLabel->SetFiberColors(255, 255, 255); + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(false); + m_StreamlineInteractor->SetToLabelNode(m_DistanceLabelNode); + } + else + { + m_StreamlineInteractor->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; + } + RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkInteractiveFiberDissectionView::RemovefromPrediction( bool checked ) +{ + if (checked) + { + m_Controls->m_predlabelingBrush->setChecked(false); + m_Controls->m_unclabelingBrush->setChecked(false); + m_Controls->m_unclabeling->setChecked(false); + +// m_Prediction->SetFiberColors(255, 255, 255); + this->CreateStreamlineInteractor(); + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(true); + m_StreamlineInteractor->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractor->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractor->SetToLabelNode(m_PredictionNode); + } + else + { + m_StreamlineInteractor->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; +// this->CleanTestArray(); + } + +} + +void QmitkInteractiveFiberDissectionView::RemovefromPredictionBrush( bool checked ) +{ + if (checked) + { + m_Controls->m_predlabeling->setChecked(false); + m_Controls->m_unclabelingBrush->setChecked(false); + m_Controls->m_unclabeling->setChecked(false); + +// m_Prediction->SetFiberColors(255, 255, 255); + this->CreateStreamlineInteractorBrush(); + m_StreamlineInteractorBrush->EnableInteraction(true); + m_StreamlineInteractorBrush->LabelfromPrediction(true); + m_StreamlineInteractorBrush->SetNegativeNode(m_negativeBundleNode); + m_StreamlineInteractorBrush->SetPositiveNode(m_positiveBundleNode); + m_StreamlineInteractorBrush->SetToLabelNode(m_PredictionNode); + } + else + { + m_StreamlineInteractorBrush->EnableInteraction(false); +// m_StreamlineInteractor = nullptr; +// this->CleanTestArray(); + } + +} + +void QmitkInteractiveFiberDissectionView::RemovefromSelection( bool checked ) +{ + if (checked) + { + + // m_Prediction->SetFiberColors(255, 255, 255); + m_StreamlineInteractor->EnableInteraction(true); + m_StreamlineInteractor->LabelfromPrediction(true); +// m_StreamlineInteractor->SetToLabelNode(m_SelectedFB.at(0)); + m_StreamlineInteractor->SetToLabelNode(m_testnode); + } + else + { + m_StreamlineInteractor->EnableInteraction(false); + // m_StreamlineInteractor = nullptr; + } +} + +void QmitkInteractiveFiberDissectionView::StartValidation() +{ + + + + + validater.reset(); +// mitk::DataNode::Pointer prednode = m_Controls->m_BundleBox->GetSelectedNode(); +// mitk::FiberBundle::Pointer pred = dynamic_cast(prednode->GetData()); +// mitk::DataNode::Pointer gtnode = m_Controls->m_BundleBox->GetSelectedNode(); +// mitk::FiberBundle::Pointer gt = dynamic_cast(gtnode->GetData()); +// mitk::FiberBundle::Pointer pred = dynamic_cast(m_Controls->m_PredictionBox->GetSelectedNode()->GetData()); +// mitk::FiberBundle::Pointer gt = dynamic_cast(m_Controls->m_GroundtruthBox->GetSelectedNode()->GetData()); + + validater= std::make_shared(); + validater->SetTractogramPrototypes(dynamic_cast(m_Controls->m_PrototypeBox->GetSelectedNode()->GetData()), m_Controls->m_useStandardP->isChecked()); + MITK_INFO << "Prototypes loaded"; + validater->SetTractogramPrediction(dynamic_cast(m_Controls->m_PredictionBox->GetSelectedNode()->GetData())); + MITK_INFO << "Prediction loaded"; + validater->SetTractogramGroundtruth(dynamic_cast(m_Controls->m_GroundtruthBox->GetSelectedNode()->GetData())); + MITK_INFO << "Groundtruth loaded"; + + validater->SetActiveCycle(m_activeCycleCounter); +// validater->SetTractogramTest(dynamic_cast(m_SelectedFB.at(0)->GetData()), m_SelectedFB.at(0)->GetName()); + validater->SetTractogramTest(dynamic_cast(m_testnode->GetData()), m_testnode->GetName()); +// classifier->SetTractogramTest(dynamic_cast(m_trainbundle->GetData()), m_trainbundle->GetName()); + + + + MITK_INFO << "Testdata loaded"; + vnl_vector metrics; + metrics = validater->ValidationPipe(); + + m_metrics.push_back(metrics); + + + std::ofstream metricsfile; + metricsfile.open("/home/r948e/mycsv/metrics_" + std::to_string(m_activeCycleCounter) + ".csv"); + for (unsigned int i = 0; i < m_metrics.size(); i++) + { + metricsfile << m_metrics.at(i) << std::endl; + } + + metricsfile.close(); + + + MITK_INFO << "Validation run succesfully"; + + UpdateGui(); + +} + +void QmitkInteractiveFiberDissectionView::AutomaticLabelling() +{ +// mitk::FiberBundle::Pointer fib = dynamic_cast(m_SelectedFB.at(0)->GetData()); +// mitk::FiberBundle::Pointer fib_true = dynamic_cast(m_Controls->m_GroundtruthBox->GetSelectedNode()->GetData()); +// vtkCell* cell; +// vtkCell* cell2; +// for (int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) +// { +// cell = fib->GetFiberPolyData()->GetCell(i); +// for (int k=0; kGetFiberPolyData()->GetNumberOfCells(); k++ ) +// { +// cell2 = fib_true->GetFiberPolyData()->GetCell(i); +// if (cell==cell2) +// MITK_INFO << "Same"; +// } +// } + + mitk::FiberBundle::Pointer fib = dynamic_cast(m_PredictionNode->GetData()); + mitk::FiberBundle::Pointer fib_true = dynamic_cast(m_positiveBundleNode->GetData()); + + vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); + vtkSmartPointer vNewLines = vtkSmartPointer::New(); + vtkSmartPointer vNewPoints = vtkSmartPointer::New(); + + vtkSmartPointer weights = vtkSmartPointer::New(); + + /* Check wether all Streamlines of the bundles are labeled... If all are labeled Skip for Loop*/ + unsigned int counter = 0; + + for (int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = fib->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + for (int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + vtkCell* cell = fib_true->GetFiberPolyData()->GetCell(i); + auto numPoints = cell->GetNumberOfPoints(); + vtkPoints* points = cell->GetPoints(); + + vtkSmartPointer container = vtkSmartPointer::New(); + for (unsigned int j=0; jGetPoint(j, p); + + vtkIdType id = vNewPoints->InsertNextPoint(p); + container->GetPointIds()->InsertNextId(id); + } + weights->InsertValue(counter, fib_true->GetFiberWeight(i)); + vNewLines->InsertNextCell(container); + counter++; + + } + + + + vNewPolyData->SetLines(vNewLines); + vNewPolyData->SetPoints(vNewPoints); + + mitk::FiberBundle::Pointer MergedPrediction = mitk::FiberBundle::New(vNewPolyData); + MergedPrediction->SetFiberWeights(weights); + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(MergedPrediction); + node->SetName("MergedPrediction"); + this->GetDataStorage()->Add(node); + + +} + +void QmitkInteractiveFiberDissectionView::CleanTestArray() +{ + + mitk::FiberBundle::Pointer fib_pos = dynamic_cast(m_positiveBundleNode->GetData()); + mitk::FiberBundle::Pointer fib_neg = dynamic_cast(m_negativeBundleNode->GetData()); +// mitk::FiberBundle::Pointer fib = dynamic_cast(m_SelectedFB.at(0)->GetData()); + mitk::FiberBundle::Pointer fib = dynamic_cast(m_testnode->GetData()); + vtkCell* cur_cell; + vtkCell* cur_cell2; + MITK_INFO << fib_neg->GetFiberPolyData()->GetNumberOfCells(); + MITK_INFO << fib_pos->GetFiberPolyData()->GetNumberOfCells(); + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + + + std::vector array; + std::vector array2; + + + // cv::parallel_for_(cv::Range(0, fib->GetFiberPolyData()->GetNumberOfCells()), [&](const cv::Range &range) + // { + // for (int i = range.start; i < range.end; i++) + for (int i=0; iGetFiberPolyData()->GetNumberOfCells(); i++) + { + cur_cell = fib->GetFiberPolyData()->GetCell(i); + auto numPoints = cur_cell->GetNumberOfPoints(); + vtkPoints* points = cur_cell->GetPoints(); + for (unsigned int j=0; jGetPoint(j, p); + array.push_back(*p); + } + for (int ik=0; ikGetFiberPolyData()->GetNumberOfCells(); ik++) + { + cur_cell2 = fib_neg->GetFiberPolyData()->GetCell(ik); + auto numPoints2 = cur_cell2->GetNumberOfPoints(); + vtkPoints* points2 = cur_cell2->GetPoints(); + for (unsigned int j2=0; j2GetPoint(j2, p2); + array2.push_back(*p2); + + } + if (array==array2) + { + fib->GetFiberPolyData()->DeleteCell(i); + MITK_INFO << "Delete Cell"; + } + array2.clear(); + } + for (int ik=0; ikGetFiberPolyData()->GetNumberOfCells(); ik++) + { + + cur_cell2 = fib_pos->GetFiberPolyData()->GetCell(ik); + auto numPoints2 = cur_cell2->GetNumberOfPoints(); + vtkPoints* points2 = cur_cell2->GetPoints(); + for (unsigned int j2=0; j2GetPoint(j2, p2); + array2.push_back(*p2); + } + if (array==array2) + { + fib->GetFiberPolyData()->DeleteCell(i); + MITK_INFO << "Delete Cell"; + } + array2.clear(); + } + array.clear(); + } + // }); + +// fib->GetFiberPolyData()->RemoveDeletedCells(); + + MITK_INFO << fib->GetFiberPolyData()->GetNumberOfCells(); + + + +} + +void QmitkInteractiveFiberDissectionView::ResetClassifier() +{ + m_IterationCounter = 0; + m_RandomExtractionCounter = 0; + m_activeCycleCounter = 0; + m_createdStreamlineCounter = 0; + + classifier.reset(); + this->GetDataStorage()->Remove(m_positiveBundleNode); + this->GetDataStorage()->Remove(m_negativeBundleNode); + this->GetDataStorage()->Remove(m_negativeBundleNode); + + m_positiveBundleNode = NULL; + m_negativeBundleNode = NULL; + m_negativeBundleNode = NULL; + m_positiveBundle = NULL; + m_negativeBundle = NULL; + m_negativeBundle = NULL; + m_Controls->m_TrainClassifier->setEnabled(false); + m_Controls->m_CreatePrediction->setEnabled(false); + m_Controls->m_CreateUncertantyMap->setEnabled(false); + + + +} diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.h b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.h new file mode 100644 index 0000000..acab0f6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionView.h @@ -0,0 +1,191 @@ +/*=================================================================== + +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 QmitkInteractiveFiberDissectionView_h +#define QmitkInteractiveFiberDissectionView_h +#include "ui_QmitkInteractiveFiberDissectionViewControls.h" + +#include //Pointset +#include //Pointset + +#include //Pointset +#include //Pointset + + +#include +#include +#include //Pointset +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! +\brief View to process fiber bundles. Supplies methods to extract fibers from the bundle, fiber resampling, mirroring, join and subtract bundles and much more. +*/ +class QmitkInteractiveFiberDissectionView : public QmitkAbstractView, public mitk::IRenderWindowPartListener +{ + // 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: + + typedef itk::Image< unsigned char, 3 > ItkUCharImageType; + typedef itk::Image< float, 3 > ItkFloatImageType; + + static const std::string VIEW_ID; + + QmitkInteractiveFiberDissectionView(); + virtual ~QmitkInteractiveFiberDissectionView(); + + virtual void CreateQtPartControl(QWidget *parent) override; + + /// + /// Sets the focus to an internal widget. + /// + virtual void SetFocus() override; + +protected slots: + + void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; //Pointset + void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override; //Pointset + void OnAddPointSetClicked();//Pointset + void CreateStreamline(); + void RemovefromBundle( bool checked ); + void RemovefromBundleBrush( bool checked ); + void ExtractRandomFibersFromTractogram(); + void StartAlgorithm(); + void CreatePredictionNode(); + void CreateCertainNode(); + void CreateUncertaintySampleNode(); + void CreateDistanceSampleNode(); + void RemovefromUncertainty( bool checked ); + void RemovefromUncertaintyBrush( bool checked ); + void RemovefromDistance( bool checked ); + void RemovefromPrediction( bool checked ); + void RemovefromPredictionBrush( bool checked ); + void RemovefromSelection( bool checked ); + void ResampleTractogram(); + void RandomPrototypes(); + void SFFPrototypes(); + void StartValidation(); + void AutomaticLabelling(); + void RemoveCertainData(); + void ResetClassifier(); + + + + void UpdateGui(); ///< update button activity etc. dpending on current datamanager selection + + + + +protected: + void OnCurrentSelectionChanged(QmitkSingleNodeSelectionWidget::NodeList nodes);//Pointset + + + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override; + + void OnEndInteraction(); + void CreateStreamlineInteractor(); + void CreateStreamlineInteractorBrush(); + void CleanTestArray(); + + Ui::QmitkInteractiveFiberDissectionViewControls* m_Controls; + + + + int m_IterationCounter; ///< used for data node naming + int m_RandomExtractionCounter; ///< used for random extracton of different Streamlines + int m_activeCycleCounter; + int m_newpos; + int m_newneg; + int m_startneg; + int m_createdStreamlineCounter; + int m_uncCounter; +// int m_thresh2; + + + std::vector m_SelectedFB; ///< selected fiber bundle nodes + mitk::DataNode::Pointer m_testnode; +// mitk::DataNode::Pointer m_trainbundle; + mitk::Image::Pointer m_SelectedImage; + mitk::DataNode::Pointer m_SelectedPS; + mitk::DataNode::Pointer m_SelectedImageNode; + mitk::FiberBundle::Pointer m_positiveBundle; + mitk::FiberBundle::Pointer m_newfibersBundle; + mitk::FiberBundle::Pointer m_negativeBundle; + mitk::FiberBundle::Pointer m_Prediction; + mitk::FiberBundle::Pointer m_CertainPlus; + mitk::FiberBundle::Pointer m_CertainMinus; + mitk::FiberBundle::Pointer m_CertainBetweenPlus; + mitk::FiberBundle::Pointer m_CertainBetweenMinus; + mitk::FiberBundle::Pointer m_UncertaintyLabel; + mitk::FiberBundle::Pointer m_DistanceLabel; + + + mitk::DataNode::Pointer m_positiveBundleNode; + mitk::DataNode::Pointer m_newfibersBundleNode; + mitk::DataNode::Pointer m_negativeBundleNode; + mitk::DataNode::Pointer m_PredictionNode; + mitk::DataNode::Pointer m_CertainPlusNode; + mitk::DataNode::Pointer m_CertainMinusNode; + mitk::DataNode::Pointer m_CertainBetweenPlusNode; + mitk::DataNode::Pointer m_CertainBetweenMinusNode; + mitk::DataNode::Pointer m_UncertaintyLabelNode; + mitk::DataNode::Pointer m_DistanceLabelNode; + + vtkSmartPointer m_positiveFibersData; + vtkSmartPointer m_newfibersFibersData; + + vtkSmartPointer m_picker1; + mitk::StreamlineInteractor::Pointer m_StreamlineInteractor; + mitk::StreamlineInteractorBrush::Pointer m_StreamlineInteractorBrush; + + std::shared_ptr< mitk::StreamlineFeatureExtractor > classifier; + std::shared_ptr< mitk::StreamlineFeatureExtractor > validater; + + + std::vector> m_metrics; + + std::vector> m_index; + +}; + + + +#endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionViewControls.ui new file mode 100644 index 0000000..1747417 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkInteractiveFiberDissectionViewControls.ui @@ -0,0 +1,1125 @@ + + + QmitkInteractiveFiberDissectionViewControls + + + + 0 + 0 + 417 + 711 + + + + Form + + + QCommandLinkButton:disabled { + border: none; +} + +QGroupBox { + background-color: transparent; +} + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + true + + + + true + + + + Label Fibers + + + QFrame::NoFrame + + + 3 + + + 6 + + + + + 0 + 0 + 399 + 439 + + + + Generate Prototypes + + + + + + 0 + + + 0 + + + + + 0 + 0 + 381 + 359 + + + + Defaults + + + + + + Extract from + + + + + + + + + + SFF Extraction + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 273 + 171 + + + + Advanced Settings + + + + + + Number of Prototypes + + + + + + + 10 + + + 200 + + + 100 + + + + + + + Random Extraction + + + + + + + Resample Bundle + + + + + + + true + + + Use Standard Prototypes + + + true + + + + + + + Choose own Prototypes + + + + + + + + + + Qt::Vertical + + + + 20 + 170 + + + + + + + + + + + + + + 0 + 0 + 399 + 439 + + + + Fiber Creation + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Selected Streamline Pointset + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Streamline Points + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add new Streamline Pointset + + + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Create Streamline + + + + + + + + + + + true + + + + 0 + 0 + 399 + 439 + + + + + + + Fiber Labelling + + + Dissect/Eraze Fibers by Erasion and Highlighting + + + + + + true + + + ArrowCursor + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + Label individual Streamlines + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Streamlines to be labeled + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Label Streamlines + + + + + + + Unlabel: Leftclick + shift/alt + + + + + + + Reject: Rightclick + shift + + + + + + + + 30 + 30 + + + + + + + + :/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png + + + + 32 + 32 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Accept: Rightclick + alt + + + + + + + 1 + + + 2000 + + + 20 + + + + + + + Random Streamlines + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Add + + + + + + + + 30 + 30 + + + + + + + + :/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png + + + + 32 + 32 + + + + true + + + + + + + + + + + + 0 + 0 + 399 + 439 + + + + Active Learning + + + + + 0 + 0 + 381 + 391 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 0 + + + + + 0 + 0 + 361 + 309 + + + + Default + + + + + + Qt::Horizontal + + + + 57 + 20 + + + + + + + + Qt::Horizontal + + + + 57 + 20 + + + + + + + + Add + + + + + + + Qt::Horizontal + + + + 57 + 20 + + + + + + + + Label from Uncertainy Node + + + + + + + Train Classifier + + + + + + + + 30 + 30 + + + + + + + + :/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png + + + + 32 + 32 + + + + true + + + + + + + Unc: to label + + + + + + + Label from Prediction Node + + + + + + + Qt::Horizontal + + + + 57 + 20 + + + + + + + + + 30 + 30 + + + + + + + + :/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png + + + + 32 + 32 + + + + true + + + + + + + Create Prediction + + + + + + + + 30 + 30 + + + + + + + + :/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/eraze.png + + + + 32 + 32 + + + + true + + + + + + + 1 + + + 2000 + + + 0 + + + 20 + + + + + + + + 30 + 30 + + + + + + + + :/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/brush.png + + + + 32 + 32 + + + + true + + + + + + + Qt::Horizontal + + + + 57 + 20 + + + + + + + + Reset Classifier + + + + + + + + + 0 + 0 + 337 + 173 + + + + Advanced + + + + + + Label from Current Selection + + + + + + + Create Uncertanty Map + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Unc_dis_Label + + + + + + + Add + + + + + + + 100 + + + 95 + + + + + + + Certain Data + + + + + + + 100 + + + + + + + 1 + + + 500 + + + 20 + + + + + + + Dist: to label + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Label + + + + + + + Remove + + + + + + + + + + + + + + 0 + 0 + 399 + 439 + + + + Validation + + + + + 10 + 20 + 351 + 371 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Prediction + + + + + + + + + + Groundtrouth + + + + + + + Validate + + + + + + + Merge Prediction with Labled Data + + + + + + + + + + + + Please Select Input Data + + + + + + Training Fiber Bundle: + + + + + + + Input DTI + + + Selectd Fiber Bundle: + + + + + + + + + + <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> + + + true + + + + + + + + + + + QmitkDataStorageComboBox + QComboBox +
QmitkDataStorageComboBox.h
+
+ + QmitkSingleNodeSelectionWidget + QWidget +
QmitkSingleNodeSelectionWidget.h
+ 1 +
+ + QmitkPointListWidget + QWidget +
QmitkPointListWidget.h
+
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/mitkPluginActivator.cpp index 042b6c0..666fd1c 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/mitkPluginActivator.cpp @@ -1,51 +1,53 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "src/internal/Perspectives/QmitkFiberProcessingPerspective.h" #include "src/internal/QmitkFiberProcessingView.h" #include "src/internal/QmitkFiberQuantificationView.h" +#include "src/internal/QmitkInteractiveFiberDissectionView.h" #include "src/internal/QmitkFiberClusteringView.h" #include "src/internal/QmitkFiberFitView.h" #include "src/internal/QmitkTractometryView.h" ctkPluginContext* mitk::PluginActivator::m_Context = nullptr; ctkPluginContext* mitk::PluginActivator::GetContext() { return m_Context; } void mitk::PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberQuantificationView, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkInteractiveFiberDissectionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberClusteringView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberFitView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTractometryView, context) m_Context = context; } void mitk::PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_Context = nullptr; }