15 #include <vtkPolyData.h> 16 #include <vtkCardinalSpline.h> 38 mBranches.push_back(b);
43 for(
int i = 0; i < mBranches.size(); i++ )
45 if (b == mBranches[i])
47 mBranches.erase(mBranches.begin() + i);
65 std::vector<int> branchNumbersToBeDeleted;
66 for(
int i = 0; i < mBranches.size(); i++ )
68 int generationCounter = 1;
70 while (currentBranch->getParentBranch()){
72 currentBranch = currentBranch->getParentBranch();
73 if (generationCounter > maxGeneration)
75 branchNumbersToBeDeleted.push_back(i);
82 for (
int i = branchNumbersToBeDeleted.size() - 1; i >= 0; i-- )
89 for (
int i = 0; i < mBranches.size(); i++)
91 Eigen::MatrixXd positions = mBranches[i]->getPositions();
92 Eigen::MatrixXd diff = positions.rightCols(positions.cols() - 1) - positions.leftCols(positions.cols() - 1);
93 Eigen::MatrixXd orientations(positions.rows(),positions.cols());
94 orientations.leftCols(orientations.cols() - 1) = diff / diff.norm();
95 orientations.rightCols(1) = orientations.col(orientations.cols() - 1);
96 mBranches[i]->setOrientations(orientations);
102 for (
int i = 0; i < mBranches.size(); i++)
104 Eigen::MatrixXd orientations = mBranches[i]->getOrientations();
105 Eigen::MatrixXd newOrientations(orientations.rows(),orientations.cols());
106 int numberOfColumns = orientations.cols();
107 for (
int j = 0; j < numberOfColumns; j++)
109 newOrientations.col(j) = orientations.block(0,std::max(j-2,0),orientations.rows(),std::min(5,numberOfColumns-j)).rowwise().mean();
110 newOrientations.col(j) = newOrientations.col(j) / newOrientations.col(j).norm();
112 mBranches[i]->setOrientations(newOrientations);
118 for (
int i = 0; i < mBranches.size(); i++)
120 Eigen::MatrixXd positions = mBranches[i]->getPositions();
122 if (mBranches[i]->getParentBranch())
124 Eigen::MatrixXd parentPositions = mBranches[i]->getParentBranch()->getPositions();
125 Eigen::MatrixXd positionsResized(positions.rows(), positions.cols()+1);
126 positionsResized.col(0) = parentPositions.rightCols(1);
127 positionsResized.rightCols(positions.cols()) = positions;
128 positions = positionsResized;
131 std::vector<Eigen::Vector3d> interpolatedPositions;
132 for (
int j = 0; j < positions.cols()-1; j++)
134 for (
int k = 0; k < interpolationFactor; k++){
135 Eigen::Vector3d interpolationPoint;
136 interpolationPoint[0] = (positions(0,j)*(interpolationFactor-k) + positions(0,j+1)*(k) ) / interpolationFactor;
137 interpolationPoint[1] = (positions(1,j)*(interpolationFactor-k) + positions(1,j+1)*(k) ) / interpolationFactor;
138 interpolationPoint[2] = (positions(2,j)*(interpolationFactor-k) + positions(2,j+1)*(k) ) / interpolationFactor;
139 interpolatedPositions.push_back(interpolationPoint);
142 if (mBranches[i]->getParentBranch())
144 Eigen::MatrixXd positionsResized(positions.rows(), positions.cols()-1);
145 positionsResized = positions.rightCols(positionsResized.cols());
146 positions = positionsResized;
148 Eigen::MatrixXd interpolationResult(3 , interpolatedPositions.size());
149 for (
int j = 0; j < interpolatedPositions.size(); j++)
151 interpolationResult(0,j) = interpolatedPositions[j](0);
152 interpolationResult(1,j) = interpolatedPositions[j](1);
153 interpolationResult(2,j) = interpolatedPositions[j](2);
155 mBranches[i]->setPositions(interpolationResult);
162 for (
int i = 0; i < mBranches.size(); i++)
164 Eigen::MatrixXd positions = mBranches[i]->getPositions();
165 int numberOfInputPoints = positions.cols();
168 double branchLength = (positions.rightCols(1) - positions.leftCols(1)).norm();
169 int numberOfControlPoints =
std::ceil(branchLength/controlPointDistance);
170 numberOfControlPoints = std::max(numberOfControlPoints, 2);
177 for(
int j=0; j<numberOfControlPoints; j++)
179 int indexP = (j*numberOfInputPoints)/numberOfControlPoints;
181 splineX->AddPoint(indexP,positions(0,indexP));
182 splineY->AddPoint(indexP,positions(1,indexP));
183 splineZ->AddPoint(indexP,positions(2,indexP));
186 splineX->AddPoint(numberOfInputPoints-1,positions(0,numberOfInputPoints-1));
187 splineY->AddPoint(numberOfInputPoints-1,positions(1,numberOfInputPoints-1));
188 splineZ->AddPoint(numberOfInputPoints-1,positions(2,numberOfInputPoints-1));
191 Eigen::MatrixXd smoothingResult(3 , numberOfInputPoints);
192 for(
int j=0; j<numberOfInputPoints; j++)
194 double splineParameter = j;
195 smoothingResult(0,j) = splineX->Evaluate(splineParameter);
196 smoothingResult(1,j) = splineY->Evaluate(splineParameter);
197 smoothingResult(2,j) = splineZ->Evaluate(splineParameter);
199 mBranches[i]->setPositions(smoothingResult);
206 Eigen::MatrixXd positionsNotUsed_r = positions_r;
211 Eigen::MatrixXd::Index startIndex;
213 while (positionsNotUsed_r.cols() > 0)
215 if (!mBranches.empty())
217 double minDistance = 1000;
218 for (
int i = 0; i < mBranches.size(); i++)
220 std::pair<std::vector<Eigen::MatrixXd::Index>, Eigen::VectorXd> distances;
221 distances =
dsearchn(positionsNotUsed_r, mBranches[i]->getPositions());
222 double d = distances.second.minCoeff(&index);
226 branchToSplit = mBranches[i];
232 std::pair<Eigen::MatrixXd::Index, double> dsearchResult =
dsearch(positionsNotUsed_r.col(startIndex) , branchToSplit->getPositions());
233 splitIndex = dsearchResult.first;
236 startIndex = positionsNotUsed_r.cols() - 1;
238 std::pair<Eigen::MatrixXd,Eigen::MatrixXd > connectedPointsResult =
findConnectedPointsInCT(startIndex , positionsNotUsed_r);
239 Eigen::MatrixXd branchPositions = connectedPointsResult.first;
240 positionsNotUsed_r = connectedPointsResult.second;
242 if (branchPositions.cols() >= 5)
245 newBranch->setPositions(branchPositions);
246 mBranches.push_back(newBranch);
248 if (mBranches.size() > 1)
250 if ((splitIndex + 1 >= 5) && (branchToSplit->getPositions().cols() - splitIndex - 1 >= 5))
256 Eigen::MatrixXd branchToSplitPositions = branchToSplit->getPositions();
257 newBranchFromSplit->setPositions(branchToSplitPositions.rightCols(branchToSplitPositions.cols() - splitIndex - 1));
258 branchToSplit->setPositions(branchToSplitPositions.leftCols(splitIndex + 1));
259 mBranches.push_back(newBranchFromSplit);
260 newBranchFromSplit->setParentBranch(branchToSplit);
261 newBranch->setParentBranch(branchToSplit);
262 newBranchFromSplit->setChildBranches(branchToSplit->getChildBranches());
263 branchVector branchToSplitChildren = branchToSplit->getChildBranches();
264 for (
int i = 0; i < branchToSplitChildren.size(); i++)
265 branchToSplitChildren[i]->setParentBranch(newBranchFromSplit);
266 branchToSplit->deleteChildBranches();
267 branchToSplit->addChildBranch(newBranchFromSplit);
268 branchToSplit->addChildBranch(newBranch);
270 else if (splitIndex + 1 < 5)
275 newBranch->setParentBranch(branchToSplit->getParentBranch());
276 if(branchToSplit->getParentBranch())
277 branchToSplit->getParentBranch()->addChildBranch(newBranch);
279 else if (branchToSplit->getPositions().cols() - splitIndex - 1 < 5)
283 newBranch->setParentBranch(branchToSplit);
284 branchToSplit->addChildBranch(newBranch);
298 for (
int i = 0; i < mBranches.size(); i++)
301 b->setPositions(mBranches[i]->getPositions());
302 b->setOrientations(mBranches[i]->getOrientations());
303 retval->addBranch(b);
306 std::vector<BranchPtr> branches = retval->getBranches();
307 Eigen::MatrixXd positions;
308 Eigen::MatrixXd orientations;
309 for (
int i = 0; i < branches.size(); i++)
311 positions = branches[i]->getPositions();
312 orientations = branches[i]->getOrientations();
313 std::pair<std::vector<Eigen::MatrixXd::Index>, Eigen::VectorXd> distanceData;
314 distanceData =
dsearchn(positions, trackingPositions);
315 Eigen::VectorXd distance = distanceData.second;
316 for (
int j = positions.cols() - 1; j >= 0; j--)
318 if (distance(j) > maxDistance)
321 orientations =
eraseCol(j, orientations);
324 branches[i]->setPositions(positions);
325 branches[i]->setOrientations(orientations);
354 int positionCounter = 0;
355 for (
size_t i = 0; i < mBranches.size(); ++i)
357 Eigen::MatrixXd positions = mBranches[i]->getPositions();
361 points->InsertNextPoint(positions(0,0),positions(1,0),positions(2,0));
362 points->InsertNextPoint(positions(0,positions.cols()-1),positions(1,positions.cols()-1),positions(2,positions.cols()-1));
363 vtkIdType connection[2] = {positionCounter-1, positionCounter};
364 lines->InsertNextCell(2, connection);
369 for (
int j = 0; j < positions.cols(); ++j)
372 points->InsertNextPoint(positions(0,j),positions(1,j),positions(2,j));
373 if (j < positions.cols()-1)
375 vtkIdType connection[2] = {positionCounter-1, positionCounter};
376 lines->InsertNextCell(2, connection);
383 int this_branchs_first_point_in_full_polydata_point_list = 0;
384 for(
size_t i = 0; i < mBranches.size(); ++i)
388 if(!straightBranches)
389 this_branchs_first_point_in_full_polydata_point_list += mBranches[i-1]->getPositions().cols();
391 this_branchs_first_point_in_full_polydata_point_list += 2;
393 int parent_index_in_branch_list = mBranches[i]->findParentIndex(mBranches);
395 if(parent_index_in_branch_list > -1)
397 int parent_branch_last_point_in_full_polydata = 0;
398 for(
int j = 0; j <= parent_index_in_branch_list; ++j)
400 if(!straightBranches)
401 parent_branch_last_point_in_full_polydata += mBranches[j]->getPositions().cols() - 1;
403 parent_branch_last_point_in_full_polydata += (1 + j*2);
405 vtkIdType connection[2] = {parent_branch_last_point_in_full_polydata, this_branchs_first_point_in_full_polydata_point_list};
406 lines->InsertNextCell(2, connection);
412 retval->SetPoints(points);
413 retval->SetLines(lines);
418 Eigen::MatrixXd
sortMatrix(
int rowNumber, Eigen::MatrixXd matrix)
420 for (
int i = 0; i < matrix.cols() - 1; i++) {
421 for (
int j = i + 1; j < matrix.cols(); j++) {
422 if (matrix(rowNumber,i) > matrix(rowNumber,j)){
423 matrix.col(i).swap(matrix.col(j));
432 Eigen::MatrixXd
eraseCol(
int removeIndex, Eigen::MatrixXd positions)
434 positions.block(0 , removeIndex , positions.rows() , positions.cols() - removeIndex - 1) = positions.rightCols(positions.cols() - removeIndex - 1);
435 positions.conservativeResize(Eigen::NoChange, positions.cols() - 1);
439 std::pair<Eigen::MatrixXd::Index, double>
dsearch(Eigen::Vector3d p, Eigen::MatrixXd positions)
441 Eigen::MatrixXd::Index index;
443 (positions.colwise() - p).colwise().squaredNorm().minCoeff(&index);
444 double d = (positions.col(index) - p).norm();
446 return std::make_pair(index , d);
449 std::pair<std::vector<Eigen::MatrixXd::Index>, Eigen::VectorXd >
dsearchn(Eigen::MatrixXd p1, Eigen::MatrixXd p2)
451 Eigen::MatrixXd::Index index;
452 std::vector<Eigen::MatrixXd::Index> indexVector;
453 Eigen::VectorXd D(p1.cols());
454 for (
int i = 0; i < p1.cols(); i++)
457 (p2.colwise() - p1.col(i)).colwise().squaredNorm().minCoeff(&index);
458 D(i) = (p2.col(index) - p1.col(i)).norm();
459 indexVector.push_back(index);
461 return std::make_pair(indexVector , D);
467 Eigen::MatrixXd thisPosition(3,1);
468 std::vector<Eigen::MatrixXd> branchPositionsVector;
469 thisPosition = positionsNotUsed.col(startIndex);
470 branchPositionsVector.push_back(thisPosition);
471 positionsNotUsed =
eraseCol(startIndex,positionsNotUsed);;
473 while (positionsNotUsed.cols() > 0)
475 std::pair<Eigen::MatrixXd::Index, double > minDistance =
dsearch(thisPosition, positionsNotUsed);
476 Eigen::MatrixXd::Index index = minDistance.first;
477 double d = minDistance.second;
481 thisPosition = positionsNotUsed.col(index);
482 positionsNotUsed =
eraseCol(index,positionsNotUsed);
484 branchPositionsVector.push_back(thisPosition);
488 Eigen::MatrixXd branchPositions(3,branchPositionsVector.size());
490 for (
int j = 0; j < branchPositionsVector.size(); j++)
492 branchPositions.block(0,j,3,1) = branchPositionsVector[j];
495 return std::make_pair(branchPositions, positionsNotUsed);
Vector3D ceil(const Vector3D &a)
std::pair< Eigen::MatrixXd, Eigen::MatrixXd > findConnectedPointsInCT(int startIndex, Eigen::MatrixXd positionsNotUsed)
void interpolateBranchPositions(int interpolationFactor)
vtkSmartPointer< class vtkCellArray > vtkCellArrayPtr
boost::shared_ptr< class BranchList > BranchListPtr
BranchListPtr removePositionsForLocalRegistration(Eigen::MatrixXd trackingPositions, double maxDistance)
vtkSmartPointer< vtkPoints > vtkPointsPtr
void addBranch(BranchPtr b)
boost::shared_ptr< class Branch > BranchPtr
vtkSmartPointer< class vtkCardinalSpline > vtkCardinalSplinePtr
vtkSmartPointer< class vtkCardinalSpline > vtkCardinalSplinePtr
vtkPolyDataPtr createVtkPolyDataFromBranches(bool fullyConnected=false, bool straightBranches=false) const
BranchList::createVtkPolyDataFromBranches Return a VtkPolyData object created from the branches in th...
std::pair< Eigen::MatrixXd::Index, double > dsearch(Eigen::Vector3d p, Eigen::MatrixXd positions)
void calculateOrientations()
void smoothBranchPositions(int controlPointDistance)
std::vector< BranchPtr > getBranches()
void deleteBranch(BranchPtr b)
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
void findBranchesInCenterline(Eigen::MatrixXd positions_r)
class org_custusx_registration_method_bronchoscopy_EXPORT Branch
std::pair< std::vector< Eigen::MatrixXd::Index >, Eigen::VectorXd > dsearchn(Eigen::MatrixXd p1, Eigen::MatrixXd p2)
Eigen::MatrixXd eraseCol(int removeIndex, Eigen::MatrixXd positions)
void selectGenerations(int maxGeneration)
Eigen::MatrixXd sortMatrix(int rowNumber, Eigen::MatrixXd matrix)
void smoothOrientations()
std::vector< BranchPtr > branchVector
Namespace for all CustusX production code.