+//--------------------------------------------------------------------
+template <class ImageType>
+void
+clitk::ExtractMediastinumFilter<ImageType>::
+RemovePostPartOfVertebralBody()
+{
+
+ /*
+ Posteriorly, Station 8 abuts the descending aorta and the anterior
+ aspect of the vertebral body until an imaginary horizontal line
+ running 1 cm posterior to the anterior border of the vertebral
+ body (Fig. 3C).
+
+ => We use this definition for all the mediastinum
+
+ Find most Ant point in VertebralBody. Consider the horizontal line
+ which is 'DistanceMaxToAnteriorPartOfTheVertebralBody' away from
+ the most ant point.
+ */
+
+ // Get VertebralBody mask image
+ MaskImagePointer VertebralBody =
+ this->GetAFDB()->template GetImage <MaskImageType>("VertebralBody");
+
+ // Consider vertebral body slice by slice
+ std::vector<MaskSlicePointer> vertebralSlices;
+ clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, vertebralSlices);
+
+ // For each slice, compute the most anterior point
+ std::map<int, MaskSlicePointType> vertebralAntPositionBySlice;
+ for(uint i=0; i<vertebralSlices.size(); i++) {
+ MaskSlicePointType p;
+ bool found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vertebralSlices[i],
+ this->GetBackgroundValue(),
+ 1, true, p);
+ if (found) {
+ vertebralAntPositionBySlice[i] = p;
+ }
+ else {
+ // 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;
+ // [ Possible alternative -> consider previous limit ]
+ }
+ }
+
+ // Convert 2D points in slice into 3D points
+ std::vector<MaskImagePointType> vertebralAntPositions;
+ clitk::PointsUtils<MaskImageType>::Convert2DMapTo3DList(vertebralAntPositionBySlice,
+ VertebralBody,
+ vertebralAntPositions);
+
+ // DEBUG : write list of points
+ clitk::WriteListOfLandmarks<MaskImageType>(vertebralAntPositions,
+ "VertebralBodyMostAnteriorPoints.txt");
+
+ // Cut support posteriorly 1cm the most anterior point of the
+ // VertebralBody. Do nothing below and above the VertebralBody. To
+ // do that compute several region, slice by slice and fill.
+ MaskImageRegionType region;
+ MaskImageSizeType size;
+ MaskImageIndexType start;
+ size[2] = 1; // a single slice
+ start[0] = output->GetLargestPossibleRegion().GetIndex()[0];
+ size[0] = output->GetLargestPossibleRegion().GetSize()[0];
+ for(uint i=0; i<vertebralAntPositions.size(); i++) {
+ typedef typename itk::ImageRegionIterator<MaskImageType> IteratorType;
+ IteratorType iter =
+ IteratorType(output, output->GetLargestPossibleRegion());
+ MaskImageIndexType index;
+ // Consider some cm posterior to most anterior positions (usually
+ // 1 cm).
+ vertebralAntPositions[i][1] += GetDistanceMaxToAnteriorPartOfTheVertebralBody();
+ // Get index of this point
+ output->TransformPhysicalPointToIndex(vertebralAntPositions[i], index);
+ // Compute region (a single slice)
+ start[2] = index[2];
+ start[1] = output->GetLargestPossibleRegion().GetIndex()[1]+index[1];
+ size[1] = output->GetLargestPossibleRegion().GetSize()[1]-start[1];
+ region.SetSize(size);
+ region.SetIndex(start);
+ // Fill region
+ if (output->GetLargestPossibleRegion().IsInside(start)) {
+ itk::ImageRegionIterator<MaskImageType> it(output, region);
+ it.GoToBegin();
+ while (!it.IsAtEnd()) {
+ it.Set(this->GetBackgroundValue());
+ ++it;
+ }
+ }
+ }
+}
+//--------------------------------------------------------------------
+