PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusTransverseProcessEnhancerTest.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"
14 #include <vtkPlusSequenceIO.h>
15 
16 // VTK includes
17 #include "vtkImageCast.h"
18 #include <vtkSmartPointer.h>
19 #include <vtksys/CommandLineArguments.hxx>
20 
21 // IGSIO includes
22 #include <igsioTrackedFrame.h>
23 #include <vtkIGSIOTrackedFrameList.h>
24 
25 //----------------------------------------------------------------------------
26 int main(int argc, char** argv)
27 {
28 
29  bool printHelp = false;
30  vtksys::CommandLineArguments args;
31 
32  //Setup variables for command line
33  std::string inputFileName;
34  std::string inputConfigFileName;
35  std::string outputConfigFileName;
36  std::string outputFileName;
37  bool saveIntermediateResults = false;
38  int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
39 
40  //Get command line arguments
41  args.Initialize(argc, argv);
42  args.AddArgument("--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp, "Print this help");
43  args.AddArgument("--input-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputFileName, "The filename for the input ultrasound sequence to process.");
44  args.AddArgument("--input-config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName, "The filename for input config file.");
45  args.AddArgument("--output-config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputConfigFileName, "Optional filename for output config file. Creates new config file with paramaters used during this test");
46  args.AddArgument("--output-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputFileName, "The filename to write the processed sequence to.");
47  args.AddArgument("--save-intermediate-images", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &saveIntermediateResults, "If intermediate images should be saved to output files");
48  args.AddArgument("--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel, "Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
49 
50  if (!args.Parse())
51  {
52  LOG_ERROR("Problem parsing arguments");
53  LOG_INFO("Help: " << args.GetHelp());
54  exit(EXIT_FAILURE);
55  }
56 
57  vtkPlusLogger::Instance()->SetLogLevel(verboseLevel);
58 
59  //check for various non-optional command line arguments
60  int commandCheckStatus = EXIT_SUCCESS;
61 
62  if (inputFileName.empty())
63  {
64  LOG_ERROR("The argument --input-seq-file is required");
65  commandCheckStatus = EXIT_FAILURE;
66  }
67  if (inputConfigFileName.empty())
68  {
69  LOG_ERROR("The argument --input-config-file is required");
70  commandCheckStatus = EXIT_FAILURE;
71  }
72  if (outputFileName.empty())
73  {
74  LOG_ERROR("The argument --output-seq-file is required");
75  commandCheckStatus = EXIT_FAILURE;
76  }
77 
78  if (commandCheckStatus == EXIT_FAILURE)
79  {
80  return EXIT_FAILURE;
81  }
82 
83  vtkSmartPointer<vtkPlusTransverseProcessEnhancer> enhancer = vtkSmartPointer<vtkPlusTransverseProcessEnhancer>::New();
84 
85  // Read input sequence
86  vtkSmartPointer<vtkIGSIOTrackedFrameList> trackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
87  if (vtkPlusSequenceIO::Read(inputFileName, trackedFrameList) == PLUS_FAIL)
88  {
89  return EXIT_FAILURE;
90  }
91  vtkSmartPointer<vtkImageCast> castToUchar = vtkSmartPointer<vtkImageCast>::New();
92  castToUchar->SetOutputScalarTypeToUnsignedChar();
93 
94  int numberOfFrames = trackedFrameList->GetNumberOfTrackedFrames();
95  LOG_INFO("Number of frames in input: " << numberOfFrames);
96 
97  enhancer->SetInputFrames(trackedFrameList);
98 
99  LOG_INFO("Reading Config file");
100  vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::New();
101  if (PlusXmlUtils::ReadDeviceSetConfigurationFromFile(configRootElement, inputConfigFileName.c_str()) == PLUS_FAIL)
102  {
103  LOG_ERROR("Unable to read configuration from file " << inputConfigFileName);
104  return EXIT_FAILURE;
105  }
106 
107  vtkSmartPointer<vtkXMLDataElement> elementToUse;
108 
109  // Find the ScanConversion element in the XML file
110  vtkSmartPointer<vtkXMLDataElement> processorElement = configRootElement->FindNestedElementWithName("ScanConversion");
111  if (processorElement == NULL)
112  {
113  processorElement = configRootElement->LookupElementWithName("Processor");
114  if (processorElement != NULL){
115  vtkSmartPointer<vtkXMLDataElement> scanConversionElement = processorElement->FindNestedElementWithName("ScanConversion");
116  if (scanConversionElement == NULL){
117  LOG_ERROR("Cannot find device set in XML tree element: ScanConversion");
118  return PLUS_FAIL;
119  }
120  else
121  {
122  elementToUse = processorElement;
123  }
124  }
125  else
126  {
127  // If this cannot be found, the algorithm cannot work
128  LOG_ERROR("Cannot find device set in XML tree: Processor");
129  return PLUS_FAIL;
130  }
131  }
132  else
133  {
134  elementToUse = configRootElement;
135  }
136 
137  if (enhancer->ReadConfiguration(elementToUse) == PLUS_FAIL)
138  {
139  LOG_ERROR("Unable to read configuration from file " << inputConfigFileName);
140  return EXIT_FAILURE;
141  }
142  LOG_INFO("Reading config file finished");
143 
144  // Process the frames for the input file
145  enhancer->SetSaveIntermediateResults(saveIntermediateResults);
146  LOG_INFO("Processing frames...");
147 
148  if (enhancer->Update() == PLUS_FAIL)
149  {
150  LOG_ERROR("Processing frames failed!");
151  return EXIT_FAILURE;
152  }
153 
154  LOG_INFO("Processing frames successful");
155  if (saveIntermediateResults)
156  {
157  // Find out where to add the unique suffix for each intermediate image
158  int startInputFileNameIndex = 0;
159  if (inputFileName.find("/") != std::string::npos)
160  {
161  startInputFileNameIndex = inputFileName.rfind("/") + 1;
162  }
163  if (inputFileName.find("\\") != std::string::npos)
164  {
165  startInputFileNameIndex = inputFileName.rfind("\\") + 1;
166  }
167  int startOutputFileNameIndex = 0;
168  if (outputFileName.find("/") != std::string::npos)
169  {
170  startOutputFileNameIndex = outputFileName.rfind("/") + 1;
171  }
172  if (outputFileName.find("\\") != std::string::npos)
173  {
174  startOutputFileNameIndex = outputFileName.rfind("\\") + 1;
175  }
176 
177  // Saves the intermediate results that were recorded during the call to enhancer->Update()
178  enhancer->SetIntermediateImageFileName(
179  outputFileName.substr(0, startOutputFileNameIndex) + inputFileName.substr(startInputFileNameIndex, inputFileName.find(".") - startInputFileNameIndex));
180  enhancer->SaveAllIntermediateResultsToFile();
181  }
182 
183  if (vtkPlusSequenceIO::Write(outputFileName, enhancer->GetOutputFrames()) == PLUS_FAIL)
184  {
185  LOG_ERROR("Could not save output sequence to the file: " << outputFileName);
186  return EXIT_FAILURE;
187  }
188 
189  // Test the ability to Write to the config file
190  if (!outputConfigFileName.empty())
191  {
192  //Start the xml tree that will be written to
193  vtkSmartPointer<vtkXMLDataElement> processorWriteData = vtkSmartPointer<vtkXMLDataElement>::New();
194  processorWriteData->SetName("Processor");
195 
196  //Write to the config file
197  LOG_INFO("Writing to config file.");
198  if (enhancer->WriteConfiguration(processorWriteData) == PLUS_FAIL)
199  {
200  LOG_ERROR("Unable to write to config file.");
201  return EXIT_FAILURE;
202  }
203  if (igsioCommon::XML::PrintXML(outputConfigFileName, processorWriteData) == PLUS_FAIL)
204  {
205  LOG_ERROR("An error occured when trying to save to the config file " << outputConfigFileName);
206  return EXIT_FAILURE;
207  }
208  LOG_INFO("Writing to config file finished successfully.");
209  }
210 
211  LOG_INFO("Completed Test Successfully.");
212  return EXIT_SUCCESS;
213 }
#define PLUS_FAIL
Definition: PlusCommon.h:43
static igsioStatus Write(const std::string &filename, igsioTrackedFrame *frame, US_IMAGE_ORIENTATION orientationInFile=US_IMG_ORIENT_MF, bool useCompression=true, bool EnableImageDataWrite=true)
int main(int argc, char **argv)
static igsioStatus Read(const std::string &filename, vtkIGSIOTrackedFrameList *frameList)
static vtkIGSIOLogger * Instance()
static PlusStatus ReadDeviceSetConfigurationFromFile(vtkXMLDataElement *config, const char *filename)
Definition: PlusXmlUtils.h:23