PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusUsScanConvertLinear.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 #include "PlusConfigure.h"
8 
10 
11 #include "vtkObjectFactory.h"
12 #include "vtkXMLDataElement.h"
13 #include "vtkImageReslice.h"
14 #include "vtkImageData.h"
15 #include "vtkAlgorithmOutput.h"
16 
18 
19 //----------------------------------------------------------------------------
21 {
22  this->ImagingDepthMm=50.0;
23  this->TransducerWidthMm=38.0;
24 
25  this->ImageReslice=vtkImageReslice::New();
26 }
27 
28 //----------------------------------------------------------------------------
30 {
31  this->ImageReslice->Delete();
32  this->ImageReslice=NULL;
33 }
34 
35 void vtkPlusUsScanConvertLinear::PrintSelf(ostream& os, vtkIndent indent)
36 {
37  this->Superclass::PrintSelf(os,indent);
38  os << indent << "ImagingDepthMm: "<< this->ImagingDepthMm << "\n";
39  os << indent << "TransducerWidthMm: "<< this->TransducerWidthMm << "\n";
40 }
41 
42 //-----------------------------------------------------------------------------
43 void vtkPlusUsScanConvertLinear::SetInputConnection(vtkAlgorithmOutput* input)
44 {
45  this->ImageReslice->SetInputConnection(input);
46 }
47 
48 //-----------------------------------------------------------------------------
49 void vtkPlusUsScanConvertLinear::SetInputData(vtkDataObject *input)
50 {
51  this->ImageReslice->SetInputData(input);
52 }
53 
54 //-----------------------------------------------------------------------------
56 {
57  this->ImageReslice->SetOutputExtent(this->OutputImageExtent);
58  // In Plus the convention is that the image coordinate system has always unit spacing and zero origin
59  this->ImageReslice->SetOutputSpacing(1.0, 1.0, 1.0);
60 
61  // The direction cosines give the x, y, and z axes for the output volume.
62  // Updating whole extent is needed when the requested extent is smaller than the producer's whole extent
63  this->ImageReslice->GetInputConnection(0,0)->GetProducer()->UpdateWholeExtent();
64  vtkImageData* inputImage=this->ImageReslice->GetImageDataInput(0);
65  if (inputImage==NULL)
66  {
67  LOG_ERROR("vtkPlusUsScanConvertLinear::Update failed: no input image is specified");
68  return;
69  }
70 
71  inputImage->GetExtent(this->InputImageExtent);
72  int scanLineLengthPixels=this->InputImageExtent[1]-this->InputImageExtent[0]+1;
73  int numberOfScanLines=this->InputImageExtent[3]-this->InputImageExtent[2]+1;
74 
75  // xVec: controls the width of the output image, if larger then image becomes narrower
76  double inputWidthSpacing=this->TransducerWidthMm/static_cast<double>(numberOfScanLines);
77  double xVec[3]={0, (this->OutputImageSpacing[0]/inputWidthSpacing), 0};
78 
79  // yVec: controls the height of the output image, if larger then image becomes shorter
80  double inputDepthSpacing=this->ImagingDepthMm/static_cast<double>(scanLineLengthPixels);
81  double yVec[3]={this->OutputImageSpacing[1]/inputDepthSpacing, 0, 0};
82 
83  double zVec[3]={0,0,1.0};
84  this->ImageReslice->SetResliceAxesDirectionCosines(xVec, yVec, zVec);
85 
86  // Default transducer center is horizontally centered, with 0 offset along y axis
87  double halfImageWidthPixel=numberOfScanLines/2*inputWidthSpacing/this->OutputImageSpacing[0];
88  double transducerCenterPixel[2] = { halfImageWidthPixel, 0};
90  {
91  transducerCenterPixel[0]=this->TransducerCenterPixel[0];
92  transducerCenterPixel[1]=this->TransducerCenterPixel[1];
93  }
94 
95  this->ImageReslice->SetOutputOrigin(-this->TransducerCenterPixel[0]+halfImageWidthPixel,-this->TransducerCenterPixel[1],0);
96 
97  this->ImageReslice->Update();
98 }
99 
100 //-----------------------------------------------------------------------------
102 {
103  return this->ImageReslice->GetOutput();
104 }
105 
106 //-----------------------------------------------------------------------------
107 PlusStatus vtkPlusUsScanConvertLinear::ReadConfiguration(vtkXMLDataElement* scanConversionElement)
108 {
109  LOG_TRACE("vtkPlusUsScanConvertLinear::ReadConfiguration");
110 
111  if (this->Superclass::ReadConfiguration(scanConversionElement)!=PLUS_SUCCESS)
112  {
113  return PLUS_FAIL;
114  }
115 
116  XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(double, ImagingDepthMm, scanConversionElement);
117  XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(double, TransducerWidthMm, scanConversionElement);
118 
119  return PLUS_SUCCESS;
120 }
121 
122 //-----------------------------------------------------------------------------
123 PlusStatus vtkPlusUsScanConvertLinear::WriteConfiguration(vtkXMLDataElement* scanConversionElement)
124 {
125  LOG_TRACE("vtkPlusUsScanConvertLinear::WriteConfiguration");
126 
127  if (this->Superclass::WriteConfiguration(scanConversionElement)!=PLUS_SUCCESS)
128  {
129  return PLUS_FAIL;
130  }
131 
132  scanConversionElement->SetDoubleAttribute("ImagingDepthMm", this->ImagingDepthMm);
133  scanConversionElement->SetDoubleAttribute("TransducerWidthMm", this->TransducerWidthMm);
134 
135  return PLUS_SUCCESS;
136 }
137 
138 //-----------------------------------------------------------------------------
139 PlusStatus vtkPlusUsScanConvertLinear::GetScanLineEndPoints(int scanLineIndex, double scanlineStartPoint_OutputImage[4],double scanlineEndPoint_OutputImage[4])
140 {
141  int numberOfScanLines=this->InputImageExtent[3]-this->InputImageExtent[2]+1;
142  if (scanLineIndex<0 || scanLineIndex>=numberOfScanLines)
143  {
144  LOG_ERROR("GetScanLineEndPoints failed: requestd scanLine="<<scanLineIndex<<" is out of the valid range (0-"<<numberOfScanLines-1<<")");
145  return PLUS_FAIL;
146  }
147 
148  int outputImageSizePixel[2]=
149  {
150  this->OutputImageExtent[1]-this->OutputImageExtent[0]+1,
151  this->OutputImageExtent[3]-this->OutputImageExtent[2]+1
152  };
153 
154  // Default transducer center is horizontally centered in the frame, with 0 offset along y axis
155  double transducerCenterPixel[2] = { 0.5*outputImageSizePixel[0], 0 };
157  {
158  transducerCenterPixel[0]=this->TransducerCenterPixel[0];
159  transducerCenterPixel[1]=this->TransducerCenterPixel[1];
160  }
161 
162  double imageWidthPixel=this->TransducerWidthMm/this->OutputImageSpacing[0];
163  double transducerCornerPixel[2] = { transducerCenterPixel[0]-0.5*imageWidthPixel, transducerCenterPixel[1] };
164  double scanlineSpacingXPixel=imageWidthPixel/double(numberOfScanLines);
165  scanlineStartPoint_OutputImage[0] = transducerCornerPixel[0]+double(scanLineIndex)*scanlineSpacingXPixel;
166  scanlineStartPoint_OutputImage[1] = transducerCornerPixel[1];
167  scanlineStartPoint_OutputImage[2] = 0;
168  scanlineStartPoint_OutputImage[3] = 1;
169 
170  scanlineEndPoint_OutputImage[0] = scanlineStartPoint_OutputImage[0];
171  scanlineEndPoint_OutputImage[1] = transducerCornerPixel[1] + this->ImagingDepthMm/this->OutputImageSpacing[1];
172  scanlineEndPoint_OutputImage[2] = 0;
173  scanlineEndPoint_OutputImage[3] = 1;
174 
175  return PLUS_SUCCESS;
176 }
177 
178 //-----------------------------------------------------------------------------
180 {
181  int scanLineLengthPixels=this->InputImageExtent[1]-this->InputImageExtent[0]+1;
182  if (scanLineLengthPixels<1)
183  {
184  LOG_ERROR("Cannot determine DistanceBetweenScanlineSamplePointsMm because scanLineLengthPixels="<<scanLineLengthPixels<<" is invalid");
185  return 0.0;
186  }
187  double distanceBetweenScanlineSamplePointsMm=this->ImagingDepthMm/double(scanLineLengthPixels);
188  return distanceBetweenScanlineSamplePointsMm;
189 }
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *scanConversionElement)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *scanConversionElement)
igsioStatus PlusStatus
Definition: PlusCommon.h:40
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *scanConversionElement)
#define PLUS_FAIL
Definition: PlusCommon.h:43
virtual void SetInputData(vtkDataObject *input)
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
virtual double GetDistanceBetweenScanlineSamplePointsMm()
vtkStandardNewMacro(vtkPlusUsScanConvertLinear)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
This class performs scan conversion from scan lines for curvilinear probes.
virtual PlusStatus GetScanLineEndPoints(int scanLineIndex, double scanlineStartPoint_OutputImage[4], double scanlineEndPoint_OutputImage[4])
virtual void SetInputConnection(vtkAlgorithmOutput *input)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *scanConversionElement)