13 #include "PlusConfigure.h" 14 #include "igsioMath.h" 17 #include "vtkIGSIOSequenceIO.h" 18 #include "vtkIGSIOTrackedFrameList.h" 19 #include "vtkXMLDataElement.h" 20 #include "vtkXMLUtilities.h" 21 #include "vtksys/CommandLineArguments.hxx" 22 #include "vtksys/SystemTools.hxx" 30 std::ofstream outFile;
31 outFile.open( resultSaveFilename.c_str() );
32 outFile <<
"<LineSegmentationResults>" << std::endl;
33 for (
unsigned int frameIndex = 0; frameIndex < lineParameters.size(); ++frameIndex )
35 outFile <<
" <Frame Index=\"" << frameIndex <<
"\" SegmentationStatus=\"";
36 if ( lineParameters[frameIndex].lineDetected )
39 << std::fixed << std::setprecision( 8 )
40 <<
"LineOriginPointPx=\"" << lineParameters[frameIndex].lineOriginPoint_Image[0] <<
" " << lineParameters[frameIndex].lineOriginPoint_Image[1] <<
"\" " 41 <<
"LineDirectionVectorPx=\"" << lineParameters[frameIndex].lineDirectionVector_Image[0] <<
" " << lineParameters[frameIndex].lineDirectionVector_Image[1] <<
"\" ";
45 outFile <<
"Failed\"";
47 outFile <<
" />" << std::endl;
49 outFile <<
"</LineSegmentationResults>" << std::endl;
56 lineParameters.clear();
57 if ( resultSaveFilename.empty() )
59 LOG_ERROR(
"Cannot read line segmentation results, filename is empty" );
62 vtkSmartPointer<vtkXMLDataElement> resultsElem = vtkSmartPointer<vtkXMLDataElement>::Take( vtkXMLUtilities::ReadElementFromFile( resultSaveFilename.c_str() ) );
63 if ( resultsElem == NULL )
65 LOG_ERROR(
"Failed to read baseline file: " << resultSaveFilename );
68 if ( resultsElem->GetName() == NULL || STRCASECMP( resultsElem->GetName(),
"LineSegmentationResults" ) != 0 )
70 LOG_ERROR(
"Unable to find LineSegmentationResults XML data element in baseline: " << resultSaveFilename );
73 for (
int childElemIndex = 0; childElemIndex < resultsElem->GetNumberOfNestedElements(); ++childElemIndex )
75 vtkXMLDataElement* frameElem = resultsElem->GetNestedElement( childElemIndex );
76 if ( frameElem == NULL || frameElem->GetName() == NULL || STRCASECMP( frameElem->GetName(),
"Frame" ) != 0 )
78 LOG_ERROR(
"Invalid child element in LineSegmentationResults: #" << childElemIndex );
82 if ( !frameElem->GetScalarAttribute(
"Index", frameIndex ) )
84 LOG_ERROR(
"Unable to find Index element in LineSegmentationResults: child index " << childElemIndex );
87 unsigned int frameIndexUint = static_cast<unsigned int>( frameIndex );
91 const char* baselineSegmentationStatusString = frameElem->GetAttribute(
"SegmentationStatus" );
92 if ( baselineSegmentationStatusString == NULL )
94 LOG_ERROR(
"SegmentationStatus is not available in the baseline for frame " << frameIndexUint );
97 currentLineParams.
lineDetected = !STRCASECMP( baselineSegmentationStatusString,
"OK" );
101 if ( !frameElem->GetVectorAttribute(
"LineOriginPointPx", 2, currentLineParams.
lineOriginPoint_Image ) )
103 LOG_ERROR(
"Unable to find LineOriginPointPx element in LineSegmentationResults for frame " << frameIndexUint );
108 LOG_ERROR(
"Unable to find LineDirectionVectorPx element in LineSegmentationResults for frame " << frameIndexUint );
120 if ( frameIndexUint >= lineParameters.size() )
129 lineParameters.insert( lineParameters.end(), frameIndexUint - lineParameters.size() + 1, nonDetectedLineParams );
131 lineParameters[frameIndex] = currentLineParams;
138 int CompareLineSegmentationResults(
const std::vector<vtkPlusLineSegmentationAlgo::LineParameters>& lineParameters,
const std::vector<vtkPlusLineSegmentationAlgo::LineParameters>& baselineLineParameters )
140 unsigned int numberOfFailures = 0;
142 for (
unsigned int frameIndex = 0; frameIndex < lineParameters.size(); ++frameIndex )
144 LOG_DEBUG(
"Comparing frame " << frameIndex );
145 if ( frameIndex >= baselineLineParameters.size() )
147 LOG_ERROR(
"Unable to find frame " << frameIndex <<
" in LineSegmentationResults baseline" );
157 LOG_ERROR(
"SegmentationStatus mismatch in Frame #" << frameIndex <<
": current=" << currentParam.
lineDetected <<
", baseline=" << baselineParam.
lineDetected );
162 LOG_DEBUG(
" Line detection status: " << ( currentParam.
lineDetected ?
"detected" :
"not detected" ) );
172 const double lineLen = 50;
176 double distanceOfBaselineOriginFromCurrentLinePx = igsioMath::ComputeDistanceLinePoint( currentLinePoint1, currentLinePoint2, baselineOrigin3d );
179 LOG_ERROR(
"Line position mismatch in Frame #" << frameIndex <<
": baseline origin point distance from current line is " << distanceOfBaselineOriginFromCurrentLinePx <<
" pixels" );
184 LOG_DEBUG(
" Line distance: " << distanceOfBaselineOriginFromCurrentLinePx <<
" pixels" );
190 double angleDeg = acos( vtkMath::Dot( baselineVec3d, currentVec3d ) );
193 LOG_ERROR(
"Line angle mismatch in Frame #" << frameIndex <<
": angle difference is " << angleDeg <<
" deg, vector coordinates: " 200 LOG_DEBUG(
" Line angle difference is " << angleDeg <<
" deg" );
204 return numberOfFailures;
208 int main(
int argc,
char** argv )
210 int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
212 bool printHelp =
false;
213 vtksys::CommandLineArguments args;
214 args.Initialize( argc, argv );
215 std::string inputSequenceMetafile;
216 std::vector<int> clipRectOrigin;
217 std::vector<int> clipRectSize;
218 std::string inputBaselineFileName;
219 bool saveImages =
false;
221 args.AddArgument(
"--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp,
"Print this help." );
222 args.AddArgument(
"--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel,
"Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)" );
223 args.AddArgument(
"--seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputSequenceMetafile,
"Input sequence metafile name with path" );
224 args.AddArgument(
"--clip-rect-origin", vtksys::CommandLineArguments::MULTI_ARGUMENT, &clipRectOrigin,
"Origin of the clipping rectangle" );
225 args.AddArgument(
"--clip-rect-size", vtksys::CommandLineArguments::MULTI_ARGUMENT, &clipRectSize,
"Size of the clipping rectangle" );
226 args.AddArgument(
"--save-images", vtksys::CommandLineArguments::NO_ARGUMENT, &saveImages,
"Save images with detected lines overlaid" );
227 args.AddArgument(
"--baseline-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputBaselineFileName,
"Input xml baseline file name with path" );
231 std::cerr <<
"Problem parsing arguments" << std::endl;
232 std::cout <<
"Help: " << args.GetHelp() << std::endl;
233 exit( EXIT_FAILURE );
238 std::cout << args.GetHelp() << std::endl;
239 exit( EXIT_SUCCESS );
244 if ( inputSequenceMetafile.empty() )
246 std::cerr <<
"--seq-file argument is required" << std::endl;
247 std::cout <<
"Help: " << args.GetHelp() << std::endl;
248 exit( EXIT_FAILURE );
251 LOG_DEBUG(
"Read input sequence" );
252 vtkSmartPointer<vtkIGSIOTrackedFrameList> trackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
253 if ( vtkIGSIOSequenceIO::Read( inputSequenceMetafile, trackedFrameList ) !=
PLUS_SUCCESS )
255 LOG_ERROR(
"Failed to read sequence metafile: " << inputSequenceMetafile );
259 vtkSmartPointer<vtkPlusLineSegmentationAlgo> lineSegmenter = vtkSmartPointer<vtkPlusLineSegmentationAlgo>::New();
261 if ( clipRectOrigin.size() > 0 || clipRectSize.size() > 0 )
264 if ( clipRectOrigin.size() != 2 || clipRectSize.size() != 2 )
266 LOG_ERROR(
"--clip-rect-origin and --clip-rect-size arguments shall contain exactly two values each" );
267 exit( EXIT_FAILURE );
269 int origin[2] = {clipRectOrigin[0], clipRectOrigin[1]};
270 int size[2] = {clipRectSize[0], clipRectSize[1]};
271 lineSegmenter->SetClipRectangle( origin, size );
274 lineSegmenter->SetTrackedFrameList( *trackedFrameList );
275 lineSegmenter->SetSaveIntermediateImages( saveImages );
278 LOG_DEBUG(
"Segment lines" );
281 LOG_ERROR(
"Failed to get line positions from video frames" );
284 std::vector<vtkPlusLineSegmentationAlgo::LineParameters> lineParameters;
285 lineSegmenter->GetDetectedLineParameters( lineParameters );
289 LOG_INFO(
"Save calibration results to XML file: " << resultSaveFilename );
293 if ( !inputBaselineFileName.empty() )
295 LOG_INFO(
"Comparing result with baseline..." );
296 std::vector<vtkPlusLineSegmentationAlgo::LineParameters> baselineLineParameters;
299 LOG_ERROR(
"Failed to read baseline data file" );
300 exit( EXIT_FAILURE );
303 if ( numberOfFailures > 0 )
305 LOG_ERROR(
"Number of differences compared to baseline: " << numberOfFailures <<
". Test failed!" );
306 exit( EXIT_FAILURE );
310 LOG_INFO(
"Test finished successfully!" );
std::string GetOutputPath(const std::string &subPath)
void WriteLineSegmentationResultsToFile(const std::string &resultSaveFilename, const std::vector< vtkPlusLineSegmentationAlgo::LineParameters > &lineParameters)
double lineOriginPoint_Image[2]
static vtkPlusConfig * GetInstance()
const double MAX_ORIGIN_DISTANCE_PIXEL
const double MAX_LINE_ANGLE_DIFFERENCE_DEG
PlusStatus ReadLineSegmentationResultsFromFile(const std::string &resultSaveFilename, std::vector< vtkPlusLineSegmentationAlgo::LineParameters > &lineParameters)
double lineDirectionVector_Image[2]
static vtkIGSIOLogger * Instance()
int CompareLineSegmentationResults(const std::vector< vtkPlusLineSegmentationAlgo::LineParameters > &lineParameters, const std::vector< vtkPlusLineSegmentationAlgo::LineParameters > &baselineLineParameters)
int main(int argc, char **argv)