13 #include "PlusConfigure.h" 17 #include "vtkCallbackCommand.h" 18 #include "vtkCommand.h" 20 #include "vtkMatrix4x4.h" 22 #include "vtkIGSIOSequenceIO.h" 23 #include "vtkSmartPointer.h" 24 #include "vtkIGSIOTrackedFrameList.h" 25 #include "vtkTransform.h" 26 #include "vtkIGSIOTransformRepository.h" 27 #include "vtkIGSIOTransformRepository.h" 28 #include "vtkXMLDataElement.h" 29 #include "vtkXMLUtilities.h" 30 #include "vtksys/CommandLineArguments.hxx" 31 #include "vtksys/SystemTools.hxx" 43 int main(
int argc,
char* argv[])
46 bool printHelp(
false);
47 std::string inputCalibrationSeqMetafile;
48 std::string inputValidationSeqMetafile;
50 std::string inputConfigFileName;
51 std::string inputBaselineFileName;
52 std::string resultConfigFileName;
55 double inputTranslationErrorThreshold(LINUXTOLERANCE * 2);
56 double inputRotationErrorThreshold(LINUXTOLERANCE);
58 double inputTranslationErrorThreshold(1e-10);
59 double inputRotationErrorThreshold(1e-10);
62 int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
64 vtksys::CommandLineArguments args;
65 args.Initialize(argc, argv);
67 args.AddArgument(
"--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp,
"Print this help.");
69 args.AddArgument(
"--calibration-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputCalibrationSeqMetafile,
"Sequence metafile name of input calibration dataset.");
70 args.AddArgument(
"--validation-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputValidationSeqMetafile,
"Sequence metafile name of input validation dataset. Optional, if not specified then the calibration error will be computed from the calibration dataset.");
72 args.AddArgument(
"--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName,
"Configuration file name)");
73 args.AddArgument(
"--baseline-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputBaselineFileName,
"Name of file storing baseline calibration results. Optional.");
75 args.AddArgument(
"--translation-error-threshold", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputTranslationErrorThreshold,
"Translation error threshold in mm. Used for baseline comparison.");
76 args.AddArgument(
"--rotation-error-threshold", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputRotationErrorThreshold,
"Rotation error threshold in degrees. Used for baseline comparison.");
78 args.AddArgument(
"--output-config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &resultConfigFileName,
"Result configuration file name. Optional.");
80 args.AddArgument(
"--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel,
"Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
84 std::cerr <<
"Problem parsing arguments" << std::endl;
85 std::cout <<
"Help: " << args.GetHelp() << std::endl;
91 std::cout << args.GetHelp() << std::endl;
97 LOG_INFO(
"Read configuration file...");
100 vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::New();
103 LOG_ERROR(
"Unable to read configuration from file " << inputConfigFileName.c_str());
109 vtkSmartPointer<vtkIGSIOTransformRepository> transformRepository = vtkSmartPointer<vtkIGSIOTransformRepository>::New();
110 if (transformRepository->ReadConfiguration(configRootElement) !=
PLUS_SUCCESS)
112 LOG_ERROR(
"Failed to read CoordinateDefinitions!");
116 vtkSmartPointer<vtkPlusProbeCalibrationAlgo> freehandCalibration = vtkSmartPointer<vtkPlusProbeCalibrationAlgo>::New();
117 freehandCalibration->ReadConfiguration(configRootElement);
124 LOG_INFO(
"Read calibration sequence file...");
125 vtkSmartPointer<vtkIGSIOTrackedFrameList> calibrationTrackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
126 if (vtkIGSIOSequenceIO::Read(inputCalibrationSeqMetafile, calibrationTrackedFrameList) !=
PLUS_SUCCESS)
128 LOG_ERROR(
"Reading calibration images from '" << inputCalibrationSeqMetafile <<
"' failed!");
132 LOG_INFO(
"Segment fiducials...");
133 int numberOfSuccessfullySegmentedCalibrationImages = 0;
134 if (patternRecognition.
RecognizePattern(calibrationTrackedFrameList, error, &numberOfSuccessfullySegmentedCalibrationImages) !=
PLUS_SUCCESS)
136 LOG_ERROR(
"Error occured during segmentation of calibration images!");
140 LOG_INFO(
"Segmentation success rate of calibration images: " << numberOfSuccessfullySegmentedCalibrationImages <<
" out of " << calibrationTrackedFrameList->GetNumberOfTrackedFrames());
142 if (!inputValidationSeqMetafile.empty())
145 LOG_INFO(
"Read validation sequence file...");
146 vtkSmartPointer<vtkIGSIOTrackedFrameList> validationTrackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
147 if (vtkIGSIOSequenceIO::Read(inputValidationSeqMetafile, validationTrackedFrameList) !=
PLUS_SUCCESS)
149 LOG_ERROR(
"Reading validation images from '" << inputValidationSeqMetafile <<
"' failed!");
152 LOG_INFO(
"Segment fiducials...");
153 int numberOfSuccessfullySegmentedValidationImages = 0;
154 if (patternRecognition.
RecognizePattern(validationTrackedFrameList, error, &numberOfSuccessfullySegmentedValidationImages) !=
PLUS_SUCCESS)
156 LOG_ERROR(
"Error occured during segmentation of validation images!");
160 LOG_INFO(
"Segmentation success rate of validation images: " << numberOfSuccessfullySegmentedValidationImages <<
" out of " << validationTrackedFrameList->GetNumberOfTrackedFrames());
163 LOG_INFO(
"Calibrate...");
164 if (freehandCalibration->Calibrate(validationTrackedFrameList, calibrationTrackedFrameList, transformRepository, patternRecognition.
GetFidLineFinder()->
GetNWires()) !=
PLUS_SUCCESS)
166 LOG_ERROR(
"Calibration failed!");
173 LOG_INFO(
"Validation data set is not provided, therefore error is computed from the calibration data set");
175 LOG_INFO(
"Calibrate...");
176 if (freehandCalibration->Calibrate(calibrationTrackedFrameList, calibrationTrackedFrameList, transformRepository, patternRecognition.
GetFidLineFinder()->
GetNWires()) !=
PLUS_SUCCESS)
178 LOG_ERROR(
"Calibration failed!");
184 if (!resultConfigFileName.empty())
186 LOG_INFO(
"Save results to: " << resultConfigFileName);
189 LOG_ERROR(
"Unable to save freehand calibration result in configuration XML tree!");
196 if (!inputBaselineFileName.empty())
198 LOG_INFO(
"Compare with baseline: " << inputBaselineFileName);
204 LOG_ERROR(
"Comparison of calibration data to baseline failed");
205 std::cout <<
"Exit failure!!!" << std::endl;
211 std::cout <<
"Calibration has been completed successfully" << std::endl;
220 int numberOfFailures = 0;
223 double absoluteErrorTolerance = LINUXTOLERANCE * 2;
225 double absoluteErrorTolerance = 50;
228 vtkSmartPointer<vtkXMLDataElement> baselineRootElem = vtkSmartPointer<vtkXMLDataElement>::Take(
229 vtkXMLUtilities::ReadElementFromFile(baselineFileName));
230 vtkSmartPointer<vtkXMLDataElement> currentRootElem = vtkSmartPointer<vtkXMLDataElement>::Take(
231 vtkXMLUtilities::ReadElementFromFile(currentResultFileName));
234 if (baselineRootElem == NULL)
236 LOG_ERROR(
"Reading baseline data file failed: " << baselineFileName);
237 return ++numberOfFailures;
239 if (currentRootElem == NULL)
241 LOG_ERROR(
"Reading newly generated data file failed: " << currentResultFileName);
242 return ++numberOfFailures;
247 vtkXMLDataElement* calibrationResultsBaseline = baselineRootElem->FindNestedElementWithName(
"CalibrationResults");
248 vtkXMLDataElement* calibrationResults = currentRootElem->FindNestedElementWithName(
"CalibrationResults");
250 if (calibrationResultsBaseline == NULL)
252 LOG_ERROR(
"Reading baseline CalibrationResults tag failed: " << baselineFileName);
253 return ++numberOfFailures;
256 if (calibrationResults == NULL)
258 LOG_ERROR(
"Reading current CalibrationResults tag failed: " << currentResultFileName);
259 return ++numberOfFailures;
264 vtkXMLDataElement* transformBaseline = calibrationResultsBaseline->FindNestedElementWithName(
"Transform");
265 vtkXMLDataElement* transform = calibrationResults->FindNestedElementWithName(
"Transform");
267 if (transformBaseline == NULL)
269 LOG_ERROR(
"Reading baseline Transform tag failed: " << baselineFileName);
270 return ++numberOfFailures;
273 if (transform == NULL)
275 LOG_ERROR(
"Reading current Transform tag failed: " << currentResultFileName);
276 return ++numberOfFailures;
280 double blTransformImageToProbe[16];
281 double cTransformImageToProbe[16];
282 const char* blFrom = transformBaseline->GetAttribute(
"From");
283 const char* cFrom = transform->GetAttribute(
"From");
284 const char* blTo = transformBaseline->GetAttribute(
"To");
285 const char* cTo = transform->GetAttribute(
"To");
287 if (STRCASECMP(blFrom,
"Image") != 0 || STRCASECMP(blTo,
"Probe"))
289 LOG_ERROR(
"Baseline From and To tags are invalid!");
292 else if (STRCASECMP(cFrom,
"Image") != 0 || STRCASECMP(cTo,
"Probe"))
294 LOG_ERROR(
"Current From and To tags are invalid!");
297 else if (!transformBaseline->GetVectorAttribute(
"Matrix", 16, blTransformImageToProbe))
299 LOG_ERROR(
"Baseline Matrix tag is missing");
302 else if (!transform->GetVectorAttribute(
"Matrix", 16, cTransformImageToProbe))
304 LOG_ERROR(
"Current Matrix tag is missing");
309 vtkSmartPointer<vtkMatrix4x4> baseTransMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
310 vtkSmartPointer<vtkMatrix4x4> currentTransMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
311 for (
int i = 0;
i < 4;
i++)
313 for (
int j = 0; j < 4; j++)
315 baseTransMatrix->SetElement(
i, j, blTransformImageToProbe[4 *
i + j]);
316 currentTransMatrix->SetElement(
i, j, cTransformImageToProbe[4 *
i + j]);
320 double translationError = igsioMath::GetPositionDifference(baseTransMatrix, currentTransMatrix);
321 if (translationError > translationErrorThreshold)
323 LOG_ERROR(
"TransformImageToProbe translation difference (compared to baseline) is higher than expected: " << translationError <<
" mm (threshold: " << translationErrorThreshold <<
" mm). ");
327 double rotationError = igsioMath::GetOrientationDifference(baseTransMatrix, currentTransMatrix);
328 if (rotationError > rotationErrorThreshold)
330 LOG_ERROR(
"TransformImageToProbe rotation difference (compared to baseline) is higher than expected: " << rotationError <<
" degree (threshold: " << rotationErrorThreshold <<
" degree). ");
340 vtkXMLDataElement* errorReportBaseline = baselineRootElem->FindNestedElementWithName(
"ErrorReport");
341 vtkXMLDataElement* errorReport = currentRootElem->FindNestedElementWithName(
"ErrorReport");
343 if (errorReportBaseline == NULL)
345 LOG_ERROR(
"Reading baseline ErrorReports tag failed: " << baselineFileName);
346 return ++numberOfFailures;
349 if (errorReport == NULL)
351 LOG_ERROR(
"Reading current ErrorReports tag failed: " << currentResultFileName);
352 return ++numberOfFailures;
357 vtkXMLDataElement* reprojectionError3DStatisticsBaseline = errorReportBaseline->FindNestedElementWithName(
"ReprojectionError3DStatistics");
358 vtkXMLDataElement* reprojectionError3DStatistics = errorReport->FindNestedElementWithName(
"ReprojectionError3DStatistics");
360 if (reprojectionError3DStatisticsBaseline == NULL || reprojectionError3DStatistics == NULL)
362 LOG_ERROR(
"Reading ReprojectionError3DStatistics tag failed");
363 return ++numberOfFailures;
366 double blReprojectionError3DValidationMeanMm = 0.0;
367 double blReprojectionError3DValidationStdDevMm = 0.0;
368 if (! reprojectionError3DStatisticsBaseline->GetScalarAttribute(
"ValidationMeanMm", blReprojectionError3DValidationMeanMm)
369 || ! reprojectionError3DStatisticsBaseline->GetScalarAttribute(
"ValidationStdDevMm", blReprojectionError3DValidationStdDevMm))
371 LOG_ERROR(
"Reading baseline validation ReprojectionError3DStatistics statistics failed: " << baselineFileName);
372 return ++numberOfFailures;
375 double cReprojectionError3DValidationMeanMm = 0.0;
376 double cReprojectionError3DValidationStdDevMm = 0.0;
377 if (! reprojectionError3DStatistics->GetScalarAttribute(
"ValidationMeanMm", cReprojectionError3DValidationMeanMm)
378 || ! reprojectionError3DStatistics->GetScalarAttribute(
"ValidationStdDevMm", cReprojectionError3DValidationStdDevMm))
380 LOG_ERROR(
"Reading current validation ReprojectionError3DStatistics statistics failed: " << currentResultFileName);
381 return ++numberOfFailures;
384 double ratioValidationMean = 1.0 * blReprojectionError3DValidationMeanMm / cReprojectionError3DValidationMeanMm;
385 double absoluteErrorValidationMean = fabs(blReprojectionError3DValidationMeanMm - cReprojectionError3DValidationMeanMm);
386 if ((ratioValidationMean > 1 +
ERROR_THRESHOLD || ratioValidationMean < 1 -
ERROR_THRESHOLD) && (absoluteErrorValidationMean > absoluteErrorTolerance))
388 LOG_ERROR(
"ReprojectionError3DStatistics/ValidationMeanMm mismatch: current=" << cReprojectionError3DValidationMeanMm <<
", baseline=" << blReprojectionError3DValidationMeanMm);
389 return ++numberOfFailures;
391 double ratioValidationStdDev = 1.0 * blReprojectionError3DValidationStdDevMm / cReprojectionError3DValidationStdDevMm;
392 double absoluteErrorValidationStdDev = fabs(blReprojectionError3DValidationStdDevMm - cReprojectionError3DValidationStdDevMm);
393 if ((ratioValidationStdDev > 1 +
ERROR_THRESHOLD || ratioValidationStdDev < 1 -
ERROR_THRESHOLD) && (absoluteErrorValidationStdDev > absoluteErrorTolerance))
395 LOG_ERROR(
"ReprojectionError3DStatistics/ValidationStdDevMm mismatch: current=" << cReprojectionError3DValidationStdDevMm <<
", baseline=" << blReprojectionError3DValidationStdDevMm);
396 return ++numberOfFailures;
399 double blReprojectionError3DCalibrationMeanMm = 0.0;
400 double blReprojectionError3DCalibrationStdDevMm = 0.0;
401 if (! reprojectionError3DStatisticsBaseline->GetScalarAttribute(
"CalibrationMeanMm", blReprojectionError3DCalibrationMeanMm)
402 || ! reprojectionError3DStatisticsBaseline->GetScalarAttribute(
"CalibrationStdDevMm", blReprojectionError3DCalibrationStdDevMm))
404 LOG_ERROR(
"Reading baseline calibration ReprojectionError3DStatistics statistics failed: " << baselineFileName);
405 return ++numberOfFailures;
408 double cReprojectionError3DCalibrationMeanMm = 0.0;
409 double cReprojectionError3DCalibrationStdDevMm = 0.0;
410 if (! reprojectionError3DStatistics->GetScalarAttribute(
"CalibrationMeanMm", cReprojectionError3DCalibrationMeanMm)
411 || ! reprojectionError3DStatistics->GetScalarAttribute(
"CalibrationStdDevMm", cReprojectionError3DCalibrationStdDevMm))
413 LOG_ERROR(
"Reading current calibration ReprojectionError3DStatistics statistics failed: " << currentResultFileName);
414 return ++numberOfFailures;
417 double ratioCalibrationMean = 1.0 * blReprojectionError3DCalibrationMeanMm / cReprojectionError3DCalibrationMeanMm;
418 double absoluteErrorCalibrationMean = fabs(blReprojectionError3DCalibrationMeanMm - cReprojectionError3DCalibrationMeanMm);
419 if ((ratioCalibrationMean > 1 +
ERROR_THRESHOLD || ratioCalibrationMean < 1 -
ERROR_THRESHOLD) && (absoluteErrorCalibrationMean > absoluteErrorTolerance))
421 LOG_ERROR(
"ReprojectionError3DStatistics/CalibrationMeanMm mismatch: current=" << cReprojectionError3DCalibrationMeanMm <<
", baseline=" << blReprojectionError3DCalibrationMeanMm);
422 return ++numberOfFailures;
424 double ratioCalibrationStdDev = 1.0 * blReprojectionError3DCalibrationStdDevMm / cReprojectionError3DCalibrationStdDevMm;
425 double absoluteErrorCalibrationStdDev = fabs(blReprojectionError3DCalibrationStdDevMm - cReprojectionError3DCalibrationStdDevMm);
426 if ((ratioCalibrationStdDev > 1 +
ERROR_THRESHOLD || ratioCalibrationStdDev < 1 -
ERROR_THRESHOLD) && (absoluteErrorCalibrationStdDev > absoluteErrorTolerance))
428 LOG_ERROR(
"ReprojectionError3DStatistics/CalibrationStdDevMm mismatch: current=" << cReprojectionError3DCalibrationStdDevMm <<
", baseline=" << blReprojectionError3DCalibrationStdDevMm);
429 return ++numberOfFailures;
435 vtkXMLDataElement* reprojectionError2DStatisticsBaseline = errorReportBaseline->FindNestedElementWithName(
"ReprojectionError2DStatistics");
436 vtkXMLDataElement* reprojectionError2DStatistics = errorReport->FindNestedElementWithName(
"ReprojectionError2DStatistics");
438 if (reprojectionError2DStatisticsBaseline == NULL || reprojectionError2DStatistics == NULL)
440 LOG_ERROR(
"Reading ReprojectionError2DStatistics tag failed");
441 return ++numberOfFailures;
445 for (
int wireIndex = 0; wireIndex < reprojectionError2DStatisticsBaseline->GetNumberOfNestedElements(); ++wireIndex)
447 vtkXMLDataElement* wireBaseline = reprojectionError2DStatisticsBaseline->GetNestedElement(wireIndex);
448 vtkXMLDataElement* wire = reprojectionError2DStatistics->GetNestedElement(wireIndex);
449 if (!wireBaseline || !wire || STRCASECMP(wireBaseline->GetName(),
"Wire") != 0 || STRCASECMP(wire->GetName(),
"Wire") != 0)
451 LOG_ERROR(
"Invalid Wire element in ReprojectionError2DStatistics");
456 if (STRCASECMP(wireBaseline->GetAttribute(
"Name"), wire->GetAttribute(
"Name")) != 0)
458 LOG_ERROR(
"Wire name mismatch: " << wireBaseline->GetAttribute(
"Name") <<
" <> " << wire->GetAttribute(
"Name"));
463 double blValidationMeanPx[2];
464 double blValidationStdDevPx[2];
465 if (! wireBaseline->GetVectorAttribute(
"ValidationMeanPx", 2, blValidationMeanPx)
466 || ! wireBaseline->GetVectorAttribute(
"ValidationStdDevPx", 2, blValidationStdDevPx))
468 LOG_ERROR(
"Reading baseline validation ReprojectionError2DStatistics failed for wire " << wireIndex);
473 double cValidationMeanPx[2];
474 double cValidationStdDevPx[2];
475 if (! wire->GetVectorAttribute(
"ValidationMeanPx", 2, cValidationMeanPx)
476 || ! wire->GetVectorAttribute(
"ValidationStdDevPx", 2, cValidationStdDevPx))
478 LOG_ERROR(
"Reading current validation ReprojectionError2DStatistics failed for wire " << wireIndex);
483 for (
int i = 0;
i < 2;
i++)
485 double ratioMean = 1.0 * blValidationMeanPx[
i] / cValidationMeanPx[
i];
486 double absoluteErrorMean = fabs(blValidationMeanPx[
i] - cValidationMeanPx[
i]);
489 LOG_ERROR(
"ValidationMeanPx mismatch for wire " << wireIndex <<
": current=" << cValidationMeanPx[
i] <<
", baseline=" << blValidationMeanPx[
i]);
490 return ++numberOfFailures;
492 double ratioStdDev = 1.0 * blValidationStdDevPx[
i] / cValidationStdDevPx[
i];
493 double absoluteErrorStdDev = fabs(blValidationStdDevPx[
i] - cValidationStdDevPx[
i]);
496 LOG_ERROR(
"ValidationStdDevPx mismatch for wire " << wireIndex <<
": current=" << cValidationStdDevPx[
i] <<
", baseline=" << blValidationStdDevPx[
i]);
497 return ++numberOfFailures;
501 double blCalibrationMeanPx[2];
502 double blCalibrationStdDevPx[2];
503 if (! wireBaseline->GetVectorAttribute(
"CalibrationMeanPx", 2, blCalibrationMeanPx)
504 || ! wireBaseline->GetVectorAttribute(
"CalibrationStdDevPx", 2, blCalibrationStdDevPx))
506 LOG_ERROR(
"Reading baseline calibration ReprojectionError2DStatistics failed for wire " << wireIndex);
511 double cCalibrationMeanPx[2];
512 double cCalibrationStdDevPx[2];
513 if (! wire->GetVectorAttribute(
"CalibrationMeanPx", 2, cCalibrationMeanPx)
514 || ! wire->GetVectorAttribute(
"CalibrationStdDevPx", 2, cCalibrationStdDevPx))
516 LOG_ERROR(
"Reading current calibration ReprojectionError2DStatistics failed for wire " << wireIndex);
521 for (
int i = 0;
i < 2;
i++)
523 double ratioMean = 1.0 * blCalibrationMeanPx[
i] / cCalibrationMeanPx[
i];
524 double absoluteErrorMean = fabs(blCalibrationMeanPx[
i] - cCalibrationMeanPx[
i]);
527 LOG_ERROR(
"CalibrationMeanPx mismatch for wire " << wireIndex <<
": current=" << cCalibrationMeanPx[
i] <<
", baseline=" << blCalibrationMeanPx[
i]);
528 return ++numberOfFailures;
530 double ratioStdDev = 1.0 * blCalibrationStdDevPx[
i] / cCalibrationStdDevPx[
i];
531 double absoluteErrorStdDev = fabs(blCalibrationStdDevPx[
i] - cCalibrationStdDevPx[
i]);
534 LOG_ERROR(
"CalibrationStdDevPx mismatch for wire " << wireIndex <<
": current=" << cCalibrationStdDevPx[
i] <<
", baseline=" << blCalibrationStdDevPx[
i]);
535 return ++numberOfFailures;
543 vtkXMLDataElement* validationDataBaseline = errorReportBaseline->FindNestedElementWithName(
"ValidationData");
544 vtkXMLDataElement* validationData = errorReport->FindNestedElementWithName(
"ValidationData");
546 if (validationDataBaseline == NULL || validationData == NULL)
548 LOG_ERROR(
"Reading ValidationData tag failed");
549 return ++numberOfFailures;
552 for (
int frameIndex = 0; frameIndex < validationDataBaseline->GetNumberOfNestedElements(); ++frameIndex)
554 vtkXMLDataElement* frameBaseline = validationDataBaseline->GetNestedElement(frameIndex);
555 vtkXMLDataElement* frame = validationData->GetNestedElement(frameIndex);
556 if (!frameBaseline || !frame || STRCASECMP(frameBaseline->GetName(),
"Frame") != 0 || STRCASECMP(frame->GetName(),
"Frame") != 0)
558 LOG_ERROR(
"Invalid Frame element #" << frameIndex);
563 const char* segmentationStatusBaseline = frameBaseline->GetAttribute(
"SegmentationStatus");
564 const char* segmentationStatus = frame->GetAttribute(
"SegmentationStatus");
566 if (STRCASECMP(segmentationStatusBaseline, segmentationStatus) != 0)
568 LOG_ERROR(
"SegmentationStatus mismatch in Frame #" << frameIndex <<
": current=" << segmentationStatus <<
", baseline=" << segmentationStatusBaseline);
573 if (igsioCommon::IsEqualInsensitive(segmentationStatusBaseline,
"OK"))
577 vtkXMLDataElement* segmentedPointsBaseline = frameBaseline->FindNestedElementWithName(
"SegmentedPoints");
578 vtkXMLDataElement* segmentedPoints = frame->FindNestedElementWithName(
"SegmentedPoints");
580 if (segmentedPointsBaseline == NULL || segmentedPoints == NULL)
582 LOG_ERROR(
"Reading SegmentedPoints tag in Frame #" << frameIndex <<
"failed");
588 for (
int pointIndex = 0; pointIndex < segmentedPointsBaseline->GetNumberOfNestedElements(); ++pointIndex)
590 vtkXMLDataElement* pointBaseline = segmentedPointsBaseline->GetNestedElement(pointIndex);
591 vtkXMLDataElement* point = segmentedPoints->GetNestedElement(pointIndex);
592 if (!pointBaseline || !point || STRCASECMP(pointBaseline->GetName(),
"Point") != 0 || STRCASECMP(point->GetName(),
"Point") != 0)
594 LOG_ERROR(
"Invalid Point element in Frame #" << frameIndex);
599 if (STRCASECMP(pointBaseline->GetAttribute(
"WireName"), point->GetAttribute(
"WireName")) != 0)
601 LOG_ERROR(
"Wire name mismatch: " << pointBaseline->GetAttribute(
"Name") <<
" <> " << point->GetAttribute(
"Name"));
606 double blPosition[3];
608 if (! pointBaseline->GetVectorAttribute(
"Position", 3, blPosition)
609 || ! point->GetVectorAttribute(
"Position", 3, cPosition))
611 LOG_ERROR(
"Reading Position of Point #" << pointIndex <<
" in Frame #" << frameIndex <<
"failed!");
616 for (
int i = 0;
i < 3;
i++)
618 double ratio = 1.0 * blPosition[
i] / cPosition[
i];
619 double absoluteError = fabs(blPosition[
i] - cPosition[
i]);
622 LOG_ERROR(
"Position component " <<
i <<
" mismatch: current=" << cPosition[
i] <<
", baseline=" << blPosition[
i] <<
" (point " << pointIndex <<
" in frame " << frameIndex <<
")");
632 vtkXMLDataElement* reprojectionError3DListBaseline = frameBaseline->FindNestedElementWithName(
"ReprojectionError3DList");
633 vtkXMLDataElement* reprojectionError3DList = frame->FindNestedElementWithName(
"ReprojectionError3DList");
635 if (reprojectionError3DListBaseline == NULL || reprojectionError3DList == NULL)
637 LOG_ERROR(
"Reading ReprojectionError3DList tag in Frame #" << frameIndex <<
" failed");
643 for (
int reprojectionError3DIndex = 0; reprojectionError3DIndex < reprojectionError3DListBaseline->GetNumberOfNestedElements(); ++reprojectionError3DIndex)
645 vtkXMLDataElement* reprojectionError3DBaseline = reprojectionError3DListBaseline->GetNestedElement(reprojectionError3DIndex);
646 vtkXMLDataElement* reprojectionError3D = reprojectionError3DList->GetNestedElement(reprojectionError3DIndex);
647 if (!reprojectionError3DBaseline || !reprojectionError3D || STRCASECMP(reprojectionError3DBaseline->GetName(),
"ReprojectionError3D") != 0 || STRCASECMP(reprojectionError3D->GetName(),
"ReprojectionError3D") != 0)
649 LOG_ERROR(
"Invalid ReprojectionError3D element in Frame #" << frameIndex);
654 if (STRCASECMP(reprojectionError3DBaseline->GetAttribute(
"WireName"), reprojectionError3D->GetAttribute(
"WireName")) != 0)
656 LOG_ERROR(
"Wire name mismatch: " << reprojectionError3DBaseline->GetAttribute(
"Name") <<
" <> " << reprojectionError3D->GetAttribute(
"Name"));
661 double blErrorMm = 0.0;
662 double cErrorMm = 0.0;
663 if (! reprojectionError3DBaseline->GetScalarAttribute(
"ErrorMm", blErrorMm)
664 || ! reprojectionError3D->GetScalarAttribute(
"ErrorMm", cErrorMm))
666 LOG_ERROR(
"Reading ErrorMm in ReprojectionError3D #" << reprojectionError3DIndex <<
" in Frame #" << frameIndex <<
"failed!");
671 double ratio = 1.0 * blErrorMm / cErrorMm;
672 double absoluteError = fabs(blErrorMm - cErrorMm);
673 if (ratio > 1 +
ERROR_THRESHOLD || ratio < 1 - ERROR_THRESHOLD || absoluteError > absoluteErrorTolerance)
675 LOG_ERROR(
"ErrorMm mismatch: current=" << cErrorMm <<
", baseline=" << blErrorMm <<
" (error index " << reprojectionError3DIndex <<
" in frame " << frameIndex <<
")");
684 vtkXMLDataElement* reprojectionError2DListBaseline = frameBaseline->FindNestedElementWithName(
"ReprojectionError2DList");
685 vtkXMLDataElement* reprojectionError2DList = frame->FindNestedElementWithName(
"ReprojectionError2DList");
687 if (reprojectionError2DListBaseline == NULL || reprojectionError2DList == NULL)
689 LOG_ERROR(
"Reading ReprojectionError2DList tag in Frame #" << frameIndex <<
"failed");
695 for (
int reprojectionError2DIndex = 0; reprojectionError2DIndex < reprojectionError2DListBaseline->GetNumberOfNestedElements(); ++reprojectionError2DIndex)
697 vtkXMLDataElement* reprojectionError2DBaseline = reprojectionError2DListBaseline->GetNestedElement(reprojectionError2DIndex);
698 vtkXMLDataElement* reprojectionError2D = reprojectionError2DList->GetNestedElement(reprojectionError2DIndex);
699 if (!reprojectionError2DBaseline || !reprojectionError2D || STRCASECMP(reprojectionError2DBaseline->GetName(),
"ReprojectionError2D") != 0 || STRCASECMP(reprojectionError2D->GetName(),
"ReprojectionError2D") != 0)
701 LOG_ERROR(
"Invalid ReprojectionError2D element in Frame #" << frameIndex);
706 if (STRCASECMP(reprojectionError2DBaseline->GetAttribute(
"WireName"), reprojectionError2D->GetAttribute(
"WireName")) != 0)
708 LOG_ERROR(
"Wire name mismatch: " << reprojectionError2DBaseline->GetAttribute(
"Name") <<
" <> " << reprojectionError2D->GetAttribute(
"Name"));
715 if (! reprojectionError2DBaseline->GetVectorAttribute(
"ErrorPx", 2, blErrorPx)
716 || ! reprojectionError2D->GetVectorAttribute(
"ErrorPx", 2, cErrorPx))
718 LOG_ERROR(
"Reading ErrorPx of reprojectionError2D #" << reprojectionError2DIndex <<
" in Frame #" << frameIndex <<
"failed!");
723 for (
int i = 0;
i < 2;
i++)
725 double ratio = 1.0 * blErrorPx[
i] / cErrorPx[
i];
726 double absoluteError = fabs(blErrorPx[
i] - cErrorPx[
i]);
729 LOG_ERROR(
"ErrorPx component " <<
i <<
" mismatch: current=" << cErrorPx[
i] <<
", baseline=" << blErrorPx[
i] <<
" (error index " << reprojectionError2DIndex <<
" in frame " << frameIndex <<
")");
742 vtkXMLDataElement* calibrationDataBaseline = errorReportBaseline->FindNestedElementWithName(
"CalibrationData");
743 vtkXMLDataElement* calibrationData = errorReport->FindNestedElementWithName(
"CalibrationData");
745 if (calibrationDataBaseline == NULL || calibrationData == NULL)
747 LOG_ERROR(
"Reading CalibrationData tag failed");
748 return ++numberOfFailures;
751 for (
int frameIndex = 0; frameIndex < calibrationDataBaseline->GetNumberOfNestedElements(); ++frameIndex)
753 vtkXMLDataElement* frameBaseline = calibrationDataBaseline->GetNestedElement(frameIndex);
754 vtkXMLDataElement* frame = calibrationData->GetNestedElement(frameIndex);
755 if (!frameBaseline || !frame || STRCASECMP(frameBaseline->GetName(),
"Frame") != 0 || STRCASECMP(frame->GetName(),
"Frame") != 0)
757 LOG_ERROR(
"Invalid Frame element #" << frameIndex);
762 const char* segmentationStatusBaseline = frameBaseline->GetAttribute(
"SegmentationStatus");
763 const char* segmentationStatus = frame->GetAttribute(
"SegmentationStatus");
765 if (STRCASECMP(segmentationStatusBaseline, segmentationStatus) != 0)
767 LOG_ERROR(
"SegmentationStatus mismatch in Frame #" << frameIndex <<
": current=" << segmentationStatus <<
", baseline=" << segmentationStatusBaseline);
772 if (igsioCommon::IsEqualInsensitive(segmentationStatusBaseline,
"OK"))
776 vtkXMLDataElement* segmentedPointsBaseline = frameBaseline->FindNestedElementWithName(
"SegmentedPoints");
777 vtkXMLDataElement* segmentedPoints = frame->FindNestedElementWithName(
"SegmentedPoints");
779 if (segmentedPointsBaseline == NULL || segmentedPoints == NULL)
781 LOG_ERROR(
"Reading SegmentedPoints tag in Frame #" << frameIndex <<
"failed");
787 for (
int pointIndex = 0; pointIndex < segmentedPointsBaseline->GetNumberOfNestedElements(); ++pointIndex)
789 vtkXMLDataElement* pointBaseline = segmentedPointsBaseline->GetNestedElement(pointIndex);
790 vtkXMLDataElement* point = segmentedPoints->GetNestedElement(pointIndex);
791 if (!pointBaseline || !point || STRCASECMP(pointBaseline->GetName(),
"Point") != 0 || STRCASECMP(point->GetName(),
"Point") != 0)
793 LOG_ERROR(
"Invalid Point element in Frame #" << frameIndex);
798 if (STRCASECMP(pointBaseline->GetAttribute(
"WireName"), point->GetAttribute(
"WireName")) != 0)
800 LOG_ERROR(
"Wire name mismatch: " << pointBaseline->GetAttribute(
"Name") <<
" <> " << point->GetAttribute(
"Name"));
805 double blPosition[3];
807 if (! pointBaseline->GetVectorAttribute(
"Position", 3, blPosition)
808 || ! point->GetVectorAttribute(
"Position", 3, cPosition))
810 LOG_ERROR(
"Reading Position of Point #" << pointIndex <<
" in Frame #" << frameIndex <<
"failed!");
815 for (
int i = 0;
i < 3;
i++)
817 double ratio = 1.0 * blPosition[
i] / cPosition[
i];
818 double absoluteError = fabs(blPosition[
i] - cPosition[
i]);
821 LOG_ERROR(
"Position component " <<
i <<
" mismatch: current=" << cPosition[
i] <<
", baseline=" << blPosition[
i] <<
" (point " << pointIndex <<
" in frame " << frameIndex <<
")");
831 vtkXMLDataElement* middleWiresBaseline = frameBaseline->FindNestedElementWithName(
"MiddleWires");
832 vtkXMLDataElement* middleWires = frame->FindNestedElementWithName(
"MiddleWires");
834 if (middleWiresBaseline == NULL || middleWires == NULL)
836 LOG_ERROR(
"Reading MiddleWires tag in Frame #" << frameIndex <<
"failed");
842 for (
int middleWireIndex = 0; middleWireIndex < middleWiresBaseline->GetNumberOfNestedElements(); ++middleWireIndex)
844 vtkXMLDataElement* middleWireBaseline = middleWiresBaseline->GetNestedElement(middleWireIndex);
845 vtkXMLDataElement* middleWire = middleWires->GetNestedElement(middleWireIndex);
846 if (!middleWireBaseline || !middleWire || STRCASECMP(middleWireBaseline->GetName(),
"MiddleWire") != 0 || STRCASECMP(middleWire->GetName(),
"MiddleWire") != 0)
848 LOG_ERROR(
"Invalid MiddleWire element in Frame #" << frameIndex);
853 double blPositionInImageFrame[3];
854 double cPositionInImageFrame[3];
855 if (! middleWireBaseline->GetVectorAttribute(
"PositionInImageFrame", 3, blPositionInImageFrame)
856 || ! middleWire->GetVectorAttribute(
"PositionInImageFrame", 3, cPositionInImageFrame))
858 LOG_ERROR(
"Reading PositionInImageFrame of MiddleWire #" << middleWireIndex <<
" in Frame #" << frameIndex <<
"failed!");
863 for (
int i = 0;
i < 3;
i++)
865 double ratio = 1.0 * blPositionInImageFrame[
i] / cPositionInImageFrame[
i];
866 double absoluteError = fabs(blPositionInImageFrame[
i] - cPositionInImageFrame[
i]);
869 LOG_ERROR(
"PositionInImageFrame component " <<
i <<
" mismatch: current=" << cPositionInImageFrame[
i] <<
", baseline=" << blPositionInImageFrame[
i] <<
" (middleWire " << middleWireIndex <<
" in frame " << frameIndex <<
")");
875 double blPositionInProbeFrame[3];
876 double cPositionInProbeFrame[3];
877 if (! middleWireBaseline->GetVectorAttribute(
"PositionInProbeFrame", 3, blPositionInProbeFrame)
878 || ! middleWire->GetVectorAttribute(
"PositionInProbeFrame", 3, cPositionInProbeFrame))
880 LOG_ERROR(
"Reading PositionInProbeFrame of MiddleWire #" << middleWireIndex <<
" in Frame #" << frameIndex <<
"failed!");
885 for (
int i = 0;
i < 3;
i++)
887 double ratio = 1.0 * blPositionInProbeFrame[
i] / cPositionInProbeFrame[
i];
888 double absoluteError = fabs(blPositionInProbeFrame[
i] - cPositionInProbeFrame[
i]);
891 LOG_ERROR(
"PositionInProbeFrame component " <<
i <<
" mismatch: current=" << cPositionInProbeFrame[
i] <<
", baseline=" << blPositionInProbeFrame[
i] <<
" (middleWire " << middleWireIndex <<
" in frame " << frameIndex <<
")");
901 vtkXMLDataElement* reprojectionError3DListBaseline = frameBaseline->FindNestedElementWithName(
"ReprojectionError3DList");
902 vtkXMLDataElement* reprojectionError3DList = frame->FindNestedElementWithName(
"ReprojectionError3DList");
904 if (reprojectionError3DListBaseline == NULL || reprojectionError3DList == NULL)
906 LOG_ERROR(
"Reading ReprojectionError3DList tag in Frame #" << frameIndex <<
" failed");
912 for (
int reprojectionError3DIndex = 0; reprojectionError3DIndex < reprojectionError3DListBaseline->GetNumberOfNestedElements(); ++reprojectionError3DIndex)
914 vtkXMLDataElement* reprojectionError3DBaseline = reprojectionError3DListBaseline->GetNestedElement(reprojectionError3DIndex);
915 vtkXMLDataElement* reprojectionError3D = reprojectionError3DList->GetNestedElement(reprojectionError3DIndex);
916 if (!reprojectionError3DBaseline || !reprojectionError3D || STRCASECMP(reprojectionError3DBaseline->GetName(),
"ReprojectionError3D") != 0 || STRCASECMP(reprojectionError3D->GetName(),
"ReprojectionError3D") != 0)
918 LOG_ERROR(
"Invalid ReprojectionError3D element in Frame #" << frameIndex);
923 if (STRCASECMP(reprojectionError3DBaseline->GetAttribute(
"WireName"), reprojectionError3D->GetAttribute(
"WireName")) != 0)
925 LOG_ERROR(
"Wire name mismatch: " << reprojectionError3DBaseline->GetAttribute(
"Name") <<
" <> " << reprojectionError3D->GetAttribute(
"Name"));
930 double blErrorMm = 0.0;
931 double cErrorMm = 0.0;
932 if (! reprojectionError3DBaseline->GetScalarAttribute(
"ErrorMm", blErrorMm)
933 || ! reprojectionError3D->GetScalarAttribute(
"ErrorMm", cErrorMm))
935 LOG_ERROR(
"Reading ErrorMm in ReprojectionError3D #" << reprojectionError3DIndex <<
" in Frame #" << frameIndex <<
"failed!");
940 double ratio = 1.0 * blErrorMm / cErrorMm;
941 double absoluteError = fabs(blErrorMm - cErrorMm);
944 LOG_ERROR(
"ErrorMm mismatch: current=" << cErrorMm <<
", baseline=" << blErrorMm <<
" (error index " << reprojectionError3DIndex <<
" in frame " << frameIndex <<
")");
953 vtkXMLDataElement* reprojectionError2DListBaseline = frameBaseline->FindNestedElementWithName(
"ReprojectionError2DList");
954 vtkXMLDataElement* reprojectionError2DList = frame->FindNestedElementWithName(
"ReprojectionError2DList");
956 if (reprojectionError2DListBaseline == NULL || reprojectionError2DList == NULL)
958 LOG_ERROR(
"Reading ReprojectionError2DList tag in Frame #" << frameIndex <<
"failed");
964 for (
int reprojectionError2DIndex = 0; reprojectionError2DIndex < reprojectionError2DListBaseline->GetNumberOfNestedElements(); ++reprojectionError2DIndex)
966 vtkXMLDataElement* reprojectionError2DBaseline = reprojectionError2DListBaseline->GetNestedElement(reprojectionError2DIndex);
967 vtkXMLDataElement* reprojectionError2D = reprojectionError2DList->GetNestedElement(reprojectionError2DIndex);
968 if (!reprojectionError2DBaseline || !reprojectionError2D || STRCASECMP(reprojectionError2DBaseline->GetName(),
"ReprojectionError2D") != 0 || STRCASECMP(reprojectionError2D->GetName(),
"ReprojectionError2D") != 0)
970 LOG_ERROR(
"Invalid ReprojectionError2D element in Frame #" << frameIndex);
975 if (STRCASECMP(reprojectionError2DBaseline->GetAttribute(
"WireName"), reprojectionError2D->GetAttribute(
"WireName")) != 0)
977 LOG_ERROR(
"Wire name mismatch: " << reprojectionError2DBaseline->GetAttribute(
"Name") <<
" <> " << reprojectionError2D->GetAttribute(
"Name"));
984 if (! reprojectionError2DBaseline->GetVectorAttribute(
"ErrorPx", 2, blErrorPx)
985 || ! reprojectionError2D->GetVectorAttribute(
"ErrorPx", 2, cErrorPx))
987 LOG_ERROR(
"Reading ErrorPx of reprojectionError2D #" << reprojectionError2DIndex <<
" in Frame #" << frameIndex <<
"failed!");
992 for (
int i = 0;
i < 2;
i++)
994 double ratio = 1.0 * blErrorPx[
i] / cErrorPx[
i];
995 double absoluteError = fabs(blErrorPx[
i] - cErrorPx[
i]);
998 LOG_ERROR(
"ErrorPx component " <<
i <<
" mismatch: current=" << cErrorPx[
i] <<
", baseline=" << blErrorPx[
i] <<
" (error index " << reprojectionError2DIndex <<
" in frame " << frameIndex <<
")");
1010 return numberOfFailures;
std::string GetOutputPath(const std::string &subPath)
const double ERROR_THRESHOLD
static vtkPlusConfig * GetInstance()
std::vector< PlusNWire > GetNWires()
int main(int argc, char *argv[])
int CompareCalibrationResultsWithBaseline(const char *baselineFileName, const char *currentResultFileName, double translationErrorThreshold, double rotationErrorThreshold)
static vtkIGSIOLogger * Instance()
PlusFidLineFinder * GetFidLineFinder()
virtual vtkXMLDataElement * GetDeviceSetConfigurationData()
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)