- MaskImagePointer OriginOfRightMiddleLobeBronchus =
- GetAFDB()->template GetImage<MaskImageType>("OriginOfRightMiddleLobeBronchus");
- clitk::PrintMemory(GetVerboseMemoryFlag(), "after read OriginOfRightMiddleLobeBronchus");
- std::vector<MaskImagePointType> centroids;
- clitk::ComputeCentroids<MaskImageType>(OriginOfRightMiddleLobeBronchus, GetBackgroundValue(), centroids);
- DD(centroids.size());
- DD(centroids[0]); // BG
- DD(centroids[1]);
- m_OriginOfRightMiddleLobeBronchusZ = centroids[1][2];
- DD(m_OriginOfRightMiddleLobeBronchusZ);
- // add one slice to include carina ?
- m_OriginOfRightMiddleLobeBronchusZ += LeftBronchus->GetSpacing()[2];
- DD(m_OriginOfRightMiddleLobeBronchusZ);
- DD(OriginOfRightMiddleLobeBronchus->GetReferenceCount());
- // We dont need Carina structure from now
- OriginOfRightMiddleLobeBronchus->Delete();
- clitk::PrintMemory(GetVerboseMemoryFlag(), "after delete OriginOfRightMiddleLobeBronchus");
-
-
- LeftBronchus =
- clitk::CropImageBelow<MaskImageType>(LeftBronchus, 2,
- m_OriginOfRightMiddleLobeBronchusZ,
- true, // AutoCrop
- GetBackgroundValue());
- RightBronchus =
- clitk::CropImageBelow<MaskImageType>(RightBronchus, 2,
- m_OriginOfRightMiddleLobeBronchusZ,
- true, // AutoCrop
- GetBackgroundValue());
-
- // Search for points that are the most left/post/ant and most
- // right/post/ant of the left and right bronchus
- // 15 = not 15 mm more distance than the middle point.
- FindExtremaPointsInBronchus(LeftBronchus, 0, 10, m_RightMostInLeftBronchus,
- m_AntMostInLeftBronchus, m_PostMostInLeftBronchus);
- FindExtremaPointsInBronchus(RightBronchus, 1, 10, m_LeftMostInRightBronchus,
- m_AntMostInRightBronchus, m_PostMostInRightBronchus);
-
- // DEBUG : write the list of points
- ListOfPointsType v;
- v.reserve(m_RightMostInLeftBronchus.size()+m_AntMostInLeftBronchus.size()+
- m_PostMostInLeftBronchus.size());
- v.insert(v.end(), m_RightMostInLeftBronchus.begin(), m_RightMostInLeftBronchus.end() );
- v.insert(v.end(), m_AntMostInLeftBronchus.begin(), m_AntMostInLeftBronchus.end() );
- v.insert(v.end(), m_PostMostInLeftBronchus.begin(), m_PostMostInLeftBronchus.end() );
- clitk::WriteListOfLandmarks<MaskImageType>(v, "LeftBronchusPoints.txt");
-
- v.clear();
- v.reserve(m_LeftMostInRightBronchus.size()+m_AntMostInRightBronchus.size()+
- m_PostMostInRightBronchus.size());
- v.insert(v.end(), m_LeftMostInRightBronchus.begin(), m_LeftMostInRightBronchus.end() );
- v.insert(v.end(), m_AntMostInRightBronchus.begin(), m_AntMostInRightBronchus.end() );
- v.insert(v.end(), m_PostMostInRightBronchus.begin(), m_PostMostInRightBronchus.end() );
- clitk::WriteListOfLandmarks<MaskImageType>(v, "RightBronchusPoints.txt");
-
-
- // Now uses these points to limit, slice by slice
- // http://www.gamedev.net/community/forums/topic.asp?topic_id=542870
- /*
- Assuming the points are (Ax,Ay) (Bx,By) and (Cx,Cy), you need to compute:
- (Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax)
- This will equal zero if the point C is on the line formed by
- points A and B, and will have a different sign depending on the
- side. Which side this is depends on the orientation of your (x,y)
- coordinates, but you can plug test values for A,B and C into this
- formula to determine whether negative values are to the left or to
- the right.
- => to accelerate, start with formula, when change sign -> stop and fill
- */
- typedef itk::ImageSliceIteratorWithIndex<MaskImageType> SliceIteratorType;
- SliceIteratorType siter = SliceIteratorType(m_Working_Support,
- m_Working_Support->GetLargestPossibleRegion());
- siter.SetFirstDirection(0);
- siter.SetSecondDirection(1);
- siter.GoToBegin();
- int i=0;
- MaskImageType::PointType A;
- MaskImageType::PointType B;
- MaskImageType::PointType C;
- while (!siter.IsAtEnd()) {
- // Check that the current slice correspond to the current point
- m_Working_Support->TransformIndexToPhysicalPoint(siter.GetIndex(), C);
- if (C[2] != m_PostMostInLeftBronchus[i][2]) {
- // m_Working_Support start from GOjunction while list of point
- // start at OriginOfRightMiddleLobeBronchusZ, so we must skip some slices.
- }
- else {
- // Define A,B,C points
- A = m_PostMostInLeftBronchus[i];
- B = m_PostMostInRightBronchus[i];
- C = A;
- C[1] += 10; // I know I must keep this point
- double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
- bool isPositive = s<0;
- while (!siter.IsAtEndOfSlice()) {
- while (!siter.IsAtEndOfLine()) {
- // Very slow, I know ... but image should be very small
- m_Working_Support->TransformIndexToPhysicalPoint(siter.GetIndex(), C);
- double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
- if (s == 0) siter.Set(2);
- if (isPositive) {
- if (s > 0) siter.Set(GetBackgroundValue());
- }
- else {
- if (s < 0) siter.Set(GetBackgroundValue());
- }
- ++siter;
+ // Consider slices
+ std::vector<typename MaskSliceType::Pointer> slices;
+ std::vector<typename MaskSliceType::Pointer> slices_vb;
+ clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices);
+ MaskImagePointer VertebralBody =
+ GetAFDB()->template GetImage <MaskImageType>("VertebralBody");
+ VertebralBody = clitk::ResizeImageLike<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
+ clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, slices_vb);
+
+ for(uint i=0; i<slices.size(); i++) {
+ // Decompose in labels
+ slices[i] = Labelize<MaskSliceType>(slices[i], 0, true, 100);
+ // Compute centroids coordinate
+ std::vector<typename MaskSliceType::PointType> centroids;
+ std::vector<typename MaskSliceType::PointType> c;
+ clitk::ComputeCentroids<MaskSliceType>(slices[i], GetBackgroundValue(), centroids);
+ clitk::ComputeCentroids<MaskSliceType>(slices_vb[i], GetBackgroundValue(), c);
+ if ((c.size() > 1) && (centroids.size() > 1)) {
+ // keep the one which is the closer to vertebralbody centroid
+ double distance=1000000;
+ int index=0;
+ for(uint j=1; j<centroids.size(); j++) {
+ double d = centroids[j].EuclideanDistanceTo(c[1]);
+ if (d<distance) {
+ distance = d;
+ index = j;