36 #include <vtkPolyData.h>
37 #include "vtkCardinalSpline.h"
58 mBranches.push_back(b);
63 for(
int i = 0; i < mBranches.size(); i++ )
65 if (b == mBranches[i])
67 mBranches.erase(mBranches.begin() + i);
85 std::vector<int> branchNumbersToBeDeleted;
86 for(
int i = 0; i < mBranches.size(); i++ )
88 int generationCounter = 1;
90 while (currentBranch->getParentBranch()){
92 currentBranch = currentBranch->getParentBranch();
93 if (generationCounter > maxGeneration)
95 branchNumbersToBeDeleted.push_back(i);
102 for (
int i = branchNumbersToBeDeleted.size() - 1; i >= 0; i-- )
109 for (
int i = 0; i < mBranches.size(); i++)
111 Eigen::MatrixXd positions = mBranches[i]->getPositions();
112 Eigen::MatrixXd diff = positions.rightCols(positions.cols() - 1) - positions.leftCols(positions.cols() - 1);
113 Eigen::MatrixXd orientations(positions.rows(),positions.cols());
114 orientations.leftCols(orientations.cols() - 1) = diff / diff.norm();
115 orientations.rightCols(1) = orientations.col(orientations.cols() - 1);
116 mBranches[i]->setOrientations(orientations);
122 for (
int i = 0; i < mBranches.size(); i++)
124 Eigen::MatrixXd orientations = mBranches[i]->getOrientations();
125 Eigen::MatrixXd newOrientations(orientations.rows(),orientations.cols());
126 int numberOfColumns = orientations.cols();
127 for (
int j = 0; j < numberOfColumns; j++)
129 newOrientations.col(j) = orientations.block(0,std::max(j-2,0),orientations.rows(),std::min(5,numberOfColumns-j)).rowwise().mean();
130 newOrientations.col(j) = newOrientations.col(j) / newOrientations.col(j).norm();
132 mBranches[i]->setOrientations(newOrientations);
138 for (
int i = 0; i < mBranches.size(); i++)
140 Eigen::MatrixXd positions = mBranches[i]->getPositions();
141 std::vector<Eigen::Vector3d> interpolatedPositions;
142 for (
int j = 0; j < positions.cols()-1; j++)
144 for (
int k = 0; k < interpolationFactor; k++){
145 Eigen::Vector3d interpolationPoint;
146 interpolationPoint[0] = (positions(0,j)*(interpolationFactor-k) + positions(0,j+1)*(k) ) / interpolationFactor;
147 interpolationPoint[1] = (positions(1,j)*(interpolationFactor-k) + positions(1,j+1)*(k) ) / interpolationFactor;
148 interpolationPoint[2] = (positions(2,j)*(interpolationFactor-k) + positions(2,j+1)*(k) ) / interpolationFactor;
149 interpolatedPositions.push_back(interpolationPoint);
152 Eigen::MatrixXd interpolationResult(3 , interpolatedPositions.size());
153 for (
int j = 0; j < interpolatedPositions.size(); j++)
155 interpolationResult(0,j) = interpolatedPositions[j](0);
156 interpolationResult(1,j) = interpolatedPositions[j](1);
157 interpolationResult(2,j) = interpolatedPositions[j](2);
159 mBranches[i]->setPositions(interpolationResult);
166 for (
int i = 0; i < mBranches.size(); i++)
168 Eigen::MatrixXd positions = mBranches[i]->getPositions();
169 int numberOfInputPoints = positions.cols();
170 int controlPointFactor = 10;
171 int numberOfControlPoints = numberOfInputPoints / controlPointFactor;
177 if (numberOfControlPoints >= 2)
180 for(
int j=0; j<numberOfControlPoints; j++)
182 int indexP = (j*numberOfInputPoints)/numberOfControlPoints;
184 splineX->AddPoint(indexP,positions(0,indexP));
185 splineY->AddPoint(indexP,positions(1,indexP));
186 splineZ->AddPoint(indexP,positions(2,indexP));
189 splineX->AddPoint(numberOfInputPoints-1,positions(0,numberOfInputPoints-1));
190 splineY->AddPoint(numberOfInputPoints-1,positions(1,numberOfInputPoints-1));
191 splineZ->AddPoint(numberOfInputPoints-1,positions(2,numberOfInputPoints-1));
194 Eigen::MatrixXd smoothingResult(3 , numberOfInputPoints);
195 for(
int j=0; j<numberOfInputPoints; j++)
197 double splineParameter = j;
198 smoothingResult(0,j) = splineX->Evaluate(splineParameter);
199 smoothingResult(1,j) = splineY->Evaluate(splineParameter);
200 smoothingResult(2,j) = splineZ->Evaluate(splineParameter);
202 mBranches[i]->setPositions(smoothingResult);
210 Eigen::MatrixXd positionsNotUsed = positions;
215 Eigen::MatrixXd::Index startIndex;
217 while (positionsNotUsed.cols() > 0)
219 if (!mBranches.empty())
221 double minDistance = 1000;
222 for (
int i = 0; i < mBranches.size(); i++)
224 std::pair<std::vector<Eigen::MatrixXd::Index>, Eigen::VectorXd> distances;
225 distances =
dsearchn(positionsNotUsed, mBranches[i]->getPositions());
226 double d = distances.second.minCoeff(&index);
230 branchToSplit = mBranches[i];
236 std::pair<Eigen::MatrixXd::Index, double> dsearchResult =
dsearch(positionsNotUsed.col(startIndex) , branchToSplit->getPositions());
237 splitIndex = dsearchResult.first;
240 startIndex = positionsNotUsed.cols() - 1;
242 std::pair<Eigen::MatrixXd,Eigen::MatrixXd > connectedPointsResult =
findConnectedPointsInCT(startIndex , positionsNotUsed);
243 Eigen::MatrixXd branchPositions = connectedPointsResult.first;
244 positionsNotUsed = connectedPointsResult.second;
246 if (branchPositions.cols() >= 5)
249 newBranch->setPositions(branchPositions);
250 mBranches.push_back(newBranch);
252 if (mBranches.size() > 1)
254 if ((splitIndex + 1 >= 5) && (branchToSplit->getPositions().cols() - splitIndex - 1 >= 5))
260 Eigen::MatrixXd branchToSplitPositions = branchToSplit->getPositions();
261 newBranchFromSplit->setPositions(branchToSplitPositions.rightCols(branchToSplitPositions.cols() - splitIndex - 1));
262 branchToSplit->setPositions(branchToSplitPositions.leftCols(splitIndex + 1));
263 mBranches.push_back(newBranchFromSplit);
264 newBranchFromSplit->setParentBranch(branchToSplit);
265 newBranch->setParentBranch(branchToSplit);
266 newBranchFromSplit->setChildBranches(branchToSplit->getChildBranches());
267 branchVector branchToSplitChildren = branchToSplit->getChildBranches();
268 for (
int i = 0; i < branchToSplitChildren.size(); i++)
269 branchToSplitChildren[i]->setParentBranch(newBranchFromSplit);
270 branchToSplit->deleteChildBranches();
271 branchToSplit->addChildBranch(newBranchFromSplit);
272 branchToSplit->addChildBranch(newBranch);
274 else if (splitIndex + 1 < 5)
279 newBranch->setParentBranch(branchToSplit->getParentBranch());
280 branchToSplit->getParentBranch()->addChildBranch(newBranch);
282 else if (branchToSplit->getPositions().cols() - splitIndex - 1 < 5)
286 newBranch->setParentBranch(branchToSplit);
287 branchToSplit->addChildBranch(newBranch);
301 for (
int i = 0; i < mBranches.size(); i++)
304 b->setPositions(mBranches[i]->getPositions());
305 b->setOrientations(mBranches[i]->getOrientations());
306 retval->addBranch(b);
309 std::vector<BranchPtr> branches = retval->getBranches();
310 Eigen::MatrixXd positions;
311 Eigen::MatrixXd orientations;
312 for (
int i = 0; i < branches.size(); i++)
314 positions = branches[i]->getPositions();
315 orientations = branches[i]->getOrientations();
316 std::pair<std::vector<Eigen::MatrixXd::Index>, Eigen::VectorXd> distanceData;
317 distanceData =
dsearchn(positions, trackingPositions);
318 Eigen::VectorXd distance = distanceData.second;
319 for (
int j = positions.cols() - 1; j >= 0; j--)
321 if (distance(j) > maxDistance)
324 orientations =
eraseCol(j, orientations);
327 branches[i]->setPositions(positions);
328 branches[i]->setOrientations(orientations);
333 Eigen::MatrixXd
sortMatrix(
int rowNumber, Eigen::MatrixXd matrix)
335 for (
int i = 0; i < matrix.cols() - 1; i++) {
336 for (
int j = i + 1; j < matrix.cols(); j++) {
337 if (matrix(rowNumber,i) > matrix(rowNumber,j)){
338 matrix.col(i).swap(matrix.col(j));
347 Eigen::MatrixXd
eraseCol(
int removeIndex, Eigen::MatrixXd positions)
349 positions.block(0 , removeIndex , positions.rows() , positions.cols() - removeIndex - 1) = positions.rightCols(positions.cols() - removeIndex - 1);
350 positions.conservativeResize(Eigen::NoChange, positions.cols() - 1);
354 std::pair<Eigen::MatrixXd::Index, double>
dsearch(Eigen::Vector3d p, Eigen::MatrixXd positions)
356 Eigen::MatrixXd::Index index;
358 (positions.colwise() - p).colwise().squaredNorm().minCoeff(&index);
359 double d = (positions.col(index) - p).norm();
361 return std::make_pair(index , d);
364 std::pair<std::vector<Eigen::MatrixXd::Index>, Eigen::VectorXd >
dsearchn(Eigen::MatrixXd p1, Eigen::MatrixXd p2)
366 Eigen::MatrixXd::Index index;
367 std::vector<Eigen::MatrixXd::Index> indexVector;
368 Eigen::VectorXd D(p1.cols());
369 for (
int i = 0; i < p1.cols(); i++)
372 (p2.colwise() - p1.col(i)).colwise().squaredNorm().minCoeff(&index);
373 D(i) = (p2.col(index) - p1.col(i)).norm();
374 indexVector.push_back(index);
376 return std::make_pair(indexVector , D);
382 Eigen::MatrixXd thisPosition(3,1);
383 std::vector<Eigen::MatrixXd> branchPositionsVector;
384 thisPosition = positionsNotUsed.col(startIndex);
385 branchPositionsVector.push_back(thisPosition);
386 positionsNotUsed =
eraseCol(startIndex,positionsNotUsed);;
388 while (positionsNotUsed.cols() > 0)
390 std::pair<Eigen::MatrixXd::Index, double > minDistance =
dsearch(thisPosition, positionsNotUsed);
391 Eigen::MatrixXd::Index index = minDistance.first;
392 double d = minDistance.second;
396 thisPosition = positionsNotUsed.col(index);
397 positionsNotUsed =
eraseCol(index,positionsNotUsed);
399 branchPositionsVector.push_back(thisPosition);
403 Eigen::MatrixXd branchPositions(3,branchPositionsVector.size());
405 for (
int j = 0; j < branchPositionsVector.size(); j++)
407 branchPositions.block(0,j,3,1) = branchPositionsVector[j];
410 return std::make_pair(branchPositions, positionsNotUsed);
std::pair< Eigen::MatrixXd, Eigen::MatrixXd > findConnectedPointsInCT(int startIndex, Eigen::MatrixXd positionsNotUsed)
void interpolateBranchPositions(int interpolationFactor)
void smoothBranchPositions()
boost::shared_ptr< class BranchList > BranchListPtr
BranchListPtr removePositionsForLocalRegistration(Eigen::MatrixXd trackingPositions, double maxDistance)
void findBranchesInCenterline(Eigen::MatrixXd positions)
void addBranch(BranchPtr b)
boost::shared_ptr< class Branch > BranchPtr
vtkSmartPointer< class vtkCardinalSpline > vtkCardinalSplinePtr
std::pair< Eigen::MatrixXd::Index, double > dsearch(Eigen::Vector3d p, Eigen::MatrixXd positions)
void calculateOrientations()
vtkSmartPointer< class vtkCardinalSpline > vtkCardinalSplinePtr
std::vector< BranchPtr > getBranches()
void deleteBranch(BranchPtr b)
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