13 #include "PlusConfigure.h" 16 #ifdef PLUS_RENDERING_ENABLED 21 #include "vtkIGSIOSequenceIO.h" 23 #include "vtkXMLDataElement.h" 24 #include "vtkXMLUtilities.h" 25 #include "vtksys/CommandLineArguments.hxx" 26 #include "vtksys/SystemTools.hxx" 36 int main(
int argc,
char** argv)
38 int numberOfFailures(0);
40 int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
42 bool printHelp(
false);
43 vtksys::CommandLineArguments args;
44 args.Initialize(argc, argv);
45 std::string inputSequenceMetafile(
"");
46 std::string inputBaselineFileName(
"");
47 std::string inputConfigFileName(
"");
49 args.AddArgument(
"--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp,
"Print this help.");
50 args.AddArgument(
"--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel,
"Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
51 args.AddArgument(
"--source-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputSequenceMetafile,
"Input sequence metafile name with path");
52 args.AddArgument(
"--baseline-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputBaselineFileName,
"Input xml baseline file name with path");
53 args.AddArgument(
"--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName,
"Input xml config file name with path");
57 std::cerr <<
"Problem parsing arguments" << std::endl;
58 std::cout <<
"Help: " << args.GetHelp() << std::endl;
64 std::cout << args.GetHelp() << std::endl;
70 if (inputSequenceMetafile.empty() || inputConfigFileName.empty() || inputBaselineFileName.empty())
72 std::cerr <<
"input-translation-sequence-metafile, input-baseline-file-name and input-config-file-name are required arguments!" << std::endl;
73 std::cout <<
"Help: " << args.GetHelp() << std::endl;
78 vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::New();
81 LOG_ERROR(
"Unable to read configuration from file " << inputConfigFileName.c_str());
91 LOG_INFO(
"Read center of rotation data from metafile...");
93 vtkSmartPointer<vtkIGSIOTrackedFrameList> trackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
94 if (vtkIGSIOSequenceIO::Read(inputSequenceMetafile, trackedFrameList) !=
PLUS_SUCCESS)
96 LOG_ERROR(
"Failed to read sequence metafile: " << inputSequenceMetafile);
100 LOG_INFO(
"Create tracked frame indices vector...");
101 std::vector<int> trackedFrameIndices(trackedFrameList->GetNumberOfTrackedFrames(), 0);
102 for (
unsigned int i = 0;
i < trackedFrameList->GetNumberOfTrackedFrames(); ++
i)
104 trackedFrameIndices[
i] =
i;
107 LOG_INFO(
"Testing image data segmentation...");
108 int numberOfSuccessfullySegmentedImages = 0;
109 patternRecognition.
RecognizePattern(trackedFrameList, error, &numberOfSuccessfullySegmentedImages);
110 LOG_INFO(
"Segmentation success rate: " << numberOfSuccessfullySegmentedImages <<
" out of " << trackedFrameList->GetNumberOfTrackedFrames()
111 <<
" (" << (100.0 * numberOfSuccessfullySegmentedImages) / trackedFrameList->GetNumberOfTrackedFrames() <<
"%)");
113 LOG_INFO(
"Testing spacing computation...");
114 vtkSmartPointer<vtkPlusSpacingCalibAlgo> spacingCalibAlgo = vtkSmartPointer<vtkPlusSpacingCalibAlgo>::New();
117 double spacing[2] = {0};
118 if (spacingCalibAlgo->GetSpacing(spacing) !=
PLUS_SUCCESS)
120 LOG_ERROR(
"Spacing calibration failed!");
125 LOG_INFO(
"Spacing: " << std::fixed << spacing[0] <<
" " << spacing[1] <<
" mm/px");
129 double spacingErrorMean(0), spacingErrorStdev(0);
130 if (spacingCalibAlgo->GetError(spacingErrorMean, spacingErrorStdev) !=
PLUS_SUCCESS)
132 LOG_ERROR(
"Failed to get spacing calibration error!");
137 LOG_INFO(
"Spacing calibration error - mean: " << std::fixed << spacingErrorMean <<
" stdev: " << spacingErrorStdev);
140 LOG_INFO(
"Testing center of rotation computation algorithm...");
141 vtkSmartPointer<vtkPlusCenterOfRotationCalibAlgo> centerOfRotationCalibAlgo = vtkSmartPointer<vtkPlusCenterOfRotationCalibAlgo>::New();
142 centerOfRotationCalibAlgo->SetInputs(trackedFrameList, trackedFrameIndices, spacing);
145 double centerOfRotationPx[2] = {0};
146 if (centerOfRotationCalibAlgo->GetCenterOfRotationPx(centerOfRotationPx) !=
PLUS_SUCCESS)
148 LOG_ERROR(
"Center of rotation calibration failed!");
153 LOG_INFO(
"Center of rotation (px): " << std::fixed << centerOfRotationPx[0] <<
" " << centerOfRotationPx[1]);
157 double errorMean(0), errorStdev(0);
158 if (centerOfRotationCalibAlgo->GetError(errorMean, errorStdev) !=
PLUS_SUCCESS)
160 LOG_ERROR(
"Failed to get center of rotation calibration error!");
165 LOG_INFO(
"Center of rotation calibration error - mean: " << std::fixed << errorMean <<
" stdev: " << errorStdev);
168 #ifdef PLUS_RENDERING_ENABLED 169 LOG_INFO(
"Testing report table generation and saving into file...");
170 vtkTable* reportTable = centerOfRotationCalibAlgo->GetReportTable();
171 if (reportTable != NULL)
175 reportTable->Dump(25);
181 LOG_ERROR(
"Failed to get report table!");
185 LOG_WARNING(
"Cannot generate table. Rendering is disabled!");
188 LOG_INFO(
"Testing HTML report generation...");
189 vtkSmartPointer<vtkPlusHTMLGenerator> htmlGenerator = vtkSmartPointer<vtkPlusHTMLGenerator>::New();
190 htmlGenerator->SetBaseFilename(
"CenterOfRotationCalibrationReport");
191 htmlGenerator->SetTitle(
"Center of Rotation Calibration Report");
192 spacingCalibAlgo->GenerateReport(htmlGenerator);
193 centerOfRotationCalibAlgo->GenerateReport(htmlGenerator);
194 htmlGenerator->SaveHtmlPageAutoFilename();
196 std::ostringstream centerOfRotationCalibAlgoStream;
197 centerOfRotationCalibAlgo->PrintSelf(centerOfRotationCalibAlgoStream, vtkIndent(0));
198 LOG_DEBUG(
"CenterOfRotationCalibAlgo::PrintSelf: " << centerOfRotationCalibAlgoStream.str());
203 const char calibResultSaveFilename[] =
"CenterOfRotationCalibrationResults.xml";
204 LOG_INFO(
"Save calibration results to XML file: " << calibResultSaveFilename);
205 std::ofstream outFile;
206 outFile.open(calibResultSaveFilename);
207 outFile <<
"<CalibrationResults>" << std::endl;
208 outFile <<
" <CenterOfRotationCalibrationResult " << std::fixed << std::setprecision(8)
209 <<
"CenterOfRotationPx=\"" << centerOfRotationPx[0] <<
" " << centerOfRotationPx[1] <<
"\" " 210 <<
"ErrorMean=\"" << errorMean <<
"\" " 211 <<
"ErrorStdev=\"" << errorStdev <<
"\" " 212 <<
" />" << std::endl;
213 outFile <<
"</CalibrationResults>" << std::endl;
219 LOG_INFO(
"Comparing result with baseline...");
221 vtkSmartPointer<vtkXMLDataElement> xmlBaseline = vtkSmartPointer<vtkXMLDataElement>::Take(vtkXMLUtilities::ReadElementFromFile(inputBaselineFileName.c_str()));
222 vtkXMLDataElement* xmlCenterOfRotationCalibrationBaseline = NULL;
223 if (xmlBaseline != NULL)
225 xmlCenterOfRotationCalibrationBaseline = xmlBaseline->FindNestedElementWithName(
"CenterOfRotationCalibrationResult");
229 LOG_ERROR(
"Failed to read baseline file!");
233 if (xmlCenterOfRotationCalibrationBaseline == NULL)
235 LOG_ERROR(
"Unable to find CenterOfRotationCalibrationResult XML data element in baseline: " << inputBaselineFileName);
241 double baseCenterOfRotationPx[2] = {0};
242 if (!xmlCenterOfRotationCalibrationBaseline->GetVectorAttribute(
"CenterOfRotationPx", 2, baseCenterOfRotationPx))
244 LOG_ERROR(
"Unable to find CenterOfRotationPx XML data element in baseline.");
249 if (fabs(baseCenterOfRotationPx[0] - centerOfRotationPx[0]) >
DOUBLE_DIFF 250 || fabs(baseCenterOfRotationPx[1] - centerOfRotationPx[1]) >
DOUBLE_DIFF)
252 LOG_ERROR(
"Center of rotation result in pixel differ from baseline: current(" << std::fixed << centerOfRotationPx[0] <<
", " << centerOfRotationPx[1]
253 <<
") base (" << baseCenterOfRotationPx[0] <<
", " << baseCenterOfRotationPx[1] <<
").");
259 double baseErrorMean = 0;
260 if (!xmlCenterOfRotationCalibrationBaseline->GetScalarAttribute(
"ErrorMean", baseErrorMean))
262 LOG_ERROR(
"Unable to find ErrorMean XML data element in baseline.");
269 LOG_ERROR(
"Center of rotation mean error differ from baseline: current(" << std::fixed << errorMean <<
") base (" << baseErrorMean <<
").");
275 double baseErrorStdev = 0;
276 if (!xmlCenterOfRotationCalibrationBaseline->GetScalarAttribute(
"ErrorStdev", baseErrorStdev))
278 LOG_ERROR(
"Unable to find ErrorStdev XML data element in baseline.");
283 if (fabs(baseErrorStdev - errorStdev) >
DOUBLE_DIFF)
285 LOG_ERROR(
"Center of rotation stdev of error differ from baseline: current(" << std::fixed << errorStdev <<
") base (" << baseErrorStdev <<
").");
292 if (numberOfFailures > 0)
294 LOG_INFO(
"Test failed!");
298 LOG_INFO(
"Test finished successfully!");
static PlusStatus WriteTableToFile(vtkTable &table, const std::string &filename)
int main(int argc, char **argv)
static vtkPlusConfig * GetInstance()
std::vector< PlusNWire > GetNWires()
static vtkIGSIOLogger * Instance()
PlusFidLineFinder * GetFidLineFinder()
PlusStatus RecognizePattern(vtkIGSIOTrackedFrameList *trackedFrameList, PatternRecognitionError &patternRecognitionError, int *numberOfSuccessfullySegmentedImages=NULL, std::vector< unsigned int > *segmentedFramesIndices=NULL)
void SetDeviceSetConfigurationData(vtkXMLDataElement *deviceSetConfigurationData)
PlusStatus ReadConfiguration(vtkXMLDataElement *rootConfigElement)
static PlusStatus ReadDeviceSetConfigurationFromFile(vtkXMLDataElement *config, const char *filename)