Commit bb6924d0 authored by Matt Clarkson's avatar Matt Clarkson

Issue #5353: Fixes to save regardless of calibration.

parent f2289b3c
......@@ -1632,13 +1632,16 @@ double NiftyCalVideoCalibrationManager::GetStereoRMSReconstructionError(const cv
//-----------------------------------------------------------------------------
std::string NiftyCalVideoCalibrationManager::Calibrate()
bool NiftyCalVideoCalibrationManager::Calibrate()
{
bool isSuccessful = false;
std::ostringstream message;
message << "Calibrating with " << m_NumberOfSnapshotsForCalibrating
<< " sample" << (m_NumberOfSnapshotsForCalibrating > 1 ? "s" : "")
<< std::endl;
m_CalibrationResult = message.str();
m_CalibrationErrorMessage = "";
try
{
......@@ -1953,22 +1956,38 @@ std::string NiftyCalVideoCalibrationManager::Calibrate()
this->UpdateDisplayNodes();
// Save successful calibrations.
this->Save();
isSuccessful = true;
this->Save(isSuccessful);
}
catch (niftk::NiftyCalException& e)
{
m_CalibrationErrorMessage = e.GetDescription();
MITK_ERROR << "ERROR: Calibration failed:" << e.GetDescription();
}
catch (mitk::Exception& e)
{
m_CalibrationErrorMessage = e.GetDescription();
MITK_ERROR << "ERROR: Calibration failed:" << e.GetDescription();
}
catch (std::exception& e)
{
m_CalibrationErrorMessage = e.what();
MITK_ERROR << "ERROR: Calibration failed:" << e.what();
}
if (!isSuccessful)
{
std::ostringstream message;
message << "ERROR: Calibration failed: " << e.what() << std::endl;
message << "CalibrationFailed: " << m_CalibrationErrorMessage << std::endl;
m_CalibrationResult += message.str();
if (this->GetSaveOutputRegardlessOfCalibration())
{
this->Save();
this->Save(isSuccessful);
}
}
MITK_INFO << m_CalibrationResult;
return m_CalibrationResult;
return isSuccessful;
}
......@@ -2135,7 +2154,7 @@ void NiftyCalVideoCalibrationManager::LoadCalibrationFromDirectory(const std::st
//-----------------------------------------------------------------------------
void NiftyCalVideoCalibrationManager::Save()
void NiftyCalVideoCalibrationManager::Save(bool isSuccessful)
{
if (m_ImageNode[0].IsNull())
{
......@@ -2163,10 +2182,62 @@ void NiftyCalVideoCalibrationManager::Save()
mitkThrow() << "Failed to create directory:" << m_OutputDirName;
}
niftk::SaveNifTKIntrinsics(m_Intrinsic[0], m_Distortion[0], m_OutputDirName + "calib.left.intrinsic.txt");
this->SaveImages("calib.left.images.", m_OriginalImages[0]);
this->SavePoints("calib.left.points.", m_Points[0]);
if (m_ImageNode[1].IsNotNull())
{
this->SaveImages("calib.right.images.", m_OriginalImages[1]);
this->SavePoints("calib.right.points.", m_Points[1]);
}
if (m_TrackingTransformNode.IsNotNull())
{
int counter = 0;
std::list<cv::Matx44d >::const_iterator iter;
for (iter = m_TrackingMatrices.begin();
iter != m_TrackingMatrices.end();
++iter
)
{
std::ostringstream fileName;
fileName << m_OutputDirName << "calib.tracking." << counter++ << ".4x4";
niftk::Save4x4Matrix(*iter, fileName.str());
}
}
if (m_ModelTransformNode.IsNotNull())
{
int counter = 0;
std::list<cv::Matx44d >::const_iterator iter;
for (iter = m_ModelTrackingMatrices.begin();
iter != m_ModelTrackingMatrices.end();
++iter
)
{
std::ostringstream fileName;
fileName << m_OutputDirName << "calib.tracking.model." << counter++ << ".4x4";
niftk::Save4x4Matrix(*iter, fileName.str());
}
}
// Write main results to file.
std::string outputMessageFileName = m_OutputDirName + "calib.result.log";
std::ofstream outputMessageFile;
outputMessageFile.open(outputMessageFileName, std::ofstream::out);
if (!outputMessageFile.is_open())
{
mitkThrow() << "Failed to open file:" << outputMessageFileName << " for writing.";
}
outputMessageFile << m_CalibrationResult << std::endl;
outputMessageFile.close();
MITK_INFO << "Saving calibration to:" << m_OutputDirName << ": - DONE.";
if (isSuccessful)
{
niftk::SaveNifTKIntrinsics(m_Intrinsic[0], m_Distortion[0], m_OutputDirName + "calib.left.intrinsic.txt");
if (m_ImageNode[1].IsNotNull())
{
niftk::SaveNifTKIntrinsics(
......@@ -2174,9 +2245,6 @@ void NiftyCalVideoCalibrationManager::Save()
niftk::SaveNifTKStereoExtrinsics(
m_LeftToRightRotationMatrix, m_LeftToRightTranslationVector, m_OutputDirName + "calib.r2l.txt");
this->SaveImages("calib.right.images.", m_OriginalImages[1]);
this->SavePoints("calib.right.points.", m_Points[1]);
}
if (m_ImageNode[0].IsNotNull())
......@@ -2213,18 +2281,6 @@ void NiftyCalVideoCalibrationManager::Save()
if (m_TrackingTransformNode.IsNotNull())
{
int counter = 0;
std::list<cv::Matx44d >::const_iterator iter;
for (iter = m_TrackingMatrices.begin();
iter != m_TrackingMatrices.end();
++iter
)
{
std::ostringstream fileName;
fileName << m_OutputDirName << "calib.tracking." << counter++ << ".4x4";
niftk::Save4x4Matrix(*iter, fileName.str());
}
// We deliberately output all hand-eye matrices, and additionally, whichever one was preferred method.
niftk::Save4x4Matrix(m_HandEyeMatrices[0][0].inv(), m_OutputDirName
+ "calib.left.eyehand.tsai.txt");
......@@ -2274,37 +2330,10 @@ void NiftyCalVideoCalibrationManager::Save()
+ "calib.right.eyehand.current.params.txt");
}
if (m_ModelTransformNode.IsNotNull())
{
int counter = 0;
std::list<cv::Matx44d >::const_iterator iter;
for (iter = m_ModelTrackingMatrices.begin();
iter != m_ModelTrackingMatrices.end();
++iter
)
{
std::ostringstream fileName;
fileName << m_OutputDirName << "calib.tracking.model." << counter++ << ".4x4";
niftk::Save4x4Matrix(*iter, fileName.str());
}
} // end if we have a reference transform
niftk::Save4x4Matrix(m_ModelToWorld, m_OutputDirName + "calib.model2world.txt");
} // end if we have tracking info
// Write main results to file.
std::string outputMessageFileName = m_OutputDirName + "calib.result.log";
std::ofstream outputMessageFile;
outputMessageFile.open (outputMessageFileName, std::ofstream::out);
if (!outputMessageFile.is_open())
{
mitkThrow() << "Failed to open file:" << outputMessageFileName << " for writing.";
}
outputMessageFile << m_CalibrationResult << std::endl;
outputMessageFile.close();
MITK_INFO << "Saving calibration to:" << m_OutputDirName << ": - DONE.";
} // end ifSuccessful
}
......
......@@ -168,6 +168,9 @@ public:
void SetModelTransformFileName(const std::string& fileName);
itkGetMacro(ModelTransformFileName, std::string);
itkGetMacro(CalibrationResult, std::string);
itkGetMacro(CalibrationErrorMessage, std::string);
bool isStereo() const;
unsigned int GetNumberOfSnapshots() const;
......@@ -195,15 +198,17 @@ public:
* This can be mono, stereo, iterative and include hand-eye,
* depending on the configuration parameters stored in this class.
*
* \return calibration message with all results in.
* \return bool true if it ran to completion, false otherwise.
*
* Note that even if calibration ran to completion, it doesn't mean its a good calibration.
*/
std::string Calibrate();
bool Calibrate();
/**
* \brief Saves a bunch of standard (from a NifTK perspective)
* calibration files to the output dir, overwriting existing files.
*/
void Save();
void Save(bool isSuccessful);
/**
* \brief To update the camera to world in mitk::DataStorage so
......@@ -413,6 +418,7 @@ private:
std::vector<cv::Matx44d> m_HandEyeMatrices[2];
cv::Matx44d m_ModelToWorld;
std::string m_CalibrationResult;
std::string m_CalibrationErrorMessage;
}; // end class
......
......@@ -422,8 +422,8 @@ void CameraCalView::OnGrabButtonPressed()
// If there is no model file, calibration will ultimately fail.
// However, if the user just wants to grab data, and hence
// m_Manager->GetSaveOutputBeforeCalibration() is true, then we do NOT need this check.
// So, only do this check if m_Manager->GetSaveOutputBeforeCalibration() is false.
// m_Manager->GetSaveOutputRegardlessOfCalibration() is true, then we do NOT need this check.
// So, only do this check if m_Manager->GetSaveOutputRegardlessOfCalibration() is false.
if (m_Manager->GetModelFileName().empty() && !m_Manager->GetSaveOutputRegardlessOfCalibration())
{
QMessageBox msgBox;
......@@ -452,9 +452,7 @@ void CameraCalView::OnGrabButtonPressed()
//-----------------------------------------------------------------------------
bool CameraCalView::RunGrab()
{
bool isSuccessful = false;
std::string errorMessage = "";
// This happens in a separate thread, so try to catch everything.
// Even if we understand where NiftyCal exceptions come from,
......@@ -467,30 +465,20 @@ bool CameraCalView::RunGrab()
}
catch (niftk::NiftyCalException& e)
{
errorMessage = e.GetDescription();
std::string errorMessage = e.GetDescription();
MITK_ERROR << "CameraCalView::RunGrab() failed:" << e.GetDescription();
}
catch (mitk::Exception& e)
{
errorMessage = e.GetDescription();
std::string errorMessage = e.GetDescription();
MITK_ERROR << "CameraCalView::RunGrab() failed:" << e.GetDescription();
}
catch (std::exception& e)
{
errorMessage = e.what();
std::string errorMessage = e.what();
MITK_ERROR << "CameraCalView::RunGrab() failed:" << e.what();
}
if (!errorMessage.empty())
{
QMessageBox msgBox;
msgBox.setText("An Error Occurred.");
msgBox.setInformativeText(QString::fromStdString(errorMessage));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
return isSuccessful;
}
......@@ -553,10 +541,9 @@ void CameraCalView::Calibrate()
//-----------------------------------------------------------------------------
std::string CameraCalView::RunCalibration()
bool CameraCalView::RunCalibration()
{
std::string outputMessage = "";
std::string errorMessage = "";
bool isSuccessful = false;
// This happens in a separate thread, so try to catch everything.
// Even if we understand where NiftyCal exceptions come from,
......@@ -565,56 +552,47 @@ std::string CameraCalView::RunCalibration()
try
{
outputMessage = m_Manager->Calibrate();
isSuccessful = m_Manager->Calibrate();
}
catch (niftk::NiftyCalException& e)
{
errorMessage = e.GetDescription();
std::string errorMessage = e.GetDescription();
MITK_ERROR << "CameraCalView::RunCalibration() failed:" << e.GetDescription();
throw e;
}
catch (mitk::Exception& e)
{
errorMessage = e.GetDescription();
std::string errorMessage = e.GetDescription();
MITK_ERROR << "CameraCalView::RunCalibration() failed:" << e.GetDescription();
throw e;
}
catch (std::exception& e)
{
errorMessage = e.what();
std::string errorMessage = e.what();
MITK_ERROR << "CameraCalView::RunCalibration() failed:" << e.what();
throw e;
}
return outputMessage;
return isSuccessful;
}
//-----------------------------------------------------------------------------
void CameraCalView::OnBackgroundCalibrateProcessFinished()
{
if (m_BackgroundCalibrateProcess.isCanceled()
|| m_BackgroundCalibrateProcess.resultCount() == 0)
bool successfullyCalibrated = m_BackgroundCalibrateProcessWatcher.result();
if (successfullyCalibrated)
{
QPixmap image(":/uk.ac.ucl.cmic.igicameracal/thumb-down-300px.png");
m_Controls->m_ProjectionErrorValue->setText(QString::fromStdString(this->m_Manager->GetCalibrationResult()));
QPixmap image(":/uk.ac.ucl.cmic.igicameracal/1465762629-300px.png");
m_Controls->m_ImageLabel->setPixmap(image);
m_Controls->m_ImageLabel->show();
QMessageBox msgBox;
msgBox.setText("An Error Occurred.");
msgBox.setInformativeText("The calibration itself failed - check log.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
m_Manager->UpdateCameraToWorldPosition();
m_Manager->UpdateVisualisedPoints();
}
else
{
std::string calibrationMessage = m_BackgroundCalibrateProcessWatcher.result();
m_Controls->m_ProjectionErrorValue->setText(QString::fromStdString(calibrationMessage));
m_Manager->UpdateCameraToWorldPosition();
m_Manager->UpdateVisualisedPoints();
QPixmap image(":/uk.ac.ucl.cmic.igicameracal/1465762629-300px.png");
m_Controls->m_ProjectionErrorValue->setText(QString::fromStdString(this->m_Manager->GetCalibrationErrorMessage()));
QPixmap image(":/uk.ac.ucl.cmic.igicameracal/thumb-down-300px.png");
m_Controls->m_ImageLabel->setPixmap(image);
m_Controls->m_ImageLabel->show();
}
......
......@@ -101,9 +101,9 @@ private slots:
private:
bool RunGrab();
void Calibrate();
std::string RunCalibration();
bool RunCalibration();
void Calibrate();
void SetButtonsEnabled(bool isEnabled);
/**
......@@ -120,8 +120,8 @@ private:
niftk::NiftyCalVideoCalibrationManager::Pointer m_Manager;
QFuture<bool> m_BackgroundGrabProcess;
QFutureWatcher<bool> m_BackgroundGrabProcessWatcher;
QFuture<std::string> m_BackgroundCalibrateProcess;
QFutureWatcher<std::string> m_BackgroundCalibrateProcessWatcher;
QFuture<bool> m_BackgroundCalibrateProcess;
QFutureWatcher<bool> m_BackgroundCalibrateProcessWatcher;
};
} // end namespace
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment