-ExtractStation_8_LR_Limits_old2()
-{
-
- //--------------------------------------------------------------------
- StartNewStep("[Station8] Left and Right limits arround esophagus (below Carina)");
-
- // Estract slices for current support for slice by slice processing
- std::vector<typename MaskSliceType::Pointer> slices;
- clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices);
-
- // Dilate the Esophagus to consider a margins around
- MaskImagePointType radiusInMM = GetEsophagusDiltationForAnt();
- m_Esophagus = clitk::Dilate<MaskImageType>(m_Esophagus,
- radiusInMM,
- GetBackgroundValue(),
- GetForegroundValue(), true);
-
- // Remove what is outside the mediastinum in this enlarged Esophagus -> it allows to select
- // 'better' extrema points (not too post).
- MaskImagePointer Lungs = GetAFDB()->template GetImage<MaskImageType>("Lungs");
- clitk::AndNot<MaskImageType>(m_Esophagus, Lungs, GetBackgroundValue());
- GetAFDB()->template ReleaseImage<MaskImageType>("Lungs");
-
- // Estract slices of Esophagus (resize like support before to have the same set of slices)
- MaskImagePointer EsophagusForSlice = clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue());
-
- std::vector<typename MaskSliceType::Pointer> eso_slices;
- clitk::ExtractSlices<MaskImageType>(EsophagusForSlice, 2, eso_slices);
-
- // Estract slices of Vertebral (resize like support before to have the same set of slices)
- MaskImagePointer VertebralBody = GetAFDB()->template GetImage<MaskImageType>("VertebralBody");
- VertebralBody = clitk::ResizeImageLike<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
- std::vector<typename MaskSliceType::Pointer> vert_slices;
- clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, vert_slices);
-
- // Estract slices of Aorta (resize like support before to have the same set of slices)
- MaskImagePointer Aorta = GetAFDB()->template GetImage<MaskImageType>("Aorta");
- Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, m_Working_Support, GetBackgroundValue());
- std::vector<typename MaskSliceType::Pointer> aorta_slices;
- clitk::ExtractSlices<MaskImageType>(Aorta, 2, aorta_slices);
-
- // Extract slices of Mediastinum (resize like support before to have the same set of slices)
- m_Mediastinum = GetAFDB()->template GetImage<MaskImageType>("Mediastinum");
- m_Mediastinum = clitk::ResizeImageLike<MaskImageType>(m_Mediastinum, m_Working_Support, GetBackgroundValue());
- std::vector<typename MaskSliceType::Pointer> mediast_slices;
- clitk::ExtractSlices<MaskImageType>(m_Mediastinum, 2, mediast_slices);
-
- // List of points
- std::vector<MaskImagePointType> p_RightMostAnt;
- std::vector<MaskImagePointType> p_RightMostPost;
- std::vector<MaskImagePointType> p_LeftMostAnt;
- std::vector<MaskImagePointType> p_LeftMostPost;
- std::vector<MaskImagePointType> p_AllPoints;
- std::vector<MaskImagePointType> p_LeftAorta;
- std::vector<MaskImagePointType> p_LeftEso;
-
- /*
- In the following, we search for the LeftRight limits. We search
- for the most Right points in Esophagus and in VertebralBody and
- consider a line between those to most right points. All points in
- the support which are most right to this line are discarded. Same
- for the left part. The underlying assumption is that the support
- is concave between Eso/VertebralBody. Esophagus is a bit
- dilatated. On VertebralBody we go right (or left) until we reach
- the lung (but no more 20 mm).
- */
-
- // Loop slices
- MaskImagePointType p;
- MaskImagePointType pp;
- for(uint i=0; i<slices.size() ; i++) {
- // Declare all needed points (sp = slice point)
- typename MaskSliceType::PointType sp_maxRight_Eso;
- typename MaskSliceType::PointType sp_maxRight_Aorta;
- typename MaskSliceType::PointType sp_maxRight_Vertebra;
- typename MaskSliceType::PointType sp_maxLeft_Eso;
- typename MaskSliceType::PointType sp_maxLeft_Aorta;
- typename MaskSliceType::PointType sp_maxLeft_Vertebra;
-
- // Right is at left on screen, coordinate decrease
- // Left is at right on screen, coordinate increase
-
- // Find limit of Vertebral -> only at most Post part of current
- // slice support. First found most ant point in VertebralBody
- typedef MaskSliceType SliceType;
- typename SliceType::PointType p_slice_ant;
- bool found = clitk::FindExtremaPointInAGivenDirection<SliceType>(vert_slices[i], GetBackgroundValue(), 1, true, p_slice_ant);
- if (!found) {
- // It should not happen ! But sometimes, a contour is missing or
- // the VertebralBody is not delineated enough inferiorly ... in
- // those cases, we consider the first found slice.
- std::cerr << "No foreground pixels in this VertebralBody slices !?? I try with the previous/next slice" << std::endl;
- int j=i++;
- bool found = false;
- while (!found) {
- found = clitk::FindExtremaPointInAGivenDirection<SliceType>(vert_slices[j], GetBackgroundValue(), 1, true, p_slice_ant);
- //clitkExceptionMacro("No foreground pixels in this VertebralBody slices ??");
- j++;
- }
- }
- p_slice_ant[1] += GetDistanceMaxToAnteriorPartOfTheSpine(); // Consider offset
-
- // The, find most Right and Left points on that AP position
- typename SliceType::IndexType indexR;
- typename SliceType::IndexType indexL;
- vert_slices[i]->TransformPhysicalPointToIndex(p_slice_ant, indexR);
- indexL = indexR;
- // Check that is inside the mask
- indexR[1] = std::min(indexR[1], (long)vert_slices[i]->GetLargestPossibleRegion().GetSize()[1]-1);
- indexL[1] = indexR[1];
- while (vert_slices[i]->GetPixel(indexR) != GetBackgroundValue()) {
- indexR[0] --; // Go to the right
- }
- while (vert_slices[i]->GetPixel(indexL) != GetBackgroundValue()) {
- indexL[0] ++; // Go to the left
- }
- vert_slices[i]->TransformIndexToPhysicalPoint(indexR, sp_maxRight_Vertebra);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, VertebralBody, i, p);
- p_AllPoints.push_back(p);
- vert_slices[i]->TransformIndexToPhysicalPoint(indexL, sp_maxLeft_Vertebra);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, VertebralBody, i, p);
- p_AllPoints.push_back(p);
-
- // Find last point out of the mediastinum on this line, Right :
- mediast_slices[i]->TransformPhysicalPointToIndex(sp_maxRight_Vertebra, indexR);
- double distance = 0.0;
- while (mediast_slices[i]->GetPixel(indexR) != GetBackgroundValue()) {
- indexR[0] --;
- distance += mediast_slices[i]->GetSpacing()[0];
- }
- if (distance < 30) { // Ok in this case, we found limit with lung
- mediast_slices[i]->TransformIndexToPhysicalPoint(indexR, sp_maxRight_Vertebra);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, m_Mediastinum, i, p);
- }
- else { // in that case, we are probably below the diaphragm, so we
- // add aribtrarly few mm
- sp_maxRight_Vertebra[0] -= 2; // Leave 2 mm around the VertebralBody
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, m_Mediastinum, i, p);
- }
- p_RightMostPost.push_back(p);
- p_AllPoints.push_back(p);
-
- // Find last point out of the mediastinum on this line, Left :
- mediast_slices[i]->TransformPhysicalPointToIndex(sp_maxLeft_Vertebra, indexL);
- distance = 0.0;
- while (mediast_slices[i]->GetPixel(indexL) != GetBackgroundValue()) {
- indexL[0] ++;
- distance += mediast_slices[i]->GetSpacing()[0];
- }
- if (distance < 30) { // Ok in this case, we found limit with lung
- mediast_slices[i]->TransformIndexToPhysicalPoint(indexL, sp_maxLeft_Vertebra);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, m_Mediastinum, i, p);
- }
- else { // in that case, we are probably below the diaphragm, so we
- // add aribtrarly few mm
- sp_maxLeft_Vertebra[0] += 2; // Leave 2 mm around the VertebralBody
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, m_Mediastinum, i, p);
- }
- p_LeftMostPost.push_back(p);
- p_AllPoints.push_back(p);
-
- // Find Eso slice centroid and do not consider what is post to
- // this centroid.
- std::vector<typename MaskSliceType::PointType> c;
- clitk::ComputeCentroids<MaskSliceType>(eso_slices[i], GetBackgroundValue(), c);
- if (c.size() >1) {
- eso_slices[i] =
- clitk::CropImageAbove<MaskSliceType>(eso_slices[i], 1, c[1][1], false, GetBackgroundValue());
- eso_slices[i] =
- clitk::ResizeImageLike<MaskSliceType>(eso_slices[i], aorta_slices[i], GetBackgroundValue());
- // writeImage<MaskSliceType>(eso_slices[i], "eso-slice-"+toString(i)+".mhd");
- }
-
- // Find right limit of Esophagus and Aorta
- bool f =
- clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(),
- 0, true, sp_maxRight_Eso);
- f = f &&
- clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(aorta_slices[i], GetBackgroundValue(),
- 0, true, sp_maxRight_Aorta);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Eso, EsophagusForSlice, i, p);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Aorta, Aorta, i, pp);
- pp[0] -= 2; // Add a margin of 2 mm to include the Aorta 'wall'
- p_AllPoints.push_back(p);
- if (f) {
- p_AllPoints.push_back(pp);
- MaskImagePointType A = p_RightMostPost.back();
- MaskImagePointType B = p;
- MaskImagePointType C = pp;
- double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
- if (s>0) p_RightMostAnt.push_back(p);
- else p_RightMostAnt.push_back(pp);
- }
- else { // No more Esophagus in this slice : do nothing
- // p_RightMostAnt.push_back(p);
- p_RightMostPost.pop_back();
- }
-
- // --------------------------------------------------------------------------
- // Find the limit on the Left: most left point between Eso and
- // Eso. (Left is left on screen, coordinate increase)
-
- // Find left limit of Esophagus
- clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(), 0, false, sp_maxLeft_Eso);
- f = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(aorta_slices[i], GetBackgroundValue(), 0, false, sp_maxLeft_Aorta);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Eso, EsophagusForSlice, i, p);
- clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Aorta, Aorta, i, pp);
- p_AllPoints.push_back(p);
- pp[0] += 2; // Add a margin of 2 mm to include the 'wall'
- if (f) { // not below Aorta
- p_AllPoints.push_back(pp);
- MaskImagePointType A = p_LeftMostPost.back();
- MaskImagePointType B = p;
- MaskImagePointType C = pp;
- double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
- if (s<0) {
- p_LeftMostAnt.push_back(p); // Insert point most at Left, Eso
- }
- else {
- // in this case -> two lines !
- p_LeftMostAnt.push_back(pp); // Insert point most at Left, Aorta (Vert to Aorta)
- // but also consider Aorta to Eso
- p_LeftAorta.push_back(pp);
- p_LeftEso.push_back(p);
- }
- }
- else { // No more Esophagus in this slice : do nothing
- p_LeftMostPost.pop_back();
- //p_LeftMostAnt.push_back(p);
- }
- } // End of slice loop
-
- clitk::WriteListOfLandmarks<MaskImageType>(p_AllPoints, "S8-LR-Eso-Vert.txt");
- clitk::WriteListOfLandmarks<MaskImageType>(p_LeftEso, "S8-Left-Eso.txt");
- clitk::WriteListOfLandmarks<MaskImageType>(p_LeftAorta, "S8-Left-Aorta.txt");
-
- // Now uses these points to limit, slice by slice
- // Line is mainly vertical, so mainDirection=0
- clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
- p_RightMostAnt, p_RightMostPost,
- GetBackgroundValue(), 0, 10);
- clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
- p_LeftMostAnt, p_LeftMostPost,
- GetBackgroundValue(), 0, -10);
- clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support,
- p_LeftEso,p_LeftAorta,
- GetBackgroundValue(), 0, -10);
- // END
- StopCurrentStep<MaskImageType>(m_Working_Support);
- m_ListOfStations["8"] = m_Working_Support;
- return;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_Limits()