4 #include <vtkPolyData.h>
8 #include <boost/math/special_functions/fpclassify.hpp>
16 isPreviousProjectedPointSet(false),
19 mUseAdvancedCenterlineProjection(false)
24 isPreviousProjectedPointSet(false),
26 mUseAdvancedCenterlineProjection(false)
37 mRunFromWidget = runFromWidget;
42 mUseAdvancedCenterlineProjection = useAdvancedCenterlineProjection;
48 "Set max distance to centerline in mm", 30,
DoubleRange(1, 100, 1), 0,
55 return mMaxDistanceToCenterline;
60 if (mRunFromWidget && mMaxDistanceToCenterline->getValue())
61 mMaxDistanceToCenterlineValue = mMaxDistanceToCenterline->getValue();
63 return mMaxDistanceToCenterlineValue;
69 "Set max search distance along centerline in mm", 20,
DoubleRange(1, 100, 1), 0,
76 return mMaxSearchDistance;
81 if (mRunFromWidget && mMaxSearchDistance->getValue())
82 mMaxSearchDistanceValue = mMaxSearchDistance->getValue();
84 return mMaxSearchDistanceValue;
90 "Weighting of position and orientation in projection (high alpha is giving orientations high weight).", 1.0,
DoubleRange(0, 10, 0.1), 1, root);
101 if (mRunFromWidget && mAlpha->getValue())
102 mAlphaValue = mAlpha->getValue();
110 int N = centerline->GetNumberOfPoints();
111 Eigen::MatrixXd CLpoints(3,N);
112 for(vtkIdType i = 0; i < N; i++)
115 centerline->GetPoint(i,p);
116 Eigen::Vector3d position;
117 position(0) = p[0]; position(1) = p[1]; position(2) = p[2];
118 CLpoints.block(0 , i , 3 , 1) = rMd.coord(position);
127 mBranchListPtr->deleteAllBranches();
131 mBranchListPtr->findBranchesInCenterline(mCLpoints);
134 mBranchListPtr->smoothOrientations();
136 std::cout <<
"Number of branches in CT centerline: " << mBranchListPtr->getBranches().size() << std::endl;
146 mBranchListPtr = branchList;
152 mMaxDistanceToCenterlineValue = maxDistance;
158 mMaxSearchDistanceValue = maxDistance;
170 Eigen::VectorXd toolPos = rMt.matrix().topRightCorner(3 , 1);
171 Eigen::MatrixXd::Index index;
174 Eigen::VectorXd P(mCLpoints.cols());
175 for (
int i = 0; i < mCLpoints.cols(); i++)
177 double p0 = ( mCLpoints(0,i) - toolPos(0) );
178 double p1 = ( mCLpoints(1,i) - toolPos(1) );
179 double p2 = ( mCLpoints(2,i) - toolPos(2) );
181 P(i) = sqrt( p0*p0 + p1*p1 + p2*p2 );
185 if (P.minCoeff() < maxDistance)
187 new_rMt.matrix().topRightCorner(3 , 1) = mCLpoints.col(index);
197 Eigen::VectorXd toolPos = rMt.matrix().topRightCorner(3 , 1);
200 double minDistance = 100000;
201 int minDistancePositionIndex;
203 std::vector<BranchPtr> branches = mBranchListPtr->getBranches();
204 for (
int i = 0; i < branches.size(); i++)
206 Eigen::MatrixXd positions = branches[i]->getPositions();
207 for (
int j = 0; j < positions.cols(); j++)
213 minDistanceBranch = branches[i];
214 minDistancePositionIndex = j;
219 if (minDistance < maxDistance)
221 Eigen::MatrixXd positions = minDistanceBranch->getPositions();
222 new_rMt.matrix().topRightCorner(3 , 1) = positions.col(minDistancePositionIndex);
223 mProjectedBranchPtr = minDistanceBranch;
224 mProjectedIndex = minDistancePositionIndex;
225 isPreviousProjectedPointSet =
true;
230 isPreviousProjectedPointSet =
false;
240 Eigen::VectorXd toolPos = rMt.matrix().topRightCorner(3 , 1);
241 Eigen::VectorXd toolOrientation = rMt.matrix().block(0 , 2 , 3 , 1);
244 double minDistance = 100000;
245 int minDistancePositionIndex;
247 for (
int i = 0; i < mSearchBranchPtrVector.size(); i++)
249 Eigen::MatrixXd positions = mSearchBranchPtrVector[i]->getPositions();
250 Eigen::MatrixXd orientations = mSearchBranchPtrVector[i]->getOrientations();
254 double D =
findDistanceWithOrientation(positions.col(mSearchIndexVector[i]), toolPos, orientations.col(mSearchIndexVector[i]), toolOrientation, alpha);
258 minDistanceBranch = mSearchBranchPtrVector[i];
259 minDistancePositionIndex = mSearchIndexVector[i];
262 if (minDistance < maxDistance)
264 Eigen::MatrixXd positions = minDistanceBranch->getPositions();
265 new_rMt.matrix().topRightCorner(3 , 1) = positions.col(minDistancePositionIndex);
266 mProjectedBranchPtr = minDistanceBranch;
267 mProjectedIndex = minDistancePositionIndex;
268 isPreviousProjectedPointSet =
true;
273 isPreviousProjectedPointSet =
false;
283 mSearchBranchPtrVector.clear();
284 mSearchIndexVector.clear();
285 mSearchBranchPtrVector.push_back(mProjectedBranchPtr);
286 mSearchIndexVector.push_back(mProjectedIndex);
287 double currentSearchDistance = 0;
289 Eigen::MatrixXd positions = mProjectedBranchPtr->getPositions();
290 if (mProjectedIndex < positions.cols() - 1)
292 currentSearchDistance =
findDistance( positions.col(mProjectedIndex), positions.col(mProjectedIndex+1) );
293 searchBranchDown(mProjectedBranchPtr, mProjectedIndex + 1, currentSearchDistance, maxSearchDistance);
295 if (mProjectedIndex > 0)
297 currentSearchDistance =
findDistance( positions.col(mProjectedIndex), positions.col(mProjectedIndex-1) );
298 searchBranchUp(mProjectedBranchPtr, mProjectedIndex - 1, currentSearchDistance, maxSearchDistance);
305 Eigen::MatrixXd positions = searchBranchPtr->getPositions();
306 mSearchBranchPtrVector.push_back(searchBranchPtr);
307 mSearchIndexVector.push_back(startIndex);
308 for (
int i = startIndex-1; i>=0; i--)
310 currentSearchDistance = currentSearchDistance +
findDistance( positions.col(i+1), positions.col(i) );
311 if (currentSearchDistance < maxSearchDistance)
313 mSearchBranchPtrVector.push_back(searchBranchPtr);
314 mSearchIndexVector.push_back(i);
319 BranchPtr parentBranchPtr = searchBranchPtr->getParentBranch();
323 std::vector<BranchPtr> childBranches = parentBranchPtr->getChildBranches();
324 searchBranchUp(parentBranchPtr, parentBranchPtr->getPositions().cols()-1, currentSearchDistance, maxSearchDistance);
325 for (
int i = 0; i < childBranches.size(); i++)
326 if (childBranches[i] != searchBranchPtr)
327 searchBranchDown(childBranches[i], 0, currentSearchDistance, maxSearchDistance);
333 Eigen::MatrixXd positions = searchBranchPtr->getPositions();
334 mSearchBranchPtrVector.push_back(searchBranchPtr);
335 mSearchIndexVector.push_back(startIndex);
336 for (
int i = startIndex+1; i<positions.cols(); i++)
338 currentSearchDistance = currentSearchDistance +
findDistance( positions.col(i), positions.col(i-1) );
339 if (currentSearchDistance < maxSearchDistance)
341 mSearchBranchPtrVector.push_back(searchBranchPtr);
342 mSearchIndexVector.push_back(i);
347 std::vector<BranchPtr> childBranches = searchBranchPtr->getChildBranches();
348 for (
int i = 0; i < childBranches.size(); i++)
349 searchBranchDown(childBranches[i], 0,currentSearchDistance,maxSearchDistance);
356 if (isPreviousProjectedPointSet)
369 return mUseAdvancedCenterlineProjection;
374 double d0 = p1(0) - p2(0);
375 double d1 = p1(1) - p2(1);
376 double d2 = p1(2) - p2(2);
378 double D = sqrt( d0*d0 + d1*d1 + d2*d2 );
383 double findDistanceWithOrientation(Eigen::VectorXd position1, Eigen::VectorXd position2, Eigen::VectorXd orientation1, Eigen::VectorXd orientation2,
double alpha)
385 double d0 = position1(0) - position2(0);
386 double d1 = position1(1) - position2(1);
387 double d2 = position1(2) - position2(2);
388 double o0 = fmod( orientation2(0) - orientation1(0) , 2 );
389 double o1 = fmod( orientation2(1) - orientation1(1) , 2 );
390 double o2 = fmod( orientation2(2) - orientation1(2) , 2 );
392 double P = sqrt( d0*d0 + d1*d1 + d2*d2 );
393 double O = sqrt( o0*o0 + o1*o1 + o2*o2 );
395 if (boost::math::isnan( O ) )
398 if ( (o0>2) || (o1>2) || (o2>2) )
399 std::cout <<
"Warning in bronchoscopyRegistration.cpp: Error on oriantation calculation in dsearch2n. Orientation > 2." << std::endl;
401 double D = P + alpha * O;
408 Eigen::MatrixXd branchPositions = branch->getPositions();
409 int numberOfPositions = branchPositions.cols();
428 lookBackIndex = std::max(0 , index-20);
429 lookBackPosition = branchPositions.col(lookBackIndex);
430 int lookForwardIndex = std::min(numberOfPositions-1 , index+20);
431 Vector3D lookForwardPosition = branchPositions.col(lookForwardIndex);
433 Vector3D viewDirection = (lookForwardPosition - lookBackPosition).normalized();
435 prMt.matrix().col(2).head(3) = viewDirection;