diff --git a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/files.cmake b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/files.cmake
index 24fb49620e..6ae8c9f888 100644
--- a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/files.cmake
+++ b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/files.cmake
@@ -1,37 +1,41 @@
SET(SRC_CPP_FILES
)
SET(INTERNAL_CPP_FILES
QmitkIGTTrackingSemiAutomaticMeasurementView.cpp
+ QmitkIGTTrackingDataEvaluationView.cpp
mitkPluginActivator.cpp
)
SET(UI_FILES
src/internal/QmitkIGTTrackingSemiAutomaticMeasurementViewControls.ui
+ src/internal/QmitkIGTTrackingDataEvaluationViewControls.ui
)
SET(MOC_H_FILES
src/internal/QmitkIGTTrackingSemiAutomaticMeasurementView.h
+ src/internal/QmitkIGTTrackingDataEvaluationView.h
src/internal/mitkPluginActivator.h
)
SET(CACHED_RESOURCE_FILES
resources/icon.xpm
+ resources/icon-eval.xpm
plugin.xml
)
SET(QRC_FILES
resources/QmitkIGTTrackingSemiAutomaticMeasurementView.qrc
)
SET(CPP_FILES)
foreach(file ${SRC_CPP_FILES})
SET(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
SET(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/plugin.xml b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/plugin.xml
index 7d39be1758..a322bed111 100644
--- a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/plugin.xml
+++ b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/plugin.xml
@@ -1,11 +1,18 @@
+
+
+
+
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/resources/QmitkIGTTrackingSemiAutomaticMeasurementView.qrc b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/resources/QmitkIGTTrackingSemiAutomaticMeasurementView.qrc
index a6ab359bf6..4222814e5c 100644
--- a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/resources/QmitkIGTTrackingSemiAutomaticMeasurementView.qrc
+++ b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/resources/QmitkIGTTrackingSemiAutomaticMeasurementView.qrc
@@ -1,5 +1,8 @@
icon.xpm
+
+ icon-eval.xpm
+
diff --git a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/resources/icon-eval.xpm b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/resources/icon-eval.xpm
new file mode 100644
index 0000000000..dd04f91df1
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/resources/icon-eval.xpm
@@ -0,0 +1,107 @@
+/* XPM */
+static char * icon_xpm[] = {
+"100 100 4 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #22B14C",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+".............................++++...................................................................",
+"...........................++++++...................................................................",
+"..........................+++++++...................................................................",
+".........................+++.++++...................................................................",
+".........................++..++++...................................................................",
+".............................++++...................................................................",
+".............................++++...........................+++++++.................................",
+".............................++++.........................++++++++++................................",
+".............................++++.........................+++++++++++...............................",
+".............................++++.........................++....+++++...............................",
+".............................++++................................++++...............................",
+".............................++++................................++++...............................",
+".............................++++...............................++++................................",
+".............................++++...........................+++++++.................................",
+".............................++++...........................+++++++.................................",
+".........................++++++++++++.......................+++++++++...............................",
+".........................++++++++++++............................+++++..............................",
+".........................++++++++++++.............................++++..............................",
+"..................................................................++++..............................",
+"..................................................................++++..............................",
+"..........................................................++.....+++++..............................",
+"..........................................................+++++++++++...............................",
+"..........................................................++++++++++................................",
+"............................................................++++++..................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"..........................................++++++....................................................",
+"........................................++++++++++..................................................",
+"........................................++++++++++..................................................",
+"........................................++....+++++.................................................",
+"...............................................++++.................................................",
+"...............................................++++.................................................",
+"...............................................++++.................................................",
+"..............................................++++..................................................",
+"..............................................++++..................................................",
+".............................................++++...................................................",
+"............................................++++....................................................",
+"...........................................++++.....................................................",
+"..........................................++++......................................................",
+".........................................++++.......................................................",
+".........................................+++........................................................",
+"........................................++++++++++++................................................",
+"........................................++++++++++++................................................",
+"........................................++++++++++++................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................+++.............................................",
+"...................................................+++++++..........................................",
+"...................................................++++++++++.......................................",
+"...................................................++++++++++++.....................................",
+"...................................................+++++++++++++++..................................",
+"........................+++++++++++++++++++++++++++++++++++++++++++++...............................",
+".......................+++++++++++++++++++++++++++++++++@++++++++++++++.............................",
+".......................+++++++++++++++++++++++++++++++++@@@@++++++++++++++..........................",
+".......................+++++++++++++++++++++++++++++++++@@@@@@+++++++++++++++.......................",
+".......................++++++++++++++++++++++++++++++++@@@@@@@@@@++++++++++++++.....................",
+".......................+++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++++++++++++++..................",
+".......................+++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++++++++++.................",
+".......................+++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++++++++................",
+".......................+++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++++++++................",
+".......................+++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++++++++++.................",
+".......................+++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++++++++++++++..................",
+".......................++++++++++++++++++++++++++++++++@@@@@@@@@@++++++++++++++.....................",
+".......................+++++++++++++++++++++++++++++++++@@@@@@+++++++++++++++.......................",
+".......................+++++++++++++++++++++++++++++++++@@@@++++++++++++++..........................",
+".......................+++++++++++++++++++++++++++++++++@++++++++++++++.............................",
+"........................+++++++++++++++++++++++++++++++++++++++++++++...............................",
+"...................................................+++++++++++++++..................................",
+"...................................................++++++++++++.....................................",
+"...................................................++++++++++.......................................",
+"...................................................+++++++..........................................",
+"....................................................+++.............................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"....................................................................................................",
+"...................................................................................................."};
diff --git a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationView.cpp b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationView.cpp
new file mode 100644
index 0000000000..4ccbee7cc6
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationView.cpp
@@ -0,0 +1,1107 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+Copyright (c) German Cancer Research Center, Division of Medical and
+Biological Informatics. All rights reserved.
+See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+// Blueberry
+#include
+#include
+
+// Qmitk
+#include "QmitkIGTTrackingDataEvaluationView.h"
+#include "QmitkStdMultiWidget.h"
+
+// Qt
+#include
+#include
+
+// MITK
+#include "mitkNavigationDataCSVSequentialPlayer.h"
+#include
+#include
+#include
+
+//ITK
+#include
+
+//VNL
+#include
+
+//vtk headers
+#include
+#include
+#include
+
+
+const std::string QmitkIGTTrackingDataEvaluationView::VIEW_ID = "org.mitk.views.igttrackingdataevaluation";
+
+QmitkIGTTrackingDataEvaluationView::QmitkIGTTrackingDataEvaluationView()
+: QmitkFunctionality()
+, m_Controls( 0 )
+, m_MultiWidget( NULL )
+, m_scalingfactor(1)
+{
+m_CSVtoXMLInputFilenameVector = std::vector();
+m_CSVtoXMLOutputFilenameVector = std::vector();
+}
+
+QmitkIGTTrackingDataEvaluationView::~QmitkIGTTrackingDataEvaluationView()
+{
+}
+
+
+void QmitkIGTTrackingDataEvaluationView::CreateQtPartControl( QWidget *parent )
+{
+ // build up qt view, unless already done
+ if ( !m_Controls )
+ {
+ // create GUI widgets from the Qt Designer's .ui file
+ m_Controls = new Ui::QmitkIGTTrackingDataEvaluationViewControls;
+ m_Controls->setupUi( parent );
+
+ connect( m_Controls->m_LoadInputFileList, SIGNAL(clicked()), this, SLOT(OnLoadFileList()) );
+ connect( m_Controls->m_StartEvaluation, SIGNAL(clicked()), this, SLOT(OnEvaluateData()) );
+ connect( m_Controls->m_AddToCurrentList, SIGNAL(clicked()), this, SLOT(OnAddToCurrentList()) );
+ connect( m_Controls->m_GeneratePointSetOfMeanPositions, SIGNAL(clicked()), this, SLOT(OnGeneratePointSet()) );
+ connect( m_Controls->m_GenerateRotationLines, SIGNAL(clicked()), this, SLOT(OnGenerateRotationLines()) );
+ connect( m_Controls->m_GeneratePointSet, SIGNAL(clicked()), this, SLOT(OnGenerateGroundTruthPointSet()) );
+ connect( m_Controls->m_Convert, SIGNAL(clicked()), this, SLOT(OnConvertCSVtoXMLFile()) );
+ connect( m_Controls->m_loadCSVtoXMLInputList, SIGNAL(clicked()), this, SLOT(OnCSVtoXMLLoadInputList()) );
+ connect( m_Controls->m_loadCSVtoXMLOutputList, SIGNAL(clicked()), this, SLOT(OnCSVtoXMLLoadOutputList()) );
+ connect( m_Controls->m_OrientationCalculationGenerateReference, SIGNAL(clicked()), this, SLOT(OnOrientationCalculation_CalcRef()) );
+ connect( m_Controls->m_OrientationCalculationWriteOrientationsToFile, SIGNAL(clicked()), this, SLOT(OnOrientationCalculation_CalcOrientandWriteToFile()) );
+ connect( m_Controls->m_GeneratePointSetsOfSinglePositions, SIGNAL(clicked()), this, SLOT(OnGeneratePointSetsOfSinglePositions()) );
+ }
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnOrientationCalculation_CalcRef()
+{
+if(m_FilenameVector.size() != 3)
+ {
+ MessageBox("Need exactly three points as reference, aborting!");
+ return;
+ }
+
+//start loop and iterate through all files of list
+for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+ //check if the stream is valid and skip file if not
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ continue;
+ }
+
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+
+
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++)
+ {myEvaluationFilter->Update();}
+
+ //store mean position as reference
+ switch (i)
+ {
+ case 0:
+ m_RefPoint1 = myEvaluationFilter->GetPositionMean(0);
+ break;
+ case 1:
+ m_RefPoint2 = myEvaluationFilter->GetPositionMean(0);
+ break;
+ case 2:
+ m_RefPoint3 = myEvaluationFilter->GetPositionMean(0);
+ break;
+ }
+ }
+ MessageBox("Created Reference!");
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnOrientationCalculation_CalcOrientandWriteToFile()
+{
+//start loop and iterate through all files of list
+for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+ //check if the stream is valid and skip file if not
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ continue;
+ }
+
+
+
+ //open file header
+ QString outputname = QString(m_FilenameVector.at(i).c_str()) + "_orientationFile.csv";
+ m_CurrentWriteFile.open(outputname.toStdString().c_str(), std::ios::out);
+ if (m_CurrentWriteFile.bad())
+ {
+ MessageBox("Error: Can't open output file!");
+ return;
+ }
+
+ //write header to file
+ m_CurrentWriteFile << "Nr;Calypso_Time;Valid_Reference;MeasureTool_Measurement-Tool[x];MeasureTool_Measurement-Tool[y];MeasureTool_Measurement-Tool[z];MeasureTool_Measurement-Tool[qx];MeasureTool_Measurement-Tool[qy];MeasureTool_Measurement-Tool[qz];MeasureTool_Measurement-Tool[qr]\n";
+
+ //update pipeline until number of samples is reached
+ int step = 0;
+ mitk::Point3D point1,point2,point3;
+ mitk::Quaternion current_orientation;
+
+ for (int j=0; !myPlayer->IsAtEnd(); j++)
+ {
+ myPlayer->Update();
+ mitk::NavigationData::Pointer currentNavData = myPlayer->GetOutput(0);
+ switch (step)
+ {
+ case 0:
+ step++;
+ point1 = currentNavData->GetPosition();
+ break;
+ case 1:
+ step++;
+ point2 = currentNavData->GetPosition();
+ break;
+ case 2:
+ step=0;
+ point3 = currentNavData->GetPosition();
+
+ //compute transform from reference to current points
+ if (point1[0] == 0 &&
+ point1[1] == 0 &&
+ point1[2] == 0 &&
+ point2[0] == 0 &&
+ point2[1] == 0 &&
+ point2[2] == 0 &&
+ point3[0] == 0 &&
+ point3[1] == 0 &&
+ point3[2] == 0
+ ) current_orientation.fill(0);
+ else
+ {
+ /* Drehen um eine Achse um das "Umschlagen" zu vermeiden
+ itk::Matrix rot180degreeAroundY;
+ rot180degreeAroundY.Fill(0);
+ rot180degreeAroundY[0][0] = -1;
+ rot180degreeAroundY[1][1] = 1;
+ rot180degreeAroundY[2][2] = -1;
+ point1 = rot180degreeAroundY * point1;
+ point2 = rot180degreeAroundY * point2;
+ point3 = rot180degreeAroundY * point3;
+ */
+
+ vtkSmartPointer transform = vtkSmartPointer::New();
+ vtkSmartPointer sourcePoints = vtkSmartPointer::New();
+ double sourcepoint1[3] = {point1[0],point1[1],point1[2]};
+ double sourcepoint2[3] = {point2[0],point2[1],point2[2]};
+ double sourcepoint3[3] = {point3[0],point3[1],point3[2]};
+ sourcePoints->InsertNextPoint(sourcepoint1);
+ sourcePoints->InsertNextPoint(sourcepoint2);
+ sourcePoints->InsertNextPoint(sourcepoint3);
+ vtkSmartPointer targetPoints = vtkSmartPointer::New();
+ double targetpoint1[3] = {m_RefPoint1[0],m_RefPoint1[1],m_RefPoint1[2]};
+ double targetpoint2[3] = {m_RefPoint2[0],m_RefPoint2[1],m_RefPoint2[2]};
+ double targetpoint3[3] = {m_RefPoint3[0],m_RefPoint3[1],m_RefPoint3[2]};
+ targetPoints->InsertNextPoint(targetpoint1);
+ targetPoints->InsertNextPoint(targetpoint2);
+ targetPoints->InsertNextPoint(targetpoint3);
+
+ transform->SetSourceLandmarks(sourcePoints);
+ transform->SetTargetLandmarks(targetPoints);
+ transform->Modified();
+ transform->Update();
+
+ mitk::Transform::Pointer newTransform = mitk::Transform::New();
+ newTransform->SetMatrix(transform->GetMatrix());
+ current_orientation = newTransform->GetOrientation();
+
+ //add pointset with the three positions
+ if((j>15) && (j<18))
+ {
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ mitk::PointSet::Pointer newPointSet = mitk::PointSet::New();
+ newPointSet->InsertPoint(0,point1);
+ newPointSet->InsertPoint(1,point2);
+ newPointSet->InsertPoint(2,point3);
+ QString name = QString(m_FilenameVector.at(i).c_str());
+ newNode->SetName(name.toStdString().c_str());
+ newNode->SetData(newPointSet);
+ newNode->SetFloatProperty("pointsize",0.1);
+ this->GetDataStorage()->Add(newNode);
+ }
+ }
+
+ break;
+ }
+ m_CurrentWriteFile << i << ";";
+ m_CurrentWriteFile << currentNavData->GetTimeStamp() << ";"; //IMPORTANT: change to GetIGTTimeStamp in new version!
+ m_CurrentWriteFile << "true;";
+ m_CurrentWriteFile << currentNavData->GetPosition()[0] << ";";
+ m_CurrentWriteFile << currentNavData->GetPosition()[1] << ";";
+ m_CurrentWriteFile << currentNavData->GetPosition()[2] << ";";
+ m_CurrentWriteFile << current_orientation.x() << ";";
+ m_CurrentWriteFile << current_orientation.y() << ";";
+ m_CurrentWriteFile << current_orientation.z() << ";";
+ m_CurrentWriteFile << current_orientation.r() << ";";
+ m_CurrentWriteFile << "\n";
+ }
+ //close output file
+ m_CurrentWriteFile.close();
+
+ }
+ MessageBox("Finished!");
+}
+
+void QmitkIGTTrackingDataEvaluationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
+{
+ m_MultiWidget = &stdMultiWidget;
+}
+
+
+void QmitkIGTTrackingDataEvaluationView::StdMultiWidgetNotAvailable()
+{
+ m_MultiWidget = NULL;
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnAddToCurrentList()
+{
+ //read in filename
+ QString filename = QFileDialog::getOpenFileName(NULL,tr("Open Measurement Filename List"), "/", tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+
+ /*
+ //save old locale
+ char * oldLocale;
+ oldLocale = setlocale( LC_ALL, 0 );
+
+ //define own locale
+ std::locale C("C");
+ setlocale( LC_ALL, "C" );
+ */ //TODO: check if this is needed here, and load old locale if yes
+
+ //read file
+ std::ifstream file;
+ file.open(filename.toStdString().c_str(), std::ios::in);
+ if (file.good())
+ {
+ //read out file
+ file.seekg(0L, std::ios::beg); // move to begin of file
+ while (! file.eof())
+ {
+ std::string buffer;
+ std::getline(file,buffer); // read out file line by line
+ if (buffer.size() > 0)
+ {
+ std::string thisFilename = "";
+ if (m_Controls->m_AddPath->isChecked()) thisFilename = m_Controls->m_ListPath->text().toStdString();
+ thisFilename.append(buffer);
+ m_FilenameVector.push_back(thisFilename);
+ }
+ }
+ }
+
+ //fill list at GUI
+ m_Controls->m_FileList->clear();
+ for(unsigned int i=0; im_FileList);}
+
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnLoadFileList()
+ {
+ m_FilenameVector = std::vector();
+ m_FilenameVector.clear();
+ OnAddToCurrentList();
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnEvaluateData()
+{
+
+//open output file
+m_CurrentWriteFile.open(std::string(m_Controls->m_OutputFilename->text().toUtf8()).c_str(), std::ios::out);
+if (m_CurrentWriteFile.bad())
+ {
+ MessageBox("Error: Can't open output file!");
+ return;
+ }
+
+//write output file header
+WriteHeader();
+
+//start loop and iterate through all files of list
+for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+ //check if the stream is valid and skip file if not
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+
+ continue;
+ }
+
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+
+
+
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++)
+ {
+ myEvaluationFilter->Update();
+ //Debug output:
+ //std::cout.precision(5);
+ //std::cout << "Euler " << j << ";" << myPlayer->GetOutput()->GetOrientation().rotation_euler_angles()[0] << ";" << myPlayer->GetOutput()->GetOrientation().rotation_euler_angles()[1] << ";" << myPlayer->GetOutput()->GetOrientation().rotation_euler_angles()[2] << "\n";
+ }
+
+ //write result to output file
+ WriteDataSet(myEvaluationFilter,m_FilenameVector.at(i));
+
+ }
+
+//close output file
+m_CurrentWriteFile.close();
+
+//calculate angles if option is on
+if(m_Controls->m_settingDifferenceAngles->isChecked() || m_Controls->m_DifferencesSLERP->isChecked()) CalculateDifferenceAngles();
+
+MessageBox("Finished!");
+
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnGeneratePointSetsOfSinglePositions()
+{
+ m_scalingfactor = m_Controls->m_ScalingFactor->value();
+
+ //start loop and iterate through all files of list
+ for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+ //check if the stream is valid and skip file if not
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+
+ continue;
+ }
+
+ //update pipline until number of samlples is reached and store every single point
+ for (int j=0; jm_NumberOfSamples->value(); j++)
+ {
+ myPlayer->Update();
+ mitk::Point3D thisPoint = myPlayer->GetOutput()->GetPosition();
+ thisPoint[0] *= m_scalingfactor;
+ thisPoint[1] *= m_scalingfactor;
+ thisPoint[2] *= m_scalingfactor;
+ thisPointSet->InsertPoint(j,thisPoint);
+ }
+
+ //add point set to data storage
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ QString name = this->m_Controls->m_prefix->text() + QString("PointSet_of_All_Positions_") + QString::number(i);
+ newNode->SetName(name.toStdString());
+ newNode->SetData(thisPointSet);
+ this->GetDataStorage()->Add(newNode);
+ }
+
+
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnGeneratePointSet()
+ {
+ m_scalingfactor = m_Controls->m_ScalingFactor->value();
+
+ mitk::PointSet::Pointer generatedPointSet = mitk::PointSet::New();
+
+ //start loop and iterate through all files of list
+ for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+ //check if the stream is valid and skip file if not
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+
+ continue;
+ }
+
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++) {myEvaluationFilter->Update();}
+
+ //add mean position to point set
+ mitk::Point3D meanPos = myEvaluationFilter->GetPositionMean(0);
+ if (m_scalingfactor!=1)
+ {
+ meanPos[0] *= m_scalingfactor;
+ meanPos[1] *= m_scalingfactor;
+ meanPos[2] *= m_scalingfactor;
+ }
+ generatedPointSet->InsertPoint(i,meanPos);
+ }
+
+ //add point set to data storage
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ QString name = this->m_Controls->m_prefix->text() + "PointSet_of_Mean_Positions";
+ newNode->SetName(name.toStdString());
+ newNode->SetData(generatedPointSet);
+ this->GetDataStorage()->Add(newNode);
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnGenerateRotationLines()
+ {
+ m_scalingfactor = m_Controls->m_ScalingFactor->value();
+
+ //start loop and iterate through all files of list
+ for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+ //check if the stream is valid and skip file if not
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ }
+ else
+ {
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++)
+ {
+ myEvaluationFilter->Update();
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ continue;
+ }
+ }
+
+ if (!myPlayer->GetStreamValid()) continue;
+
+ //create line from mean pos to a second point which lies along the sensor (1,0,0 in tool coordinates for aurora)
+ mitk::Point3D meanPos = myEvaluationFilter->GetPositionMean(0);
+ if(m_scalingfactor!=1)
+ {
+ meanPos[0] *= m_scalingfactor;
+ meanPos[1] *= m_scalingfactor;
+ meanPos[2] *= m_scalingfactor;
+ }
+ mitk::Point3D secondPoint;
+ mitk::Point3D thirdPoint;
+ mitk::Point3D fourthPoint;
+
+ mitk::FillVector3D(secondPoint,2,0,0); //X
+ vnl_vector secondPointTransformed = myEvaluationFilter->GetQuaternionMean(0).rotation_matrix_transpose().transpose() * secondPoint.Get_vnl_vector() + meanPos.Get_vnl_vector();
+ mitk::Point3D secondPointTransformedMITK;
+ mitk::FillVector3D(secondPointTransformedMITK,secondPointTransformed[0],secondPointTransformed[1],secondPointTransformed[2]);
+
+ mitk::FillVector3D(thirdPoint,0,4,0); //Y
+ vnl_vector thirdPointTransformed = myEvaluationFilter->GetQuaternionMean(0).rotation_matrix_transpose().transpose() * thirdPoint.Get_vnl_vector() + meanPos.Get_vnl_vector();
+ mitk::Point3D thirdPointTransformedMITK;
+ mitk::FillVector3D(thirdPointTransformedMITK,thirdPointTransformed[0],thirdPointTransformed[1],thirdPointTransformed[2]);
+
+ mitk::FillVector3D(fourthPoint,0,0,6); //Z
+ vnl_vector fourthPointTransformed = myEvaluationFilter->GetQuaternionMean(0).rotation_matrix_transpose().transpose() * fourthPoint.Get_vnl_vector() + meanPos.Get_vnl_vector();
+ mitk::Point3D fourthPointTransformedMITK;
+ mitk::FillVector3D(fourthPointTransformedMITK,fourthPointTransformed[0],fourthPointTransformed[1],fourthPointTransformed[2]);
+
+
+ mitk::PointSet::Pointer rotationLine = mitk::PointSet::New();
+ rotationLine->InsertPoint(0,secondPointTransformedMITK);
+ rotationLine->InsertPoint(1,meanPos);
+ rotationLine->InsertPoint(2,thirdPointTransformedMITK);
+ rotationLine->InsertPoint(3,meanPos);
+ rotationLine->InsertPoint(4,fourthPointTransformedMITK);
+
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ QString nodeName = this->m_Controls->m_prefix->text() + "RotationLineNumber" + QString::number(i);
+ newNode->SetName(nodeName.toStdString());
+ newNode->SetData(rotationLine);
+ newNode->SetBoolProperty("show contour",true);
+ newNode->SetFloatProperty("pointsize",0.5);
+ this->GetDataStorage()->Add(newNode);
+ }
+ }
+
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnGenerateGroundTruthPointSet()
+ {
+ mitk::PointSet::Pointer generatedPointSet = mitk::PointSet::New();
+ int currentPointID = 0;
+ mitk::Point3D currentPoint;
+ mitk::FillVector3D(currentPoint,0,0,0);
+ for (int i=0; im_PointNumber1->value(); i++)
+ {
+ for (int j=0; jm_PointNumber2->value(); j++)
+ {
+ generatedPointSet->InsertPoint(currentPointID,currentPoint);
+ currentPointID++;
+ currentPoint[1] += m_Controls->m_PointDistance->value();
+ }
+ currentPoint[1] = 0;
+ currentPoint[2] += m_Controls->m_PointDistance->value();
+ }
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ QString nodeName = "GroundTruthPointSet_" + QString::number(m_Controls->m_PointNumber1->value()) + "x" + QString::number(m_Controls->m_PointNumber2->value()) + "_(" + QString::number(m_Controls->m_PointDistance->value()) + "mm)";
+ newNode->SetName(nodeName.toStdString());
+ newNode->SetData(generatedPointSet);
+ this->GetDataStorage()->Add(newNode);
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnConvertCSVtoXMLFile()
+ {
+ if(m_Controls->m_ConvertSingleFile->isChecked())
+ { //convert one file
+
+ int lines = ConvertOneFile(this->m_Controls->m_InputCSV->text().toStdString(),this->m_Controls->m_OutputXML->text().toStdString());
+
+ QString result = "Converted one file with" + QString::number(lines) + " data sets";
+ MessageBox(result.toStdString());
+ }
+ else //converte file list
+ {
+ if(m_CSVtoXMLInputFilenameVector.empty() || m_CSVtoXMLOutputFilenameVector.empty())
+ {
+ MessageBox("Error: one list is not loaded!");
+ return;
+ }
+ else if(m_CSVtoXMLInputFilenameVector.size() != m_CSVtoXMLOutputFilenameVector.size())
+ {
+ MessageBox("Error: lists do not have the same number of files!");
+ return;
+ }
+ for(int i=0; i < m_CSVtoXMLInputFilenameVector.size(); i++)
+ {int lines = ConvertOneFile(m_CSVtoXMLInputFilenameVector.at(i),m_CSVtoXMLOutputFilenameVector.at(i));}
+ QString result = "Converted " + QString::number(m_CSVtoXMLInputFilenameVector.size()) + " files from file list!";
+ MessageBox(result.toStdString());
+ }
+ }
+
+int QmitkIGTTrackingDataEvaluationView::ConvertOneFile(std::string inputFilename, std::string outputFilename)
+ {
+ std::vector myNavigationDatas = GetNavigationDatasFromFile(inputFilename);
+ mitk::NavigationDataRecorder::Pointer myRecorder = mitk::NavigationDataRecorder::New();
+ myRecorder->SetFileName(outputFilename.c_str());
+ mitk::NavigationData::Pointer input = mitk::NavigationData::New();
+ if(m_Controls->m_ConvertCSV->isChecked()) myRecorder->SetOutputFormat(mitk::NavigationDataRecorder::csv);
+ myRecorder->AddNavigationData(input);
+ myRecorder->StartRecording();
+ for (int i=0; iGraft(myNavigationDatas.at(i));
+ myRecorder->Update();
+ }
+ myRecorder->StopRecording();
+ return myNavigationDatas.size();
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnCSVtoXMLLoadInputList()
+ {
+ //read in filename
+ QString filename = QFileDialog::getOpenFileName(NULL,tr("Open Measurement Filename List"), "/", tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+
+ m_CSVtoXMLInputFilenameVector = this->GetFileContentLineByLine(filename.toStdString());
+
+ m_Controls->m_labelCSVtoXMLInputList->setText("READY");
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnCSVtoXMLLoadOutputList()
+ {
+ //read in filename
+ QString filename = QFileDialog::getOpenFileName(NULL,tr("Open Measurement Filename List"), "/", tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+
+ m_CSVtoXMLOutputFilenameVector = this->GetFileContentLineByLine(filename.toStdString());
+
+ m_Controls->m_labelCSVtoXMLOutputList->setText("READY");
+ }
+
+void QmitkIGTTrackingDataEvaluationView::MessageBox(std::string s)
+ {
+ QMessageBox msgBox;
+ msgBox.setText(s.c_str());
+ msgBox.exec();
+ }
+
+void QmitkIGTTrackingDataEvaluationView::WriteHeader()
+ {
+
+ m_CurrentWriteFile << "Filename;";
+ m_CurrentWriteFile << "N;";
+ m_CurrentWriteFile << "N_invalid;";
+ m_CurrentWriteFile << "Percentage_invalid;";
+
+ if(m_Controls->m_settingPosMean->isChecked())
+ {
+ m_CurrentWriteFile << "Position_Mean[x];";
+ m_CurrentWriteFile << "Position_Mean[y];";
+ m_CurrentWriteFile << "Position_Mean[z];";
+ }
+
+ if(m_Controls->m_settingPosStabw->isChecked())
+ {
+ m_CurrentWriteFile << "Position_StandDev[x];";
+ m_CurrentWriteFile << "Position_StandDev[y];";
+ m_CurrentWriteFile << "Position_StandDev[z];";
+ }
+
+ if(m_Controls->m_settingPosSampleStabw->isChecked())
+ {
+ m_CurrentWriteFile << "Position_SampleStandDev[x];";
+ m_CurrentWriteFile << "Position_SampleStandDev[y];";
+ m_CurrentWriteFile << "Position_SampleStandDev[z];";
+ }
+
+ if(m_Controls->m_settingQuaternionMean->isChecked())
+ {
+ m_CurrentWriteFile << "Quaternion_Mean[qx];";
+ m_CurrentWriteFile << "Quaternion_Mean[qy];";
+ m_CurrentWriteFile << "Quaternion_Mean[qz];";
+ m_CurrentWriteFile << "Quaternion_Mean[qr];";
+ }
+
+ if(m_Controls->m_settionQuaternionStabw->isChecked())
+ {
+ m_CurrentWriteFile << "Quaternion_StandDev[qx];";
+ m_CurrentWriteFile << "Quaternion_StandDev[qy];";
+ m_CurrentWriteFile << "Quaternion_StandDev[qz];";
+ m_CurrentWriteFile << "Quaternion_StandDev[qr];";
+ }
+
+ if(m_Controls->m_settingPosErrorMean->isChecked()) m_CurrentWriteFile << "PositionError_Mean;";
+
+ if(m_Controls->m_settingPosErrorStabw->isChecked()) m_CurrentWriteFile << "PositionError_StandDev;";
+
+ if(m_Controls->m_settingPosErrorSampleStabw->isChecked()) m_CurrentWriteFile << "PositionError_SampleStandDev;";
+
+ if(m_Controls->m_settingPosErrorRMS->isChecked()) m_CurrentWriteFile << "PositionError_RMS;";
+
+ if(m_Controls->m_settingPosErrorMedian->isChecked()) m_CurrentWriteFile << "PositionError_Median;";
+
+ if(m_Controls->m_settingPosErrorMinMax->isChecked())
+ {
+ m_CurrentWriteFile << "PositionError_Max;";
+ m_CurrentWriteFile << "PositionError_Min;";
+ }
+
+ if(m_Controls->m_settingEulerMean->isChecked())
+ {
+ m_CurrentWriteFile << "Euler_tx;";
+ m_CurrentWriteFile << "Euler_ty;";
+ m_CurrentWriteFile << "Euler_tz;";
+ }
+
+ if(m_Controls->m_settingEulerRMS->isChecked())
+ {
+ m_CurrentWriteFile << "EulerErrorRMS (rad);";
+ m_CurrentWriteFile << "EulerErrorRMS (grad);";
+ }
+
+ m_CurrentWriteFile << "\n";
+
+ }
+
+void QmitkIGTTrackingDataEvaluationView::WriteDataSet(mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter, std::string dataSetName)
+ {
+ if (myEvaluationFilter->GetNumberOfOutputs()==0) m_CurrentWriteFile << "Error: no input \n";
+ else
+ {
+ m_CurrentWriteFile << dataSetName << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetNumberOfAnalysedNavigationData(0) << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetNumberOfInvalidSamples(0) << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPercentageOfInvalidSamples(0) << ";";
+
+
+ if(m_Controls->m_settingPosMean->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionMean(0)[0] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionMean(0)[1] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionMean(0)[2] << ";";
+ }
+
+ if(m_Controls->m_settingPosStabw->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionStandardDeviation(0)[0] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionStandardDeviation(0)[1] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionStandardDeviation(0)[2] << ";";
+ }
+
+ if(m_Controls->m_settingPosSampleStabw->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionSampleStandardDeviation(0)[0] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionSampleStandardDeviation(0)[1] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionSampleStandardDeviation(0)[2] << ";";
+ }
+
+ if(m_Controls->m_settingQuaternionMean->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionMean(0).x() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionMean(0).y() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionMean(0).z() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionMean(0).r() << ";";
+ }
+
+ if(m_Controls->m_settionQuaternionStabw->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionStandardDeviation(0).x() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionStandardDeviation(0).y() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionStandardDeviation(0).z() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionStandardDeviation(0).r() << ";";
+ }
+
+ if(m_Controls->m_settingPosErrorMean->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorMean(0) << ";";
+ if(m_Controls->m_settingPosErrorStabw->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorStandardDeviation(0) << ";";
+ if(m_Controls->m_settingPosErrorSampleStabw->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorSampleStandardDeviation(0) << ";";
+ if(m_Controls->m_settingPosErrorRMS->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorRMS(0) << ";";
+ if(m_Controls->m_settingPosErrorMedian->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorMedian(0) << ";";
+ if(m_Controls->m_settingPosErrorMinMax->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorMax(0) << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorMin(0) << ";";
+ }
+
+ if(m_Controls->m_settingEulerMean->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesMean(0)[0] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesMean(0)[1] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesMean(0)[2] << ";";
+ }
+
+ if(m_Controls->m_settingEulerRMS->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesRMS(0) << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesRMSDegree(0) << ";";
+ }
+
+ m_CurrentWriteFile << "\n";
+
+ }
+
+
+ }
+
+void QmitkIGTTrackingDataEvaluationView::CalculateDifferenceAngles()
+ {
+
+ std::vector EvaluationDataCollection;
+
+ //start loop and iterate through all files of list: store the evaluation data
+ for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //check if the stream is valid and skip file if not
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ }
+ else
+ {
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++) {myEvaluationFilter->Update();}
+ }
+
+ myEvaluationFilter->SetInput(NULL);
+ myPlayer=NULL;
+ EvaluationDataCollection.push_back(myEvaluationFilter);
+ }
+
+ //calculation and writing of output data
+ //open output file
+ m_CurrentAngleDifferencesWriteFile.open(std::string((m_Controls->m_OutputFilename->text() + ".angledifferences.csv").toUtf8()).c_str(), std::ios::out);
+ if (m_CurrentAngleDifferencesWriteFile.bad())
+ {
+ MessageBox("Error: Can't open output file for angle differences calculation!");
+ return;
+ }
+ //write header
+ WriteDifferenceAnglesHeader();
+ //compute angle differences
+ QString pos1 = "invalid";
+ QString pos2 = "invalid";
+ //now iterate through all evaluation data and calculate the angles
+ for(int i=0; im_DifferencesSLERP->isChecked())
+ {
+ //compute slerp average
+ q1 = GetSLERPAverage(EvaluationDataCollection.at(i));
+ q2 = GetSLERPAverage(EvaluationDataCollection.at(j));
+ }
+ else
+ {
+ //compute arithmetic average
+ q1 = EvaluationDataCollection.at(i)->GetQuaternionMean(0);
+ q2 = EvaluationDataCollection.at(j)->GetQuaternionMean(0);
+ }
+
+
+ double AngleBetweenTwoQuaternions = GetAngleBetweenTwoQuaterions(q1,q2);
+
+ //write data set
+ WriteDifferenceAnglesDataSet(pos1.toStdString(),pos2.toStdString(),i,j,AngleBetweenTwoQuaternions);
+ }
+ }
+
+ //close output file
+ m_CurrentAngleDifferencesWriteFile.close();
+ }
+
+void QmitkIGTTrackingDataEvaluationView::WriteDifferenceAnglesHeader()
+ {
+ m_CurrentAngleDifferencesWriteFile << "Name;Idx1;Idx2;Angle [-PI..+PI]; Angle [Degree]\n";
+ }
+
+void QmitkIGTTrackingDataEvaluationView::WriteDifferenceAnglesDataSet(std::string pos1, std::string pos2, int idx1, int idx2, double angle)
+ {
+ double PI = 3.1415926535897932384626433832795;
+ double angle_degree = (angle / PI) * 180;
+ m_CurrentAngleDifferencesWriteFile << "Angle between " << pos1 << " and " << pos2 << ";" << idx1 << ";" << idx2 << ";" << angle << ";" << angle_degree << "\n";
+ }
+
+double QmitkIGTTrackingDataEvaluationView::GetAngleBetweenTwoQuaterions(mitk::Quaternion a, mitk::Quaternion b)
+ {
+ double returnValue;
+
+ /*
+ //another variant
+ mitk::Quaternion combinedRotation = b * a;
+
+ itk::Vector pt1; //caution 5D-Tools: Vector must lie in the YZ-plane for a correct result.
+ pt1[0] = 0.0;
+ pt1[1] = 0.0;
+ pt1[2] = 100000.0;
+
+ itk::Matrix rotMatrixA;
+ for(int i=0; i<3; i++) for(int j=0; j<3; j++) rotMatrixA[i][j] = combinedRotation.rotation_matrix_transpose().transpose()[i][j];
+ itk::Vector pt2 = rotMatrixA*pt1;
+
+ //compute angle between the two vectors
+ returnValue = (pt1[0]*pt2[0]+pt1[1]*pt2[1]+pt1[2]*pt2[2]) / ( sqrt(pow(pt1[0],2)+pow(pt1[1],2)+pow(pt1[2],2)) * sqrt(pow(pt2[0],2)+pow(pt2[1],2)+pow(pt2[2],2)));
+ returnValue = acos(returnValue);
+
+ */
+
+ //variant with double precision
+
+ itk::Vector point; //caution 5D-Tools: Vector must lie in the YZ-plane for a correct result.
+ //TODO: welchen Vektor hier nehmen?
+ point[0] = 0;
+ point[1] = 100000.0;
+ point[2] = 100000.0;
+
+ //OB DAS HILFT?
+ a.normalize();
+ b.normalize();
+
+ itk::Matrix rotMatrixA;
+ for(int i=0; i<3; i++) for(int j=0; j<3; j++) rotMatrixA[i][j] = a.rotation_matrix_transpose().transpose()[i][j];
+
+ itk::Matrix rotMatrixB;
+ for(int i=0; i<3; i++) for(int j=0; j<3; j++) rotMatrixB[i][j] = b.rotation_matrix_transpose().transpose()[i][j];
+
+ itk::Vector pt1 = rotMatrixA * point;
+ itk::Vector pt2 = rotMatrixB * point;
+
+ returnValue = (pt1[0]*pt2[0]+pt1[1]*pt2[1]+pt1[2]*pt2[2]) / ( sqrt(pow(pt1[0],2.0)+pow(pt1[1],2.0)+pow(pt1[2],2.0)) * sqrt(pow(pt2[0],2.0)+pow(pt2[1],2.0)+pow(pt2[2],2.0)));
+ returnValue = acos(returnValue);
+
+
+ /* same code with float precision:
+ mitk::Point3D point;
+ mitk::FillVector3D(point,0,0,100); //caution 5D-Tools: Vector must lie in the YZ-plane for a correct result.
+ vnl_vector pt1 = a.rotate(point.Get_vnl_vector());
+ vnl_vector pt2 = b.rotate(point.Get_vnl_vector());
+
+ //compute angle between the two vectors
+ returnValue = (pt1[0]*pt2[0]+pt1[1]*pt2[1]+pt1[2]*pt2[2]) / ( sqrt(pow(pt1[0],2)+pow(pt1[1],2)+pow(pt1[2],2)) * sqrt(pow(pt2[0],2)+pow(pt2[1],2)+pow(pt2[2],2)));
+ returnValue = acos(returnValue);
+ //angle(pt1,pt2);
+ */
+
+
+ return returnValue;
+ }
+
+std::vector QmitkIGTTrackingDataEvaluationView::GetNavigationDatasFromFile(std::string filename)
+{
+std::vector returnValue = std::vector();
+std::vector fileContentLineByLine = GetFileContentLineByLine(filename);
+for(int i=1; i QmitkIGTTrackingDataEvaluationView::GetFileContentLineByLine(std::string filename)
+{
+std::vector readData = std::vector();
+
+//save old locale
+char * oldLocale;
+oldLocale = setlocale( LC_ALL, 0 );
+
+//define own locale
+std::locale C("C");
+setlocale( LC_ALL, "C" );
+
+//read file
+std::ifstream file;
+file.open(filename.c_str(), std::ios::in);
+if (file.good())
+ {
+ //read out file
+ file.seekg(0L, std::ios::beg); // move to begin of file
+ while (! file.eof())
+ {
+ std::string buffer;
+ std::getline(file,buffer); // read out file line by line
+ if (buffer.size() > 0) readData.push_back(buffer);
+
+ }
+ }
+
+file.close();
+
+//switch back to old locale
+setlocale( LC_ALL, oldLocale );
+
+return readData;
+}
+
+mitk::NavigationData::Pointer QmitkIGTTrackingDataEvaluationView::GetNavigationDataOutOfOneLine(std::string line)
+{
+ mitk::NavigationData::Pointer returnValue = mitk::NavigationData::New();
+
+ QString myLine = QString(line.c_str());
+
+ QStringList myLineList = myLine.split(';');
+
+ mitk::Point3D position;
+ mitk::Quaternion orientation;
+
+ double time = myLineList.at(1).toDouble();
+
+ bool valid = false;
+ if (myLineList.at(2).toStdString() == "1") valid = true;
+
+ position[0] = myLineList.at(3).toDouble();
+ position[1] = myLineList.at(4).toDouble();
+ position[2] = myLineList.at(5).toDouble();
+
+ orientation[0] = myLineList.at(6).toDouble();
+ orientation[1] = myLineList.at(7).toDouble();
+ orientation[2] = myLineList.at(8).toDouble();
+ orientation[3] = myLineList.at(9).toDouble();
+
+ returnValue->SetTimeStamp(time);
+ returnValue->SetDataValid(valid);
+ returnValue->SetPosition(position);
+ returnValue->SetOrientation(orientation);
+
+ return returnValue;
+}
+
+mitk::Quaternion QmitkIGTTrackingDataEvaluationView::GetSLERPAverage(mitk::NavigationDataEvaluationFilter::Pointer evaluationFilter)
+{
+ mitk::Quaternion average;
+
+
+
+ //build a vector of quaternions from the evaulation filter (caution always takes the first (0) input of the filter
+ std::vector quaternions = std::vector();
+ for(int i=0; iGetNumberOfAnalysedNavigationData(0); i++)
+ {
+
+ mitk::Quaternion currentq = evaluationFilter->GetLoggedOrientation(i,0);
+
+ quaternions.push_back(currentq);
+ }
+
+ //compute the slerp average using the quaternion averaging class
+ mitk::QuaternionAveraging::Pointer myAverager = mitk::QuaternionAveraging::New();
+ average = myAverager->CalcAverage(quaternions);
+
+
+ return average;
+
+}
diff --git a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationView.h b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationView.h
new file mode 100644
index 0000000000..a928c578b3
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationView.h
@@ -0,0 +1,125 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+Copyright (c) German Cancer Research Center, Division of Medical and
+Biological Informatics. All rights reserved.
+See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+#ifndef QmitkIGTTrackingDataEvaluationView_h
+#define QmitkIGTTrackingDataEvaluationView_h
+
+#include
+
+#include
+
+#include "ui_QmitkIGTTrackingDataEvaluationViewControls.h"
+
+#include
+
+
+
+/*!
+ \brief QmitkIGTTrackingDataEvaluationView
+
+ \warning This application module is not yet documented. Use "svn blame/praise/annotate" and ask the author to provide basic documentation.
+
+ \sa QmitkFunctionality
+ \ingroup Functionalities
+*/
+class QmitkIGTTrackingDataEvaluationView : public QmitkFunctionality
+{
+ // this is needed for all Qt objects that should have a Qt meta-object
+ // (everything that derives from QObject and wants to have signal/slots)
+ Q_OBJECT
+
+ public:
+
+ static const std::string VIEW_ID;
+
+ QmitkIGTTrackingDataEvaluationView();
+ virtual ~QmitkIGTTrackingDataEvaluationView();
+
+ virtual void CreateQtPartControl(QWidget *parent);
+
+ virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget);
+ virtual void StdMultiWidgetNotAvailable();
+
+ protected slots:
+
+ void OnLoadFileList();
+ void OnAddToCurrentList();
+ void OnEvaluateData();
+ void OnGeneratePointSet();
+ void OnGeneratePointSetsOfSinglePositions();
+ void OnGenerateRotationLines();
+ void OnGenerateGroundTruthPointSet();
+ void OnConvertCSVtoXMLFile();
+ void OnCSVtoXMLLoadInputList();
+ void OnCSVtoXMLLoadOutputList();
+
+ /** Reads in exactly three position files als reference. */
+ void OnOrientationCalculation_CalcRef();
+ /** Uses always three positions (1,2,3: first orientation; 4,5,6: second orientation; and so on) in every file to calcualte a orientation. */
+ void OnOrientationCalculation_CalcOrientandWriteToFile();
+
+
+ protected:
+
+ Ui::QmitkIGTTrackingDataEvaluationViewControls* m_Controls;
+
+ QmitkStdMultiWidget* m_MultiWidget;
+
+ std::vector m_FilenameVector;
+
+ void MessageBox(std::string s);
+
+ std::fstream m_CurrentWriteFile;
+ void WriteHeader();
+ void WriteDataSet(mitk::NavigationDataEvaluationFilter::Pointer evaluationFilter, std::string dataSetName);
+
+ //members for orientation calculation
+ mitk::Point3D m_RefPoint1;
+ mitk::Point3D m_RefPoint2;
+ mitk::Point3D m_RefPoint3;
+
+ double m_scalingfactor; //scaling factor for visualization, 1 by default
+
+ //angle diffrences: seperated file
+ std::fstream m_CurrentAngleDifferencesWriteFile;
+ void CalculateDifferenceAngles();
+ void WriteDifferenceAnglesHeader();
+ void WriteDifferenceAnglesDataSet(std::string pos1, std::string pos2, int idx1, int idx2, double angle);
+
+ //different help methods to read a csv logging file
+ std::vector GetNavigationDatasFromFile(std::string filename);
+ std::vector GetFileContentLineByLine(std::string filename);
+ mitk::NavigationData::Pointer GetNavigationDataOutOfOneLine(std::string line);
+
+ //CSV to XML members
+ std::vector m_CSVtoXMLInputFilenameVector;
+ std::vector m_CSVtoXMLOutputFilenameVector;
+
+ //returns the number of converted lines
+ int ConvertOneFile(std::string inputFilename, std::string outputFilename);
+
+ /** @brief calculates the angle in the plane perpendicular to the rotation axis of the two quaterions. */
+ double GetAngleBetweenTwoQuaterions(mitk::Quaternion a, mitk::Quaternion b);
+
+ /** @brief calculates the slerp average of a set of quaternions which is stored in the navigation data evaluation filter */
+ mitk::Quaternion GetSLERPAverage(mitk::NavigationDataEvaluationFilter::Pointer);
+};
+
+
+
+#endif // _QMITKIGTTRACKINGDATAEVALUATIONVIEW_H_INCLUDED
+
diff --git a/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationViewControls.ui b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationViewControls.ui
new file mode 100644
index 0000000000..9095e6a5af
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igttrackingsemiautomaticmeasurement/src/internal/QmitkIGTTrackingDataEvaluationViewControls.ui
@@ -0,0 +1,941 @@
+
+
+ QmitkIGTTrackingDataEvaluationViewControls
+
+
+
+ 0
+ 0
+ 378
+ 955
+
+
+
+
+ 0
+ 0
+
+
+
+ QmitkTemplate
+
+
+ -
+
+
+ 0
+
+
+
+ Evaluation
+
+
+
-
+
+
+ Input File List (recorded NavigationData / *.csv):
+
+
+
+ -
+
+
+ -
+
+
-
+
+
+ Add Path:
+
+
+
+ -
+
+
+ D:/Experimente/
+
+
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic;">(use text files with a complete filename in every line)</span></p></body></html>
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ Load New List
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ Add To Current List
+
+
+
+
+
+ -
+
+
-
+
+
+ Number of samples to analyze:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1000000
+
+
+ 150
+
+
+
+
+
+ -
+
+
-
+
+
+ Result CSV Filename:
+
+
+
+ -
+
+
+ D:/Experimente/output.csv
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 200
+ 50
+
+
+
+
+ 200
+ 50
+
+
+
+ START EVALUATION
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Visualization Tools:
+
+
+
+ -
+
+
+ Generate PointSet of Mean Positions
+
+
+
+ -
+
+
+ Generate PointSets of Single Positions
+
+
+
+ -
+
+
+ Generate Lines for Rotation
+
+
+
+ -
+
+
-
+
+
+ Prefix for Data Nodes:
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 220
+
+
+
+
+
+
+
+
+ Settings
+
+
+ -
+
+
+ Output Settings
+
+
+
-
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic; text-decoration: underline;">Position</span></p></body></html>
+
+
+
+ -
+
+
+ Mean (x,y,z)
+
+
+
+ -
+
+
+ Standard Deviation (x,y,z)
+
+
+
+ -
+
+
+ Sample Standard Deviation (x,y,z)
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic; text-decoration: underline;">Orientation</span></p></body></html>
+
+
+
+ -
+
+
+ Quaternion Mean (qx,qy,qz,qr)
+
+
+
+ -
+
+
+ Quaternion Mean (SLERP)
+
+
+
+ -
+
+
+ Quaternion Standard Deviation (qx,qy,qz,qr)
+
+
+
+ -
+
+
+ Euler Mean (tx,ty,tz)
+
+
+
+ -
+
+
+ Difference Angles to all other Positions
+
+
+
+ -
+
+
+ Difference Angles to all other Positions (SLERP)
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic; text-decoration: underline;">Position Error</span></p></body></html>
+
+
+
+ -
+
+
+ Mean
+
+
+
+ -
+
+
+ Standard Deviation
+
+
+
+ -
+
+
+ Sample Standard Deviation
+
+
+
+ -
+
+
+ RMS
+
+
+
+ -
+
+
+ Median
+
+
+
+ -
+
+
+ Min/Max
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic; text-decoration: underline;">Orientation Error</span></p></body></html>
+
+
+
+ -
+
+
+ Euler RMS
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Scaling Factor for Visualization:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 344
+
+
+
+
+
+
+
+
+ Tools
+
+
+ -
+
+
+ Point Set Ground Truth Generator
+
+
+
-
+
+
-
+
+
+ Generate
+
+
+
+ -
+
+
+ 1
+
+
+ 999
+
+
+ 10
+
+
+
+ -
+
+
+ X
+
+
+
+ -
+
+
+ 1
+
+
+ 999
+
+
+ 9
+
+
+
+ -
+
+
+ Point Set
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Inter Point Distance (in mm):
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1
+
+
+ 99999
+
+
+ 50
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Generate
+
+
+
+
+
+
+
+
+ -
+
+
+ Result CSV File to NavigationData Converter
+
+
+
-
+
+
+ Convert Single File
+
+
+ true
+
+
+
+ -
+
+
+ Input CSV Logging File:
+
+
+
+ -
+
+
+ C:/Tools/test.csv
+
+
+
+ -
+
+
+ Output Navigation Data File:
+
+
+
+ -
+
+
+ C:/Tools/testoutput.xml
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Convert File List
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic;">(use text files with a complete filename in every line)</span></p></body></html>
+
+
+
+ -
+
+
-
+
+
+ not loaded
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 100
+ 0
+
+
+
+ Load Input List
+
+
+
+
+
+ -
+
+
-
+
+
+ not loaded
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 100
+ 0
+
+
+
+ Load Output List
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Output Format
+
+
+
-
+
+
+ XML
+
+
+ true
+
+
+
+ -
+
+
+ CSV
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Convert
+
+
+
+
+
+
+
+
+ -
+
+
+ Orientation Calculation (out of three positions)
+
+
+
-
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Generate Reference From Current List
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Write Orientation Quaternions To File
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 632
+
+
+
+
+
+
+
+
+
+
+
+
+
+