PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtk3DDataCollectorTest1.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 
12 #include "PlusConfigure.h"
13 #include "igsioTrackedFrame.h"
14 #include "itkMath.h"
15 #include "vtkPlusDataCollector.h"
16 #include "vtkImageData.h"
17 #include "vtkImageHistogramStatistics.h"
18 #include "vtkMatrix4x4.h"
19 #include "vtkPlusChannel.h"
20 #include "vtkPlusDataSource.h"
21 #include "vtkPlusDevice.h"
22 #include "vtkPlusSavedDataSource.h"
23 #include "vtkIGSIOTrackedFrameList.h"
24 #include "vtkPlusVirtualMixer.h"
25 #include "vtkXMLUtilities.h"
26 #include "vtksys/CommandLineArguments.hxx"
27 
28 static const double FLOAT_COMPARISON_TOLERANCE=1e-4;
29 
30 int main(int argc, char **argv)
31 {
32  std::string inputConfigFileName;
33  double minExpected(-1.0), maxExpected(-1.0), meanExpected(-1.0), stdDevExpected(-1.0), medianExpected(-1.0);
34  double xDimension(-1.0), yDimension(-1.0), zDimension(-1.0);
35  int verboseLevel=vtkPlusLogger::LOG_LEVEL_UNDEFINED;
36 
37  vtksys::CommandLineArguments args;
38  args.Initialize(argc, argv);
39 
40  args.AddArgument("--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName, "Name of the input configuration file.");
41  args.AddArgument("--minimum", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &minExpected, "Minimum pixel value expected.");
42  args.AddArgument("--maximum", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &maxExpected, "Maximum pixel value expected.");
43  args.AddArgument("--mean", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &meanExpected, "Mean pixel value expected.");
44  args.AddArgument("--standard-deviation", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &stdDevExpected, "Standard deviation from the mean expected.");
45  args.AddArgument("--median", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &medianExpected, "Median pixel value expected.");
46  args.AddArgument("--xDimension", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &xDimension, "Expected size of the data in the X dimension.");
47  args.AddArgument("--yDimension", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &yDimension, "Expected size of the data in the Y dimension.");
48  args.AddArgument("--zDimension", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &zDimension, "Expected size of the data in the Z dimension.");
49  args.AddArgument("--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel, "Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
50 
51  if ( !args.Parse() )
52  {
53  std::cerr << "Problem parsing arguments" << std::endl;
54  std::cout << "Help: " << args.GetHelp() << std::endl;
55  exit(EXIT_FAILURE);
56  }
57 
58  vtkPlusLogger::Instance()->SetLogLevel(verboseLevel);
59 
60  if (inputConfigFileName.empty())
61  {
62  LOG_ERROR("input-config-file-name is required");
63  exit(EXIT_FAILURE);
64  }
65 
66  if( minExpected == -1.0 )
67  {
68  LOG_ERROR("minimum is required");
69  exit(EXIT_FAILURE);
70  }
71  if( maxExpected == -1.0 )
72  {
73  LOG_ERROR("maximum is required");
74  exit(EXIT_FAILURE);
75  }
76  if( meanExpected == -1.0 )
77  {
78  LOG_ERROR("mean is required");
79  exit(EXIT_FAILURE);
80  }
81  if( stdDevExpected == -1.0 )
82  {
83  LOG_ERROR("standard-deviation is required");
84  exit(EXIT_FAILURE);
85  }
86  if( medianExpected == -1.0 )
87  {
88  LOG_ERROR("median is required");
89  exit(EXIT_FAILURE);
90  }
91  if( xDimension == -1.0 )
92  {
93  LOG_ERROR("xDimension is required");
94  exit(EXIT_FAILURE);
95  }
96  if( yDimension == -1.0 )
97  {
98  LOG_ERROR("yDimension is required");
99  exit(EXIT_FAILURE);
100  }
101  if( zDimension == -1.0 )
102  {
103  LOG_ERROR("zDimension is required");
104  exit(EXIT_FAILURE);
105  }
106 
108 
109  vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::New();
110  if (PlusXmlUtils::ReadDeviceSetConfigurationFromFile(configRootElement, inputConfigFileName.c_str())==PLUS_FAIL)
111  {
112  LOG_ERROR("Unable to read configuration from file " << inputConfigFileName.c_str());
113  return EXIT_FAILURE;
114  }
115 
117 
118  vtkSmartPointer<vtkPlusDataCollector> dataCollector = vtkSmartPointer<vtkPlusDataCollector>::New();
119 
120  if( dataCollector->ReadConfiguration( configRootElement ) != PLUS_SUCCESS )
121  {
122  LOG_ERROR("Configuration incorrect for vtkPlusDataCollectorTest1.");
123  exit( EXIT_FAILURE );
124  }
125  vtkPlusDevice* videoDevice(NULL);
126  vtkPlusDevice* trackerDevice(NULL);
127  vtkPlusDevice* trackedVideoDevice(NULL);
128 
129  if( dataCollector->GetDevice(videoDevice, "VideoDevice") != PLUS_SUCCESS )
130  {
131  LOG_ERROR("Unable to locate the device with Id=\"VideoDevice\". Check config file.");
132  exit(EXIT_FAILURE);
133  }
134  vtkPlusSavedDataSource* videoSource = dynamic_cast<vtkPlusSavedDataSource*>(videoDevice);
135  if ( videoSource == NULL )
136  {
137  LOG_ERROR( "Unable to cast video source to vtkPlusSavedDataSource." );
138  exit( EXIT_FAILURE );
139  }
140 
141  if( dataCollector->GetDevice(trackerDevice, "TrackerDevice") != PLUS_SUCCESS )
142  {
143  LOG_ERROR("Unable to locate the device with Id=\"TrackerDevice\". Check config file.");
144  exit(EXIT_FAILURE);
145  }
146  vtkPlusSavedDataSource* tracker = dynamic_cast<vtkPlusSavedDataSource*>(trackerDevice);
147  if ( tracker == NULL )
148  {
149  LOG_ERROR( "Unable to cast tracker to vtkPlusSavedDataSource" );
150  exit( EXIT_FAILURE );
151  }
152 
153  if( dataCollector->GetDevice(trackedVideoDevice, "TrackedVideoDevice") != PLUS_SUCCESS )
154  {
155  LOG_ERROR("Unable to locate the device with Id=\"TrackedVideoDevice\". Check config file.");
156  exit(EXIT_FAILURE);
157  }
158  vtkPlusVirtualMixer* mixer = dynamic_cast<vtkPlusVirtualMixer*>(trackedVideoDevice);
159  if( mixer == NULL )
160  {
161  LOG_ERROR( "Unable to cast tracked video device to vtkPlusVirtualMixer" );
162  exit( EXIT_FAILURE );
163  }
164 
165  if ( dataCollector->Connect() != PLUS_SUCCESS )
166  {
167  LOG_ERROR("Failed to connect to devices!" );
168  exit( EXIT_FAILURE );
169  }
170 
171  if ( dataCollector->Start() != PLUS_SUCCESS )
172  {
173  LOG_ERROR("Failed to start data collection!" );
174  exit( EXIT_FAILURE );
175  }
176 
177  // Wait an amount of time to enable some data collection to happen
178 #ifdef _WIN32
179  Sleep(1*1000);
180 #else
181  usleep(1 * 1000000);
182 #endif
183 
184  vtkSmartPointer<vtkIGSIOTrackedFrameList> frameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
185  double timestamp(0.0);
187  if( mixer->GetChannel()->GetTrackedFrameList(timestamp, frameList, 20) != PLUS_SUCCESS )
188  {
189  LOG_ERROR("Unable to retrieve frames from virtual mixer.");
190  exit( EXIT_FAILURE );
191  }
192 
193  vtkImageData* data = frameList->GetTrackedFrame(9)->GetImageData()->GetImage(); // Get the 10th frame's image data
194 
195  int dimensions[3];
196  data->GetDimensions(dimensions);
197 
198  if( xDimension != dimensions[0] || yDimension != dimensions[1] || zDimension != dimensions[2] )
199  {
200  LOG_ERROR("Dimensions don't match. Got [" << dimensions[0] << "," << dimensions[1] << "," << dimensions[2] << "]. Expected [" << xDimension << "," << yDimension << "," << zDimension << "]");
201  exit(EXIT_FAILURE);
202  }
203 
204 
205  vtkSmartPointer<vtkImageHistogramStatistics> stats = vtkSmartPointer<vtkImageHistogramStatistics>::New();
206  stats->SetInputData(data);
207  stats->GenerateHistogramImageOff();
208  stats->Update();
209 
210  double minVal = stats->GetMinimum();
211  double maxVal = stats->GetMaximum();
212  double meanVal = stats->GetMean();
213  double median = stats->GetMedian();
214  double stdDev = stats->GetStandardDeviation();
215 
216  int numErrors(0);
217  if( !itk::Math::FloatAlmostEqual<double>(minVal, minExpected, 4, FLOAT_COMPARISON_TOLERANCE) )
218  {
219  LOG_ERROR("Min values don't match. Got: " << minVal << ". Expected: " << minExpected);
220  numErrors++;
221  }
222 
223  if( !itk::Math::FloatAlmostEqual<double>(maxVal, maxExpected, 4, 5.0) ) // tolerance set based on variance of data reported on dashboard
224  {
225  LOG_ERROR("Max values don't match. Got: " << maxVal << ". Expected: " << maxExpected);
226  numErrors++;
227  }
228 
229  if( !itk::Math::FloatAlmostEqual<double>(meanVal, meanExpected, 4, 0.3) ) // tolerance set based on variance of data reported on dashboard
230  {
231  LOG_ERROR("Mean values don't match. Got: " << meanVal << ". Expected: " << meanExpected);
232  numErrors++;
233  }
234 
235  if( !itk::Math::FloatAlmostEqual<double>(median, medianExpected, 4, FLOAT_COMPARISON_TOLERANCE) )
236  {
237  LOG_ERROR("Median values don't match. Got: " << median << ". Expected: " << medianExpected);
238  numErrors++;
239  }
240 
241  if( !itk::Math::FloatAlmostEqual<double>(stdDev, stdDevExpected, 4, 0.2) ) // tolerance set based on variance of data reported on dashboard
242  {
243  LOG_ERROR("Standard deviation values don't match. Got: " << stdDev << ". Expected: " << stdDevExpected);
244  numErrors++;
245  }
246 
247  dataCollector->Disconnect();
248 
249  if( numErrors > 0 )
250  {
251  return EXIT_FAILURE;
252  }
253 
254  LOG_INFO("vtk3DDataCollectorTest1 completed successfully!");
255  return EXIT_SUCCESS;
256 
257 }
const uint32_t * data
Definition: phidget22.h:3971
Abstract interface for tracker and video devices.
Definition: vtkPlusDevice.h:60
double * timestamp
Definition: phidget22.h:3432
#define PLUS_FAIL
Definition: PlusCommon.h:43
static vtkPlusConfig * GetInstance()
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetTrackedFrameList(double &aTimestampOfLastFrameAlreadyGot, vtkIGSIOTrackedFrameList *aTrackedFrameList, int aMaxNumberOfFramesToAdd)
vtkPlusChannel * GetChannel() const
static const double FLOAT_COMPARISON_TOLERANCE
int main(int argc, char **argv)
virtual PlusStatus GetOldestTimestamp(double &ts)
Class for providing VTK video input interface from sequence fileAttributes:
static vtkIGSIOLogger * Instance()
void SetDeviceSetConfigurationData(vtkXMLDataElement *deviceSetConfigurationData)
static PlusStatus ReadDeviceSetConfigurationFromFile(vtkXMLDataElement *config, const char *filename)
Definition: PlusXmlUtils.h:23