Orfeo Toolbox  3.16
itkPolylineMaskImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkPolylineMaskImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2008-11-07 19:39:44 $
7  Version: $Revision: 1.16 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkPolylineMaskImageFilter_txx
18 #define __itkPolylineMaskImageFilter_txx
19 
22 #include "itkImageRegionIterator.h"
24 #include "itkProgressReporter.h"
26 #include "itkResampleImageFilter.h"
27 #include "itkLineIterator.h"
29 #include "itkPathIterator.h"
30 #include "itkVector.h"
31 #include "itkBoundingBox.h"
32 
33 namespace itk
34 {
38 template <class TInputImage, class TPolyline, class TVector,
39  class TOutputImage>
42 {
43  this->SetNumberOfRequiredInputs( 2 );
44  m_ViewVector.Fill(1);
45  m_UpVector.Fill(1);
46  m_CameraCenterPoint.Fill(0);
47  m_FocalDistance = 0.0;
48  m_FocalPoint.Fill( 0.0 );
49 
50  // This filter is meant only for 3D input and output images. We must
51  // throw an exception otherwise.
52  if( (TInputImage::ImageDimension != 3) ||
53  (TOutputImage::ImageDimension !=3 ) )
54  {
55  itkExceptionMacro( << "PolylineMaskImageFilter must be templated over "
56  << "input and output images of dimension 3" );
57  }
58 
59  // View vectors must be of dimension 3
60  if(TVector::Length != 3)
61  {
62  itkExceptionMacro( << "PolylineMaskImageFilter must be templated over "
63  << "a view vector of length 3" );
64  }
65 }
66 
70 template <class TInputImage, class TPolyline, class TVector,
71  class TOutputImage>
74 {
75  // Process object is not const-correct so the const_cast is required here
77  const_cast< InputImageType * >( input ) );
78 }
79 
83 template <class TInputImage, class TPolyline, class TVector,
84  class TOutputImage>
87 {
88  // Process object is not const-correct so the const_cast is required here
90  const_cast< PolylineType * >( input ) );
91 }
92 
96 template <class TInputImage, class TPolyline, class TVector,
97  class TOutputImage>
100 {
101  /* Normalize the view and up vector */
102  TVector nUpVector; /* normalized Up vector */
103  TVector nViewVector; /* normalized View vector */
104 
105  nUpVector = m_UpVector;
106  nUpVector.Normalize();
107 
108  nViewVector = m_ViewVector;
109  nViewVector.Normalize();
110 
111  itkDebugMacro(<<"Normalized Up vector" <<nUpVector);
112  itkDebugMacro(<<"Normalized View vector"<<nViewVector);
113 
114  /* orthogonalize nUpVector and nViewVector */
115  TVector nOrthogonalVector;
116 
117  nOrthogonalVector = nUpVector - (nViewVector*(nUpVector*nViewVector));
118 
119  itkDebugMacro(<<"Up vector component orthogonal to View vector "<<nOrthogonalVector);
120 
121  /* Perform cross product and determine a third coordinate axis
122  orthogonal to both nOrthogonalVector and nViewVector */
123 
124  TVector nThirdAxis;
125  nThirdAxis = CrossProduct(nOrthogonalVector,nViewVector);
126 
127  itkDebugMacro(<<"Third basis vector"<<nThirdAxis);
128 
129  /* populate the rotation matrix using the unit vectors of the
130  camera reference coordinate system */
131 
132  m_RotationMatrix[0][0] = nThirdAxis[0];
133  m_RotationMatrix[0][1] = nThirdAxis[1];
134  m_RotationMatrix[0][2] = nThirdAxis[2];
135 
136  m_RotationMatrix[1][0] = nOrthogonalVector[0];
137  m_RotationMatrix[1][1] = nOrthogonalVector[1];
138  m_RotationMatrix[1][2] = nOrthogonalVector[2];
139 
140  m_RotationMatrix[2][0] = nViewVector[0];
141  m_RotationMatrix[2][1] = nViewVector[1];
142  m_RotationMatrix[2][2] = nViewVector[2];
143 
144 }
145 
149 template< class TInputImage, class TPolyline, class TVector, class TOutputImage>
150 typename PolylineMaskImageFilter< TInputImage,TPolyline,TVector,
151  TOutputImage>::ProjPlanePointType
154 {
155  unsigned int i;
156  PointType centered;
157 
158  // itkDebugMacro(<<"Point transforming"<<inputPoint);
159 
160  for(i=0;i<3;i++)
161  {
162  centered[i] = inputPoint[i] - m_CameraCenterPoint[i];
163  }
164 
165  PointType rotated = m_RotationMatrix * centered;
166 
167  ProjPlanePointType result;
168 
169  double factor = m_FocalDistance / ( rotated[2] );
170 
171  result[0] = m_FocalPoint[0] + (rotated[0] * factor);
172  result[1] = m_FocalPoint[1] + (rotated[1] * factor);
173 
174  // itkDebugMacro(<<"Point projected"<<result);
175 
176  return result;
177 }
178 
182 template <class TInputImage, class TPolyline, class TVector,
183  class TOutputImage>
186 {
187 
188  typedef typename TInputImage::SizeType InputImageSizeType;
189  typedef typename TInputImage::PointType InputImagePointType;
190  typedef typename TInputImage::SpacingType InputImageSpacingType;
191  typedef ImageRegionConstIterator<TInputImage> InputImageConstIteratorType;
192 
193  typedef typename TOutputImage::IndexType ImageIndexType;
194  typedef typename TOutputImage::PixelType PixelType;
195  typedef ImageRegionIterator<TOutputImage> OutputImageIteratorType;
196 
197 
198  typedef typename TPolyline::Pointer PolylinePointer;
199  typedef typename TPolyline::VertexType VertexType;
200  typedef typename TPolyline::VertexListType VertexListType;
201  typedef typename TPolyline::IndexType PolylineIndexType;
202 
203  typedef Point<double,3> OriginType;
204 
205  typename TInputImage::ConstPointer inputImagePtr(
206  dynamic_cast<const TInputImage * >(
207  this->ProcessObject::GetInput(0)));
208  typename TPolyline::ConstPointer polylinePtr(
209  dynamic_cast<const TPolyline * >(
210  this->ProcessObject::GetInput(1)));
211  typename TOutputImage::Pointer outputImagePtr(
212  dynamic_cast<TOutputImage * >(
213  this->ProcessObject::GetOutput(0)));
214 
215 
216  OriginType originInput;
217  originInput.Fill(0.0);
218  //outputImagePtr->SetOrigin(inputImagePtr->GetOrigin());
219  outputImagePtr->SetOrigin(originInput);
220  outputImagePtr->SetSpacing(inputImagePtr->GetSpacing());
221  outputImagePtr->SetDirection(inputImagePtr->GetDirection());
222 
223  outputImagePtr->SetRequestedRegion( inputImagePtr->GetRequestedRegion() );
224  outputImagePtr->SetBufferedRegion( inputImagePtr->GetBufferedRegion() );
225  outputImagePtr->SetLargestPossibleRegion( inputImagePtr->GetLargestPossibleRegion() );
226  outputImagePtr->Allocate();
227  outputImagePtr->FillBuffer(0);
228 
229  InputImageConstIteratorType inputIt(inputImagePtr,inputImagePtr->GetLargestPossibleRegion());
230  OutputImageIteratorType outputIt(outputImagePtr,outputImagePtr->GetLargestPossibleRegion());
231 
233  typedef typename InterpolatorType::OutputType OutputType;
234  typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
235  typedef typename InterpolatorType::PointType InterpolatorPointType;
236 
237 
238  /* Generate the transformation matrix */
239  this->GenerateRotationMatrix();
240 
241  // Generate input and output point
242  InterpolatorPointType inputPoint;
243  ProjPlanePointType outputPoint;
244 
245  // Generate a 2D image with the viewing polygon as a mask
246  typedef Image<PixelType,2> ProjectionImageType;
247  typedef typename ProjectionImageType::IndexType ProjectionImageIndexType;
248  typedef typename ProjectionImageType::IndexValueType ProjectionImageIndexValueType;
249  typedef typename ProjectionImageType::PointType ProjectionImagePointType;
250  typedef typename ProjectionImageType::SpacingType ProjectionImageSpacingType;
251  typedef typename ProjectionImageType::PixelType ProjectionImagePixelType;
252  typedef typename ProjectionImageType::RegionType ProjectionImageRegionType;
253  typedef typename ProjectionImageType::SizeType ProjectionImageSizeType;
254 
255 
256  ProjectionImageRegionType projectionRegion;
257 
258 
259  /* Determine projection image size by transforming the eight corner
260  of the 3D input image */
261 
262  InputImageSizeType inputImageSize;
263  typedef Point<double, 3> CornerPointType;
264  typedef Point<double, 2> CornerPointProjectionType;
265 
266  typedef BoundingBox< unsigned long int, 2, double > BoundingBoxType;
267  typedef BoundingBoxType::PointsContainer CornerPointProjectionContainer;
268 
269  CornerPointProjectionContainer::Pointer cornerPointProjectionlist = CornerPointProjectionContainer::New();
270  CornerPointType cornerPoint;
271  CornerPointType originPoint;
272  CornerPointProjectionType cornerProjectionPoint;
273 
274  originPoint[0] = 0.0;
275  originPoint[1] = 0.0;
276  originPoint[2] = 0.0;
277 
278  originPoint = inputImagePtr->GetOrigin();
279  inputImageSize = inputImagePtr->GetLargestPossibleRegion().GetSize();
280 
281  // (xmin,ymin,zmin)
282 
283  cornerPoint = originPoint;
284  cornerProjectionPoint = this->TransformProjectPoint(cornerPoint);
285  cornerPointProjectionlist->push_back(cornerProjectionPoint);
286 
287  //std::cout<<"CornerPoint="<<cornerPoint<<"\t"<<"ProjectedPoint="<<cornerProjectionPoint<<std::endl;
288 
289  // (xmin,ymin,zmax)
290  cornerPoint[0] = originPoint[0];
291  cornerPoint[1] = originPoint[1];
292  cornerPoint[2] = originPoint[2] + inputImageSize[2];
293  cornerProjectionPoint = this->TransformProjectPoint(cornerPoint);
294  cornerPointProjectionlist->push_back(cornerProjectionPoint);
295 
296  //std::cout<<"CornerPoint="<<cornerPoint<<"\t"<<"ProjectedPoint="<<cornerProjectionPoint<<std::endl;
297 
298  // (xmin,ymax,zmin)
299  cornerPoint[0] = originPoint[0];
300  cornerPoint[1] = originPoint[1] + inputImageSize[1];
301  cornerPoint[2] = originPoint[2];
302  cornerProjectionPoint = this->TransformProjectPoint(cornerPoint);
303  cornerPointProjectionlist->push_back(cornerProjectionPoint);
304 
305  //std::cout<<"CornerPoint="<<cornerPoint<<"\t"<<"ProjectedPoint="<<cornerProjectionPoint<<std::endl;
306 
307 
308 // (xmin,ymax,zmax)
309  cornerPoint[0] = originPoint[0];
310  cornerPoint[1] = originPoint[1] + inputImageSize[1];
311  cornerPoint[2] = originPoint[2] + inputImageSize[2];
312  cornerProjectionPoint = this->TransformProjectPoint(cornerPoint);
313  cornerPointProjectionlist->push_back(cornerProjectionPoint);
314 
315  //std::cout<<"CornerPoint="<<cornerPoint<<"\t"<<"ProjectedPoint="<<cornerProjectionPoint<<std::endl;
316 
317 // (xmax,ymin,zmin)
318  cornerPoint[0] = originPoint[0] + inputImageSize[0];
319  cornerPoint[1] = originPoint[1];
320  cornerPoint[2] = originPoint[2];
321 
322  cornerProjectionPoint = this->TransformProjectPoint(cornerPoint);
323  cornerPointProjectionlist->push_back(cornerProjectionPoint);
324 
325  //std::cout<<"CornerPoint="<<cornerPoint<<"\t"<<"ProjectedPoint="<<cornerProjectionPoint<<std::endl;
326 
327 // (xmax,ymin,zmax)
328  cornerPoint[0] = originPoint[0] + inputImageSize[0];
329  cornerPoint[1] = originPoint[1];
330  cornerPoint[2] = originPoint[2] + inputImageSize[2];
331 
332  cornerProjectionPoint = this->TransformProjectPoint(cornerPoint);
333  cornerPointProjectionlist->push_back(cornerProjectionPoint);
334 
335  //std::cout<<"CornerPoint="<<cornerPoint<<"\t"<<"ProjectedPoint="<<cornerProjectionPoint<<std::endl;
336 
337 // (xmax,ymax,zmin)
338  cornerPoint[0] = originPoint[0] + inputImageSize[0];
339  cornerPoint[1] = originPoint[1] + inputImageSize[1];
340  cornerPoint[2] = originPoint[2];
341 
342  cornerProjectionPoint = this->TransformProjectPoint(cornerPoint);
343  cornerPointProjectionlist->push_back(cornerProjectionPoint);
344 
345 
346  //std::cout<<"CornerPoint="<<cornerPoint<<"\t"<<"ProjectedPoint="<<cornerProjectionPoint<<std::endl;
347 
348 // (xmax,ymax,zmax)
349  cornerPoint[0] = originPoint[0] + inputImageSize[0];
350  cornerPoint[1] = originPoint[1] + inputImageSize[1];
351  cornerPoint[2] = originPoint[2] + inputImageSize[2];
352 
353  cornerProjectionPoint = this->TransformProjectPoint(cornerPoint);
354  cornerPointProjectionlist->push_back(cornerProjectionPoint);
355 
356  //std::cout<<"CornerPoint="<<cornerPoint<<"\t"<<"ProjectedPoint="<<cornerProjectionPoint<<std::endl;
357 
358  /* Compute the bounding box of the projected points */
359  BoundingBoxType::Pointer boundingBox = BoundingBoxType::New();
360 
361  boundingBox->SetPoints ( cornerPointProjectionlist );
362 
363  if ( !boundingBox->ComputeBoundingBox() )
364  {
365  itkExceptionMacro(<<"Bounding box computation error");
366  }
367 
368  const BoundingBoxType::BoundsArrayType & bounds = boundingBox->GetBounds();
369  itkDebugMacro(<< "Projection image bounding box="<<bounds);
370 
371  ProjectionImageIndexType projectionStart;
372  projectionStart[0] = 0;
373  projectionStart[1] = 0;
374 
375  ProjectionImageSizeType projectionSize;
376  ProjectionImageIndexValueType pad;
377 
378  pad=5;
379 
380  projectionSize[0] = (ProjectionImageIndexValueType) (bounds[1]-bounds[0]) + pad;
381  projectionSize[1] = (ProjectionImageIndexValueType) (bounds[3]-bounds[2]) + pad;
382 
383  projectionRegion.SetIndex(projectionStart);
384  projectionRegion.SetSize(projectionSize);
385 
386  typename ProjectionImageType::Pointer projectionImagePtr = ProjectionImageType::New();
387 
388  ProjectionImagePointType origin;
389  origin[0] = bounds[0];
390  origin[1] = bounds[2];
391 
392  projectionImagePtr->SetOrigin(origin);
393 
394  ProjectionImageSpacingType spacing;
395 
396  spacing[0] = 1.0;
397  spacing[1] = 1.0;
398 
399  projectionImagePtr->SetSpacing(spacing);
400 
401  itkDebugMacro(<<"Projection image size:"<<projectionSize);
402  itkDebugMacro(<<"Projection image start index:"<<projectionStart);
403  itkDebugMacro(<<"Projection image origin:"<<origin);
404 
405  projectionImagePtr->SetRequestedRegion( projectionRegion );
406  projectionImagePtr->SetBufferedRegion( projectionRegion );
407  projectionImagePtr->SetLargestPossibleRegion( projectionRegion );
408  projectionImagePtr->Allocate();
409  projectionImagePtr->FillBuffer(0);
410 
411  typedef ImageRegionIterator<ProjectionImageType> ProjectionImageIteratorType;
412  ProjectionImageIteratorType projectionIt(projectionImagePtr,projectionImagePtr->GetLargestPossibleRegion());
413 
414  itkDebugMacro(<<"Rotation matrix"<<std::cout<<m_RotationMatrix);
415 
416  typedef typename VertexListType::Pointer VertexListPointer;
417 
418  const VertexListType * container = polylinePtr->GetVertexList();
419 
420  typename VertexListType::ConstIterator piter = container->Begin();
421 
422  /* Rasterize each polyline segment using breshnan line iterator */
423 
424  VertexType startIndex;
425  VertexType endIndex;
426  VertexType projectionIndex;
427  VertexType pstartIndex;
428 
429  /* define flag to indicate the line segment slope */
430  bool pflag;
431 
432  /* define background, foreground pixel values and unlabed pixel value */
433  PixelType u_val = static_cast<ProjectionImagePixelType> (0);
434  PixelType b_val = static_cast<ProjectionImagePixelType> (2);
435  PixelType f_val = static_cast<ProjectionImagePixelType> (255);
436 
437  projectionImagePtr->FillBuffer(u_val);
438 
439  /* polyon start index */
440  pstartIndex = piter.Value();
441  projectionIndex = pstartIndex;
442  ++piter;
443  ProjectionImageIndexType startImageIndex;
444  ProjectionImageIndexType endImageIndex;
445  ProjectionImageIndexType projectionImageIndex;
446 
447  typedef typename ProjectionImageIndexType::IndexValueType IndexValueType;
448 
449  typedef LineIterator<ProjectionImageType> LineIteratorType;
450  typedef ImageLinearIteratorWithIndex< ProjectionImageType > ImageLineIteratorType;
451 
452  ImageLineIteratorType imit(projectionImagePtr, projectionImagePtr->GetLargestPossibleRegion());
453  imit.SetDirection( 0 );
454 
455  while ( piter != container->End() )
456  {
457  pflag = false;
458  startIndex = projectionIndex;
459  endIndex = piter.Value();
460 
461  for(unsigned int i=0; i < ProjectionImageType::ImageDimension; i++ )
462  {
463  startImageIndex[i] = static_cast<IndexValueType> (startIndex[i]);
464  endImageIndex[i] = static_cast<IndexValueType> (endIndex[i]);
465  }
466 
467 
468  if (endImageIndex[1] > startImageIndex[1])
469  {
470  pflag = true;
471  }
472 
473  itkDebugMacro(<<"Polyline:"<<startImageIndex<<","<<endImageIndex);
474  LineIteratorType it(projectionImagePtr, startImageIndex, endImageIndex);
475  it.GoToBegin();
476 
477  while (!it.IsAtEnd())
478  {
479  projectionImageIndex[0] = it.GetIndex()[0];
480  projectionImageIndex[1] = it.GetIndex()[1];
481 
482  //initialize imit using it
483  imit.SetIndex(projectionImageIndex);
484  while ( ! imit.IsAtEndOfLine() )
485  {
486  if ( pflag )
487  {
488  if ( imit.Get() == u_val)
489  {
490  imit.Set(f_val);
491  }
492  }
493  else
494  imit.Set(b_val);
495 
496  ++imit;
497  }
498  ++it;
499  }
500  projectionIndex = endIndex;
501  ++piter;
502  }
503 
504  /* Close the polygon */
505  pflag = false;
506  startIndex = projectionIndex;
507  endIndex = pstartIndex;
508 
509  for(unsigned int i=0; i < ProjectionImageType::ImageDimension; i++ )
510  {
511  startImageIndex[i] = static_cast<IndexValueType> (startIndex[i]);
512  endImageIndex[i] = static_cast<IndexValueType> (endIndex[i]);
513  }
514 
515  if (endImageIndex[1] > startImageIndex[1])
516  {
517  pflag = true;
518  }
519 
520  LineIteratorType it(projectionImagePtr, startImageIndex, endImageIndex);
521  it.GoToBegin();
522 
523  while (!it.IsAtEnd())
524  {
525  projectionImageIndex[0] = it.GetIndex()[0];
526  projectionImageIndex[1] = it.GetIndex()[1];
527  //initialize imit using it
528 
529  imit.SetIndex(projectionImageIndex);
530  while ( ! imit.IsAtEndOfLine() )
531  {
532  if ( pflag )
533  {
534  if ( imit.Get() == u_val)
535  {
536  imit.Set(f_val);
537  }
538  }
539  else
540  {
541  imit.Set(b_val);
542  }
543  ++imit;
544  }
545  ++it;
546  }
547 
548  //Mask the input image using the binary image defined by the region
549  //demarcated by the polyline contour
550  outputIt.GoToBegin();
551  inputIt.GoToBegin();
552 
553  InputImageSpacingType inputImageSpacing;
554  InputImagePointType inputImageOrigin;
555 
556  inputImageSpacing = inputImagePtr->GetSpacing();
557  inputImageOrigin = inputImagePtr->GetOrigin();
558  inputImageSize = inputImagePtr->GetLargestPossibleRegion().GetSize();
559 
560  while ( !inputIt.IsAtEnd() )
561  {
562  outputImagePtr->TransformIndexToPhysicalPoint( outputIt.GetIndex(), inputPoint );
563  outputPoint = this->TransformProjectPoint(inputPoint);
564  projectionImagePtr->TransformPhysicalPointToIndex(outputPoint,projectionImageIndex);
565 
566  //itkDebugMacro(<<"Input image (index,physical coordinate,pixel):"<<inputIt.GetIndex()<<","<<inputPoint<<inputIt.Get()<<std::endl);
567  //itkDebugMacro(<<"Projection image (index,physical coordinate,pixel):"<<projectionImageIndex<<","<<outputPoint<<","<<projectionIt.Get()<<std::endl);
568 
569  // fileout<<inputIt.GetIndex()<<","<<inputPoint<<"="<<projectionImageIndex<<","<<outputPoint<<std::endl;
570  if ( ! projectionImagePtr->GetBufferedRegion().IsInside(projectionImageIndex))
571  {
572  itkExceptionMacro(<<"Projection Image index out of bound:"<<projectionImageIndex);
573  }
574 
575  if(projectionImagePtr->GetPixel(projectionImageIndex) == f_val)
576  {
577  outputIt.Set(inputIt.Get());
578  }
579  else
580  {
581  outputIt.Set(u_val);
582  }
583 
584  ++inputIt;
585  ++outputIt;
586  }
587 }
588 
589 template <class TInputImage, class TPolyline, class TVector,
590  class TOutputImage>
592 ::PrintSelf(std::ostream& os, Indent indent) const
593 {
594  Superclass::PrintSelf(os,indent);
595  os << indent << "Viewing vector: "
596  << static_cast<typename NumericTraits<VectorType>::PrintType>(m_ViewVector)
597  << std::endl;
598  os << indent << "Up Vector: "
599  << static_cast<typename NumericTraits<VectorType>::PrintType>(m_UpVector)
600  << std::endl;
601  os << indent << "Camera Center Point: " << m_CameraCenterPoint << std::endl;
602  os << indent << "Focal Point : " << m_FocalPoint << std::endl;
603  os << indent << "Focal Distance : " << m_FocalDistance << std::endl;
604  os << indent << "Rotation matrix : " << m_RotationMatrix << std::endl;
605 
606 }
607 } // end namespace itk
608 #endif

Generated at Sun Feb 3 2013 00:00:02 for Orfeo Toolbox with doxygen 1.8.1.1