21 #include <qwt_plot_marker.h>
22 #include <qwt_plot_picker.h>
23 #include <qwt_picker_machine.h>
25 #include <vtkCellArray.h>
31 m_PlotPicker->setStateMachine(
new QwtPickerDragPointMachine());
72 int num = inBoth->GetNumFibers();
78 vtkSmartPointer<vtkPolyData> fiberPolyData = inBoth->GetFiberPolyData();
79 vtkCellArray* lines = fiberPolyData->GetLines();
80 lines->InitTraversal();
86 for(
int fiberID( 0 ); fiberID < num; fiberID++ )
88 vtkIdType numPointsInCell(0);
89 vtkIdType* pointsInCell(
nullptr);
90 lines->GetNextCell ( numPointsInCell, pointsInCell );
100 for(
int pointInCellID( 0 ); pointInCellID < numPointsInCell ; pointInCellID++)
104 mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
114 if(distanceToStart < minDistStart)
116 minDistStart = distanceToStart;
117 startId = pointInCellID;
120 if(distanceToEnd < minDistEnd)
122 minDistEnd = distanceToEnd;
123 endId = pointInCellID;
143 p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
145 p = fiberPolyData->GetPoint( pointsInCell[ startId+1 ] );
147 p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
153 pStart[0] = p0[0]; pStart[1] = p0[1]; pStart[2] = p0[2];
156 pSecond[0] = p1[0]; pSecond[1] = p1[1]; pSecond[2] = p1[2];
158 bool startOnPositive = startGeometry2D->
IsAbove(pStart);
159 bool secondOnPositive = startGeometry2D->
IsAbove(pSecond);
163 onPlane[0] = startCenter[0]; onPlane[1] = startCenter[1]; onPlane[2] = startCenter[2];
167 if(! (secondOnPositive ^ startOnPositive) )
171 p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] );
172 p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
179 point[0] = d*newPoint[0] + p0[0];
180 point[1] = d*newPoint[1] + p0[1];
181 point[2] = d*newPoint[2] + p0[2];
183 singleTract.push_back(point);
185 if(! (secondOnPositive ^ startOnPositive) )
191 point[0] = start[0]; point[1] = start[1]; point[2] = start[2];
192 singleTract.push_back(point);
197 for(
int pointInCellID( startId+1 ); pointInCellID < endId ; pointInCellID++)
200 mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
201 point[0] = p[0]; point[1] = p[1]; point[2] = p[2];
202 singleTract.push_back( point );
210 p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
211 p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
213 p = fiberPolyData->GetPoint( pointsInCell[ endId-1 ] );
214 p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
217 pLast[0] = p0[0]; pLast[1] = p0[1]; pLast[2] = p0[2];
220 pBeforeLast[0] = p1[0]; pBeforeLast[1] = p1[1]; pBeforeLast[2] = p1[2];
223 bool lastOnPositive = endGeometry2D->
IsAbove(pLast);
224 bool secondLastOnPositive = endGeometry2D->
IsAbove(pBeforeLast);
227 onPlane[0] = endCenter[0];
228 onPlane[1] = endCenter[1];
229 onPlane[2] = endCenter[2];
231 if(! (lastOnPositive ^ secondLastOnPositive) )
238 p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
239 point[0] = p[0]; point[1] = p[1]; point[2] = p[2];
240 singleTract.push_back( point );
242 p = fiberPolyData->GetPoint( pointsInCell[ endId+1 ] );
245 d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
249 point[0] = d*newPoint[0] + p0[0];
250 point[1] = d*newPoint[1] + p0[1];
251 point[2] = d*newPoint[2] + p0[2];
253 singleTract.push_back(point);
263 p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
265 p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] );
267 p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
273 pStart[0] = p0[0]; pStart[1] = p0[1]; pStart[2] = p0[2];
276 pSecond[0] = p1[0]; pSecond[1] = p1[1]; pSecond[2] = p1[2];
278 bool startOnPositive = startGeometry2D->
IsAbove(pStart);
279 bool secondOnPositive = startGeometry2D->
IsAbove(pSecond);
282 onPlane[0] = startCenter[0]; onPlane[1] = startCenter[1]; onPlane[2] = startCenter[2];
285 if(! (secondOnPositive ^ startOnPositive) )
289 p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] );
290 p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
298 point[0] = d*newPoint[0] + p0[0];
299 point[1] = d*newPoint[1] + p0[1];
300 point[2] = d*newPoint[2] + p0[2];
303 singleTract.push_back(point);
305 if(! (secondOnPositive ^ startOnPositive) )
311 point[0] = start[0]; point[1] = start[1]; point[2] = start[2];
312 singleTract.push_back(point);
317 for(
int pointInCellID( startId-1 ); pointInCellID > endId ; pointInCellID--)
320 mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
321 point[0] = p[0]; point[1] = p[1]; point[2] = p[2];
322 singleTract.push_back( point );
330 p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
331 p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
333 p = fiberPolyData->GetPoint( pointsInCell[ endId+1 ] );
334 p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
337 pLast[0] = p0[0]; pLast[1] = p0[1]; pLast[2] = p0[2];
340 pBeforeLast[0] = p1[0]; pBeforeLast[1] = p1[1]; pBeforeLast[2] = p1[2];
342 bool lastOnPositive = endGeometry2D->
IsAbove(pLast);
343 bool secondLastOnPositive = endGeometry2D->
IsAbove(pBeforeLast);
348 onPlane[0] = endCenter[0];
349 onPlane[1] = endCenter[1];
350 onPlane[2] = endCenter[2];
352 if(! (lastOnPositive ^ secondLastOnPositive) )
359 p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
360 point[0] = p[0]; point[1] = p[1]; point[2] = p[2];
361 singleTract.push_back( point );
363 p = fiberPolyData->GetPoint( pointsInCell[ endId-1 ] );
366 d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
370 point[0] = d*newPoint[0] + p0[0];
371 point[1] = d*newPoint[1] + p0[1];
372 point[2] = d*newPoint[2] + p0[2];
374 singleTract.push_back(point);
379 tracts.push_back(singleTract);
391 if(fib ==
nullptr || img ==
nullptr || startRoi ==
nullptr || endRoi ==
nullptr)
429 for(
auto it = tracts.begin(); it != tracts.end(); ++it)
441 for(
unsigned int i = 1; i<tract.size(); i++)
445 totalLength += length;
455 unsigned int tractCounter = 2;
460 position <= totalLength+0.001 && resampledTract.size() <= (number+1);
466 while(locationBetween > distance+0.001)
469 if(tractCounter == tract.size())
470 std::cout <<
"problem";
473 locationBetween = locationBetween - distance;
475 p1 = tract.at(tractCounter);
478 distance = p0.EuclideanDistanceTo(p1);
484 direction.Normalize();
486 PointType newSample = p0 + direction*locationBetween;
487 resampledTract.push_back(newSample);
490 locationBetween += stepSize;
495 resampledTracts.push_back(resampledTract);
499 return resampledTracts;
539 std::vector< std::vector<mitk::ScalarType> > profiles;
543 for(
int s=0; s<size; s++)
546 std::vector<mitk::ScalarType> profile;
547 RoiType::iterator it;
549 while(it !=
m_Roi.end())
552 profile.push_back(
m_Projections->GetPixel(ix).GetElement(s));
556 profiles.push_back(profile);
568 std::vector< std::vector<mitk::ScalarType> > groupProfiles;
570 std::vector< std::pair<std::string, int> >::iterator it;
575 while(it !=
m_Groups.end() && profiles.size() > 0)
577 std::pair<std::string, int> p = *it;
581 std::vector<mitk::ScalarType> averageProfile;
582 for(
unsigned int i=0; i<profiles.at(0).size(); i++)
584 averageProfile.push_back(0.0);
589 for(
int i=0; i<size; i++)
591 for(
unsigned int j=0; j<averageProfile.size(); ++j)
593 averageProfile.at(j) = averageProfile.at(j) + profiles.at(c).at(j);
599 for(
unsigned int i=0; i<averageProfile.size(); i++)
601 averageProfile.at(i) = averageProfile.at(i) / size;
604 groupProfiles.push_back(averageProfile);
609 return groupProfiles;
623 std::vector<mitk::ScalarType> v1;
626 std::vector<mitk::ScalarType> xAxis;
627 for(
unsigned int i=0; i<groupProfiles.at(0).size(); ++i)
634 for(
unsigned int i=0; i<groupProfiles.size(); i++)
640 for(
unsigned int j=0; j<groupProfiles.at(i).size(); j++)
642 v1.push_back(groupProfiles.at(i).at(j));
649 std::string title =
m_Measure +
" profiles on the ";
652 QPen pen( Qt::SolidLine );
657 std::vector< std::pair<std::string, int> >::iterator it;
662 QColor colors[4] = {Qt::green, Qt::blue, Qt::yellow, Qt::red};
664 while(it !=
m_Groups.end() && groupProfiles.size() > 0)
667 std::pair< std::string, int > group = *it;
669 pen.setColor(colors[c]);
670 int curveId = this->
InsertCurve( group.first.c_str() );
671 this->
SetCurveData( curveId, xAxis, groupProfiles.at(c) );
682 auto legend =
new QwtLegend;
683 this->
SetLegend(legend, QwtPlot::RightLegend, 0.5);
688 this->
m_Plot->setAxisTitle(3,
"Position");
704 int nTracts = resampledTracts.size();
711 std::vector< std::vector<mitk::ScalarType> > profiles;
715 for(
int s=0; s<size; s++)
720 for(
int t=0; t<nTracts; t++)
723 std::vector<mitk::ScalarType> profile;
724 auto it = resampledTracts[t].begin();
725 while(it != resampledTracts[t].end())
729 tbssImage->GetGeometry()->WorldToIndex(p, index);
737 profile.push_back(
m_Projections->GetPixel(ix).GetElement(s));
741 profiles.push_back(profile);
751 std::vector< std::pair<std::string, int> >::iterator it;
756 std::vector< std::vector<mitk::ScalarType> > groupProfiles;
758 while(it !=
m_Groups.end() && profiles.size() > 0)
760 std::pair<std::string, int> p = *it;
764 std::vector<mitk::ScalarType> averageProfile;
765 for(
unsigned int i=0; i<profiles.at(0).size(); i++)
767 averageProfile.push_back(0.0);
772 for(
int i=0; i<size*nTracts; i++)
774 for(
unsigned int j=0; j<averageProfile.size(); ++j)
776 averageProfile.at(j) = averageProfile.at(j) + profiles.at(c).at(j);
782 for(
unsigned int i=0; i<averageProfile.size(); i++)
784 averageProfile.at(i) = averageProfile.at(i) / (size*nTracts);
787 groupProfiles.push_back(averageProfile);
792 return groupProfiles;
813 template <
typename T>
820 auto it = tracts.begin();
823 std::vector< std::vector <mitk::ScalarType > > profiles;
828 while(it != tracts.end())
832 auto tractIt = tract.begin();
834 std::vector<mitk::ScalarType> profile;
836 while(tractIt != tract.end())
841 profile.push_back( (
mitk::ScalarType) imAccess.GetPixelByWorldCoordinates(p) );
846 profiles.push_back(profile);
847 std::cout << std::endl;
853 if(profiles.size() == 0)
859 std::string title =
"Fiber bundle plot";
864 std::vector<mitk::ScalarType> averageProfile;
865 std::vector<mitk::ScalarType> profile = profiles.at(0);
866 for(
unsigned int i=0; i<profile.size(); ++i)
868 averageProfile.push_back(0.0);
872 auto profit = profiles.begin();
875 while(profit != profiles.end())
877 std::vector<mitk::ScalarType> profile = *profit;
881 std::vector<mitk::ScalarType> xAxis;
882 for(
unsigned int i=0; i<profile.size(); ++i)
885 averageProfile.at(i) += profile.at(i) / profiles.size();
905 std::vector<mitk::ScalarType> xAxis;
906 for(
unsigned int i=0; i<averageProfile.size(); ++i)
917 QPen pen( Qt::SolidLine );
919 pen.setColor(Qt::red);
942 m_Plot->detachItems(QwtPlotItem::Rtti_PlotMarker,
true);
945 QwtPlotMarker *mX =
new QwtPlotMarker();
947 mX->setLabelAlignment(Qt::AlignLeft | Qt::AlignBottom);
948 mX->setLabelOrientation(Qt::Vertical);
949 mX->setLineStyle(QwtPlotMarker::VLine);
950 mX->setLinePen(QPen(Qt::black, 0, Qt::SolidLine));
Gives locked and index-based read access for a particular image part. The class provides several set-...
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
virtual ImageDataItemPointer GetVolumeData(int t=0, int n=0, void *data=nullptr, ImportMemoryManagementType importMemoryManagement=CopyMemory) const
Vector3D GetNormal() const
Normal of the plane.
itk::Vector< float, 3 > VectorType
virtual bool IsAbove(const Point3D &pt3d_mm, bool considerBoundingBox=false) const
Calculates, whether a point is below or above the plane. There are two different calculation methods...
#define mitkPixelTypeMultiplex3(function, ptype, param1, param2, param3)
Image class for storing images.
Base Class for Fiber Bundles;.
FiberBundle::Pointer ExtractFiberSubset(DataNode *roi, DataStorage *storage)
Describes a two-dimensional, rectangular plane.
ImageDescriptor::Pointer GetImageDescriptor() const
Class for nodes of the DataTree.
Class for defining the data type of pixels.