#include "camera.h"
#include "calibrationwidget.h"
#include <QFileDialog>
#include <QMessageBox>
#include <adtf_utils.h>
#include <adtfstreaming3/sample.h>
#include <projection_types.h>
static const tChar* strTemplate =
"Camera:\n\
Manually Calibrated Camera\n\
ADTF\n\
\n\
Extrinsic parameters:\n\
Resolution: %d x %d [pixel]\n\
Position: ( %f %f %f ) [m]\n\
Rotation: ( %f %f %f ) [rad]\n\
\n\
Intrinsic parameters:\n\
Focal length: ( %f %f ) [pixel]\n\
Skew parameter: %f\n\
Principal point: ( %f %f ) [pixel]\n\
Radial distortion: ( %f %f )\n\
Tangential distortion: ( %f %f )\n";
using namespace adtf::util;
using namespace adtf::base;
using namespace adtf::streaming;
cCalibrationWidget::cCalibrationWidget(ISampleWriter* pWriter): QWidget(), m_pWriter(pWriter), m_nCounter(0)
{
THROW_IF_FAILED(_runtime->GetObject(m_pClock));
setupUi(this);
connect(m_pLoadButton, SIGNAL(clicked()), this, SLOT(OnLoad()));
connect(m_pSaveButton, SIGNAL(clicked()), this, SLOT(OnSave()));
connect(m_pTransmitButton, SIGNAL(clicked()), this, SLOT(OnTransmit()));
connect(m_pWidth, SIGNAL(valueChanged(int)), this, SLOT(OnWidth()));
connect(m_pHeight, SIGNAL(valueChanged(int)), this, SLOT(OnHeight()));
connect(m_pPrincipalX, SIGNAL(valueChanged(double)), this, SLOT(OnPX()));
connect(m_pPrincipalY, SIGNAL(valueChanged(double)), this, SLOT(OnPY()));
connect(m_pPXSlider, SIGNAL(sliderMoved(int)), this, SLOT(OnPXSlide()));
connect(m_pPYSlider, SIGNAL(sliderMoved(int)), this, SLOT(OnPYSlide()));
OnWidth();
OnHeight();
OnPX();
OnPY();
}
void cCalibrationWidget::OnLoad()
{
QString strFileName = QFileDialog::getOpenFileName(this, "Open Calibration File");
if (!strFileName.isEmpty())
{
cCamera oHelper;
if (IS_FAILED(oHelper.ParseConfig(strFileName.toStdString().c_str())))
{
QMessageBox::critical(this, "Error while parsing file", "Unable to parse camera calibration file: " + strFileName);
return;
}
m_pWidth->setValue(oHelper.m_nResX);
m_pHeight->setValue(oHelper.m_nResY);
m_pPosX->setValue(oHelper.m_fPosX);
m_pPosY->setValue(oHelper.m_fPosY);
m_pPosZ->setValue(oHelper.m_fPosZ);
m_pRotX->setValue(oHelper.m_fRotX);
m_pRotY->setValue(oHelper.m_fRotY);
m_pRotZ->setValue(oHelper.m_fRotZ);
m_pFocalX->setValue(oHelper.m_fFocalX);
m_pFocalY->setValue(oHelper.m_fFocalY);
m_pPrincipalX->setValue(oHelper.m_fPrincipalX);
m_pPrincipalY->setValue(oHelper.m_fPrincipalY);
}
}
void cCalibrationWidget::OnSave()
{
QString strFileName = QFileDialog::getSaveFileName(this, "Save Calibration File");
if (!strFileName.isEmpty())
{
auto oResult = cFileSystem::WriteTextFile(strFileName.toStdString().c_str(),
cString::Format(strTemplate,
m_pWidth->value(),
m_pHeight->value(),
m_pPosX->value(),
m_pPosY->value(),
m_pPosZ->value(),
m_pRotX->value(),
m_pRotY->value(),
m_pRotZ->value(),
m_pFocalX->value(),
m_pFocalY->value(),
0.0,
m_pPrincipalX->value(),
m_pPrincipalY->value(),
0.0, 0.0,
0.0, 0.0));
if (IS_FAILED(oResult))
{
QMessageBox::critical(this,
"Error while saving file",
QString("Unable to save camera calibration file %1: %2").arg(strFileName).arg(to_string(oResult).GetPtr()));
}
}
}
void cCalibrationWidget::OnTransmit()
{
auto tmNow = m_pClock->GetStreamTimeNs();
output_sample_data<tCameraProjection> oOutputData(tmNow);
oOutputData->f32PosX = m_pPosX->value();
oOutputData->f32PosY = m_pPosY->value();
oOutputData->f32PosZ = m_pPosZ->value();
oOutputData->f32RotX = m_pRotX->value();
oOutputData->f32RotY = m_pRotY->value();
oOutputData->f32RotZ = m_pRotZ->value();
oOutputData->f32FocalX = m_pFocalX->value();
oOutputData->f32FocalY = m_pFocalY->value();
oOutputData->f32PrincipalX = m_pPrincipalX->value();
oOutputData->f32PrincipalY = m_pPrincipalY->value();
oOutputData->nCounter = m_nCounter++;
oOutputData->nSize = sizeof(tCameraProjection);
m_pWriter->Write(oOutputData.Release());
m_pWriter->ManualTrigger(tmNow);
}
void cCalibrationWidget::OnWidth()
{
m_pPXSlider->setMaximum(m_pWidth->value());
}
void cCalibrationWidget::OnHeight()
{
m_pPYSlider->setMaximum(m_pHeight->value());
}
void cCalibrationWidget::OnPX()
{
m_pPXSlider->setValue(m_pPrincipalX->value());
}
void cCalibrationWidget::OnPY()
{
m_pPYSlider->setValue(m_pPrincipalY->value());
}
void cCalibrationWidget::OnPXSlide()
{
m_pPrincipalX->setValue(m_pPXSlider->value());
}
void cCalibrationWidget::OnPYSlide()
{
m_pPrincipalY->setValue(m_pPYSlider->value());
}
void cCalibrationWidget::OnValueChanged()
{
if (m_pImmediately->isChecked())
{
OnTransmit();
}
}