Newer
Older
// bothersome
connect(
mLimitPlaybackSpeed,
&QAction::triggered,
mPlayerWidget,
[&]() { mPlayerWidget->setPlayerSpeedLimited(!mPlayerWidget->getPlayerSpeedLimited()); });
mFixPlaybackSpeed = new QAction(tr("&Fix playback speed"));
mFixPlaybackSpeed->setCheckable(true);
connect(mFixPlaybackSpeed, &QAction::toggled, mPlayerWidget, &Player::setPlayerSpeedFixed);
mSetToRealtime = new QAction(tr("&Realtime"));
connect(
mSetToRealtime, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(1.0); });
connect(mSetTo2p00, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(2.0); });
connect(mSetTo1p75, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(1.75); });
connect(mSetTo1p50, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(1.5); });
connect(mSetTo1p25, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(1.25); });
connect(mSetTo0p75, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(0.75); });
connect(mSetTo0p50, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(0.5); });
connect(mSetTo0p25, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(0.25); });
mPlayerLooping = new QAction(tr("&Loop"));
mPlayerLooping->setCheckable(true);
connect(mPlayerLooping, &QAction::triggered, mPlayerWidget, &Player::setLooping);
// -------------------------------------------------------------------------------------------------------
mDelPastAct = new QAction(tr("&Past part of all trj."), this);
connect(
mDelPastAct,
&QAction::triggered,
this,
[this]() { this->deleteTrackPointAll(PersonStorage::Direction::Previous); });
mDelFutureAct = new QAction(tr("&Future part of all trj."), this);
connect(
mDelFutureAct,
&QAction::triggered,
this,
[this]() { this->deleteTrackPointAll(PersonStorage::Direction::Following); });
mDelAllRoiAct = new QAction(tr("&Trj. moving through ROI"), this);
connect(mDelAllRoiAct, &QAction::triggered, this, &Petrack::deleteTrackPointROI);
mDelPartRoiAct = new QAction(tr("Part of Trj. inside &ROI"), this);
connect(mDelPartRoiAct, &QAction::triggered, this, &Petrack::deleteTrackPointInsideROI);
// -------------------------------------------------------------------------------------------------------
mCommandAct = new QAction(tr("&Command line options"), this);
connect(mCommandAct, SIGNAL(triggered()), this, SLOT(commandLineOptions()));
mKeyAct = new QAction(tr("&Key bindings"), this);
connect(mKeyAct, SIGNAL(triggered()), this, SLOT(keyBindings()));
mAboutAct = new QAction(tr("&About"), this);
connect(mAboutAct, SIGNAL(triggered()), this, SLOT(about()));
mOnlineHelpAct = new QAction(tr("Online &Help"), this);
mOnlineHelpAct->setShortcut(tr("Ctrl+H"));
connect(mOnlineHelpAct, SIGNAL(triggered()), this, SLOT(onlineHelp()));
}
/**
* @brief Helper function building menues out of QActions
* @see Petrack::createActions()
*/
void Petrack::createMenus()
{
mFileMenu = new QMenu(tr("&File"), this);
mFileMenu->addAction(mOpenPrAct);
mFileMenu->addAction(mSaveAct);
mFileMenu->addAction(mSavePrAct);
mFileMenu->addSeparator();
mFileMenu->addAction(mOpenSeqAct);
mFileMenu->addAction(mOpenCameraAct);
mFileMenu->addAction(mEditMoCapAct);
mFileMenu->addAction(mSaveSeqVidAct);
mFileMenu->addAction(mSaveSeqVidViewAct);
mFileMenu->addAction(mSaveImageAct);
mFileMenu->addAction(mSaveSeqImgAct);
mFileMenu->addAction(mSaveViewAct);
mFileMenu->addAction(mSaveSeqViewAct);
mFileMenu->addAction(mPrintAct);
mFileMenu->addSeparator();
mFileMenu->addAction(mResetSettingsAct);
mFileMenu->addAction(mAutosaveSettings);
mFileMenu->addSeparator();
mFileMenu->addAction(mExitAct);
mViewMenu = new QMenu(tr("&View"), this);
mViewMenu->addAction(mAntialiasAct);
mViewMenu->addAction(mOpenGLAct);
mViewMenu->addAction(mCropZoomViewAct);
mCameraMenu = mViewMenu->addMenu(tr("&Camera"));
mCameraMenu->addAction(mCameraLeftViewAct);
mCameraMenu->addAction(mCameraRightViewAct);
mViewMenu->addAction(mFixPlaybackSpeed);
mViewMenu->addAction(mLimitPlaybackSpeed);
mPlaybackSpeedMenu = mViewMenu->addMenu(tr("&Playback speed"));
mPlaybackSpeedMenu->addAction(mSetToRealtime);
mPlaybackSpeedMenu->addAction(mSetTo2p00);
mPlaybackSpeedMenu->addAction(mSetTo1p75);
mPlaybackSpeedMenu->addAction(mSetTo1p50);
mPlaybackSpeedMenu->addAction(mSetTo1p25);
mPlaybackSpeedMenu->addAction(mSetTo0p75);
mPlaybackSpeedMenu->addAction(mSetTo0p50);
mPlaybackSpeedMenu->addAction(mSetTo0p25);
mViewMenu->addSeparator();
mViewMenu->addAction(mFitViewAct);
mViewMenu->addAction(mFitROIAct);
mViewMenu->addAction(mResetAct);
mViewMenu->addSeparator();
mViewMenu->addAction(mFontAct);
mViewMenu->addSeparator();
mViewMenu->addAction(mHideControlsAct);
mViewMenu->addSeparator();
mViewMenu->addAction(mShowLogWindowAct);
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
mDeleteMenu = new QMenu(tr("&Delete"), this);
mDeleteMenu->addAction(mDelPastAct);
mDeleteMenu->addAction(mDelFutureAct);
mDeleteMenu->addAction(mDelAllRoiAct);
mDeleteMenu->addAction(mDelPartRoiAct);
mHelpMenu = new QMenu(tr("&Help"), this);
mHelpMenu->addAction(mCommandAct);
mHelpMenu->addAction(mKeyAct);
mHelpMenu->addAction(mAboutAct);
mHelpMenu->addAction(mOnlineHelpAct);
menuBar()->addMenu(mFileMenu);
menuBar()->addMenu(mViewMenu);
menuBar()->addMenu(mDeleteMenu);
menuBar()->addMenu(mHelpMenu);
mCameraMenu->setEnabled(false);
}
/**
* @brief Helper function to create status bar at the bottom of the window
*/
QFont f("Courier", 12, QFont::Bold); // Times Helvetica, Normal
statusBar()->setMaximumHeight(28);
statusBar()->showMessage(tr("Ready"));
statusBar()->addPermanentWidget(mStatusLabelStereo = new QLabel(" "));
statusBar()->addPermanentWidget(mStatusLabelTime = new QLabel(" "));
statusBar()->addPermanentWidget(mStatusLabelFPS = new QLabel(" "));
statusBar()->addPermanentWidget(mStatusPosRealHeight = new QDoubleSpinBox());
connect(mStatusPosRealHeight, SIGNAL(valueChanged(double)), this, SLOT(setStatusPosReal()));
statusBar()->addPermanentWidget(mStatusLabelPosReal = new QLabel(" "));
statusBar()->addPermanentWidget(mStatusLabelPos = new QLabel(" "));
statusBar()->addPermanentWidget(mStatusLabelColor = new QLabel(" "));
mStatusLabelStereo->setFont(f);
mStatusLabelStereo->setMinimumWidth(200);
mStatusLabelTime->setFont(f);
mStatusLabelTime->setMinimumWidth(200);
mStatusLabelFPS->setFont(f);
mStatusLabelFPS->setMinimumWidth(80);
mStatusLabelFPS->setAutoFillBackground(true);
mStatusLabelFPS->setToolTip("Click to adapt play rate to fps rate");
mStatusPosRealHeight->setRange(-999.9, 9999.9); // in cm
mStatusPosRealHeight->setDecimals(1);
mStatusPosRealHeight->setFont(f);
mStatusLabelPosReal->setFont(f);
mStatusLabelPosReal->setMinimumWidth(340);
mStatusLabelPos->setFont(f);
mStatusLabelPos->setMinimumWidth(100);
mStatusLabelColor->setFont(f);
mStatusLabelColor->setMinimumWidth(90);
mStatusLabelColor->setAutoFillBackground(true);
}
void Petrack::resetUI()
{
/// Reset all UI elements to default settings
/// Noetig damit alle UI Elemente, welche in der neu geladenen Projekt-Datei z.B. noch nicht vorhanden sind, auf
/// sinnvolle Werte gesetzt werden. Anderenfalls kommt es evtl. beim nacheinander laden verschiedener Projekte zu
/// einem Programmabsturz
///
return;
}
void Petrack::setStatusStereo(float x, float y, float z)
{
mStatusLabelStereo->setText(QString("x= novalue y= novalue z= novalue "));
mStatusLabelStereo->setText(
QString("x=%1cm y=%2cm z=%3cm ").arg(x, 6, 'f', 1).arg(y, 6, 'f', 1).arg(z, 6, 'f', 1));
{
mStatusLabelFPS->setText(QString("%1fps ").arg(mShowFPS, 5, 'f', 1));
QPalette pal = mStatusLabelFPS->palette(); // static moeglich?
double diff = mShowFPS - mAnimation->getFPS();
int opacity = mPlayerWidget->getPlayerSpeedLimited() ? 128 : 20;
if(diff < -6) // very slow ==> red
color.setRgb(200, 0, 0, opacity);
else if(diff < -2) // better ==> yellow
color.setRgb(200, 200, 0, opacity);
else if(diff > -2) // nearly ok ==> green
color.setRgb(0, 200, 0, opacity);
pal.setColor(QPalette::Window, color);
mStatusLabelFPS->setPalette(pal);
}
}
void Petrack::setShowFPS(double fps)
{
if((fps == 0.) || (mShowFPS == 0))
mShowFPS = mShowFPS * .9 + fps * .1; // glaetten durch Hinzunahme des alten Wertes
/**
* @brief Updates the FPS shown to the User
*
* This method calculates the FPS by remembering how long
* it has been since it was called last time. If skipped is
* true, it doesn't directly update the FPS since 2
* skipped frames have essentially a time delay of 0 between
* them, which would make calculations wonky.
*
* @param skipped True, if this is a skipped frame; default false
*/
void Petrack::updateShowFPS(bool skipped)
{
static QElapsedTimer lastTime;
lastTime.invalidate();
int numFrames = skippedFrames > 0 ? skippedFrames + 1 : 1;
setShowFPS(numFrames * 1000. / lastTime.elapsed());
}
}
lastTime.start();
}
}
// ohne neue positionsangabe, sinnvoll, wenn berechnungsweise sich in getPosReal geaendert hat
// gebraucht in control.cpp
void Petrack::setStatusPosReal() // pos in cm
{
setStatusPosReal(mWorldImageCorrespondence->getPosReal(mMousePosOnImage, getStatusPosRealHeight()));
void Petrack::setStatusPosReal(const QPointF &pos) // pos in cm
{
QChar deg(0xB0);
QString labelText = QString(" cm from ground:%1cm,%2cm,%3")
.arg(pos.x(), 6, 'f', 1)
.arg(pos.y(), 6, 'f', 1)
.arg(
mWorldImageCorrespondence->getAngleToGround(
mMousePosOnImage.x(), mMousePosOnImage.y(), getStatusPosRealHeight()),
5,
'f',
1);
labelText.append(deg);
mStatusLabelPosReal->setText(labelText);
}
}
void Petrack::setStatusPos(const QPoint &pos) // pos in pixel
{
mStatusLabelPos->setText(QString("%1x%2").arg(pos.x(), 4).arg(pos.y(), 4));
}
void Petrack::setStatusColor(const QRgb &col)
{
QString s("#%1%2%3"); // static moeglich?
s = s.arg(qRed(col), 2, 16, QChar('0')).arg(qGreen(col), 2, 16, QChar('0')).arg(qBlue(col), 2, 16, QChar('0'));
if((qRed(col) + qGreen(col) + qBlue(col)) / 3 < 128)
mStatusLabelColor->setText(QString("<font color=\"#ffffff\"> %1</font>").arg(s));
mStatusLabelColor->setText(QString("<font color=\"#000000\"> %1</font>").arg(s));
QPalette pal = mStatusLabelColor->palette(); // static moeglich?
QColor color(qRed(col), qGreen(col), qBlue(col));
pal.setColor(QPalette::Window, color);
mStatusLabelColor->setPalette(pal);
mControlWidget->getColorPlot()->setCursor(color);
mControlWidget->getColorPlot()->replot();
}
void Petrack::setStatusColor()
{
QPointF pos = getMousePosOnImage();
if(pos.x() >= 0 && pos.x() < mImage->width() && pos.y() > 0 && pos.y() < mImage->height())
setStatusColor(mImage->pixel(pos.toPoint()));
}
}
double Petrack::getStatusPosRealHeight()
{
/**
* @brief Reads (and applies) settings form platform-independent persistent storage
*
* The saved size and position of the application window get reconstructed. As well as
* the options about antialiasing and the usage of OpenGL.
* mSeqFileName and mProFileName get set, so the "Open Project" and "Open Sequence"
* dialogues start at correct folder. The old project/sequence is NOT actually loaded.
*/
const QSettings settings("Forschungszentrum Juelich GmbH", "PeTrack by Maik Boltes, Daniel Salden");
mAntialiasAct->setChecked(settings.value("antialias", false).toBool());
mOpenGLAct->setChecked(settings.value("opengl", false).toBool());
mSeqFileName = settings.value("seqFileName", QDir::currentPath()).toString();
setProFileName(settings.value("proFilePath", QDir::currentPath()).toString());
// nicht ganz sauber, da so immer schon zu anfang in calib file list etwas drin steht und somit auto ausgefuehrt
// werden kann wird aber beim ersten openCalib... ueberschrieben
mAutoCalib.addCalibFile(settings.value("calibFile", QDir::currentPath()).toString());
auto geometry = settings.value("geometry").toByteArray();
restoreGeometry(geometry);
mSplitter->restoreState(settings.value("controlSplitterSizes").toByteArray());
mAutosave.setPetSaveInterval(settings.value("petSaveInterval", 120).toDouble());
mAutosave.setChangesTillAutosave(settings.value("changesTillAutosave", 10).toInt());
/**
* @brief Writes persistent setting.
* @see Petrack::readSettings
*/
void Petrack::writeSettings()
{
QSettings settings("Forschungszentrum Juelich GmbH", "PeTrack by Maik Boltes, Daniel Salden");
settings.setValue("geometry", saveGeometry());
settings.setValue("antialias", mAntialiasAct->isChecked());
settings.setValue("opengl", mOpenGLAct->isChecked());
settings.setValue("seqFileName", mSeqFileName);
settings.setValue("proFilePath", QFileInfo(mProFileName).path()); // nur path, damit bei saveCurrentProject
if(!mAutoCalib.isEmptyCalibFiles()) //! mCalibFiles.isEmpty()
settings.setValue("controlSplitterSizes", mSplitter->saveState());
settings.setValue("petSaveInterval", mAutosave.getPetSaveInterval());
settings.setValue("changesTillAutosave", mAutosave.getChangesTillAutosave());
int ret = PWarning(
this,
tr("PeTrack"),
tr("Do you want to save "
"the current project?\n"
"Be sure to save trajectories, background "
"and 3D calibration point separately!"),
PMessageBox::StandardButton::Yes | PMessageBox::StandardButton::No | PMessageBox::StandardButton::Cancel,
PMessageBox::StandardButton::Yes);
if(ret == PMessageBox::StandardButton::Yes)
else if(ret == PMessageBox::StandardButton::Cancel)
}
void Petrack::closeEvent(QCloseEvent *event)
{
/**
* @brief Sets the mMousePosOnImage member variable and displayed pixel/real coordinates
*
* Gets called from ImageItem::hoverMoveEvent() and enables an easy access
* to the mouse position.
* @param pos Position of mouse cursor in image pixel coordinates
*/
setStatusPosReal(mWorldImageCorrespondence->getPosReal(pos, getStatusPosRealHeight()));
QPoint pos1((int) (pos.x()) + 1, (int) (pos.y()) + 1);
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
void Petrack::keyPressEvent(QKeyEvent *event)
{
switch(event->key())
{
case Qt::Key_Left:
mPlayerWidget->frameBackward();
break;
case Qt::Key_Right:
mPlayerWidget->frameForward();
break;
case Qt::Key_Down:
mViewWidget->zoomOut(1);
break;
case Qt::Key_Up:
mViewWidget->zoomIn(1);
break;
case Qt::Key_Space:
// space wird von buttons, wenn focus drauf ist als Aktivierung vorher abgegriffen und nicht durchgereicht
mPlayerWidget->togglePlayPause();
break;
case Qt::Key_D:
break;
default:;
}
}
void Petrack::mousePressEvent(QMouseEvent *event)
{
// mouse click in fps status label ?
if(event->pos().x() >= mStatusLabelFPS->pos().x() &&
event->pos().x() <= mStatusLabelFPS->pos().x() + mStatusLabelFPS->width())
mPlayerWidget->togglePlayerSpeedLimited();
const QString &Petrack::getLastTrackerExport() const
{
return mLastTrackerExport;
}
void Petrack::setLastTrackerExport(const QString &newLastTrackerExport)
{
mLastTrackerExport = newLastTrackerExport;
}
/// update control widget, if image size changed (especially because of changing border)
void Petrack::updateControlImage(cv::Mat &img)
{
// auch moeglich hoehe und breite von bild stat border veraenderungen zu checken
static int lastBorderSize = -1;
if(lastBorderSize != -1)
diffBorderSize = getImageBorderSize() - lastBorderSize;
lastBorderSize = getImageBorderSize();
const int imgWidth = img.cols;
const int imgHeight = img.rows;
// no direct invocation to have correct order of invocations
// (direct invocation gets executed immediately, i.e. before queued connection)
QMetaObject::invokeMethod(
mControlWidget,
"imageSizeChanged",
Qt::ConnectionType::QueuedConnection,
Q_ARG(int, imgWidth),
Q_ARG(int, imgHeight),
Q_ARG(int, diffBorderSize));
void Petrack::importTracker(QString dest) // default = ""
dest = QFileDialog::getOpenFileName(
this,
tr("Select file for importing tracking pathes"),
lastFile,
tr("PeTrack tracker (*.trc *.txt);;All files (*.*)"));
if(dest.endsWith(".trc", Qt::CaseInsensitive))
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
// errorstring ist je nach Betriebssystem in einer anderen Sprache!!!!
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2").arg(dest).arg(file.errorString()));
setTrackChanged(true); // flag changes of track parameters
bool ok; // shows if int stands in first line - that was in the first version of trc file
sz = firstLine.toInt(&ok);
if(!ok)
if(firstLine.contains("version 4", Qt::CaseInsensitive))
{
trcVersion = 4;
}
else if(firstLine.contains("version 3", Qt::CaseInsensitive))
else if(firstLine.contains("version 2", Qt::CaseInsensitive))
}
else
SPDLOG_ERROR("wrong header while reading TRC file.");
QMessageBox::critical(
this,
tr("PeTrack"),
tr("Could not import tracker:\nNot supported trc version in file: %1.").arg(dest));
Schrödter, Tobias
committed
return;
if((sz > 0) && (mPersonStorage.nbPersons() != 0))
SPDLOG_WARN("overlapping trajectories will be joined not until tracking adds new TrackPoints.");
TrackPerson tp = fromTrc(in);
mPersonStorage.addPerson(tp);
mControlWidget->setTrackNumberAll(QString("%1").arg(mPersonStorage.nbPersons()));
mControlWidget->setTrackShowOnlyNr(static_cast<int>(MAX(mPersonStorage.nbPersons(), 1)));
mControlWidget->setTrackNumberVisible(
QString("%1").arg(mPersonStorage.visible(mAnimation->getCurrentFrameNum())));
mControlWidget->replotColorplot();
SPDLOG_INFO("import {} ({} person(s), file version {})", dest, sz, trcVersion);
mTrcFileName =
dest; // fuer Project-File, dann koennte track path direkt mitgeladen werden, wenn er noch da ist
}
else if(dest.endsWith(".txt", Qt::CaseInsensitive)) // 3D Koordinaten als Tracking-Daten importieren
// Zeilenformat: Personennr, Framenr, x, y, z
PWarning(
this,
tr("PeTrack"),
tr("Are you sure you want to import 3D data from TXT-File? You have to make sure that the coordinate "
"system now is exactly at the same position and orientation than at export time!"));
int numberImportedPersons = 0;
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
// errorstring ist je nach Betriebssystem in einer anderen Sprache!!!!
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2").arg(dest).arg(file.errorString()));
setTrackChanged(true); // flag changes of track parameters
bool unitFound = false;
double conversionFactorToCM = 1.0;
std::unordered_map<int, std::map<int, Vec3F>> personData;
QString headerline;
while(in.readLineInto(&line))
{
if(line.startsWith("#", Qt::CaseInsensitive))
if((!unitFound) && (!headerline.contains("cm")))
conversionFactorToCM = 100.0;
unitFound = true;
PWarning(
this,
tr("PeTrack"),
tr("PeTrack will interpret position data as unit [m]. No header with [cm] found."));
// Read data from line with format: persNr frameNr x y z
int personNr = -1, frameNr = -1;
float x, y, z;
QTextStream stream(&line);
stream >> personNr >> frameNr >> x >> y >> z;
x = x * conversionFactorToCM;
y = y * conversionFactorToCM;
z = z * conversionFactorToCM;
if(personData[personNr].find(frameNr) == personData[personNr].end())
personData[personNr][frameNr] = Vec3F(x, y, z);
PCritical(
this,
"Error importing txt file",
tr("Could not import the data from the provided txt file, as the data for person %1 in frame "
"%1 is twice in the txt-file.")
.arg(personNr)
.arg(frameNr));
return;
for(auto &[persNr, frameData] : personData)
{
std::deque<TrackPoint> pixelPoints;
for(auto &[frameNr, realWorldCoordinates] : frameData)
if(mControlWidget->getCalibCoordDimension() == 0)
{
// compute image point from 3d calibration
p2d = mExtrCalibration.getImagePoint(
cv::Point3f(realWorldCoordinates.x(), realWorldCoordinates.y(), realWorldCoordinates.z()));
}
else
{
// compute image point from 2d calibration
QPointF pos = mWorldImageCorrespondence->getPosImage(
QPointF(realWorldCoordinates.x(), realWorldCoordinates.y()), realWorldCoordinates.z());
p2d.x = pos.x();
p2d.y = pos.y();
}
TrackPoint trackPoint(Vec2F(p2d.x, p2d.y), 100);
trackPoint.setSp(
realWorldCoordinates.x(),
realWorldCoordinates.y(),
-mControlWidget->getExtrinsicParameters().trans3 -
realWorldCoordinates.z()); // distance to camera as with stereo cameras
pixelPoints.push_back(trackPoint);
TrackPerson trackPerson(persNr, frameData.begin()->first, pixelPoints.front());
trackPerson.setHeight(frameData.begin()->second.z());
pixelPoints.pop_front();
for(const auto &trackPoint : pixelPoints)
trackPerson.append(trackPoint);
mPersonStorage.addPerson(trackPerson);
numberImportedPersons++;
mControlWidget->setTrackNumberAll(QString("%1").arg(mPersonStorage.nbPersons()));
mControlWidget->setTrackShowOnlyNr(static_cast<int>(MAX(mPersonStorage.nbPersons(), 1)));
mControlWidget->setTrackNumberVisible(
QString("%1").arg(mPersonStorage.visible(mAnimation->getCurrentFrameNum())));
mControlWidget->replotColorplot();
SPDLOG_INFO("import {} ({} person(s))", dest, numberImportedPersons);
mTrcFileName = dest;
PCritical(this, tr("PeTrack"), tr("Cannot load %1 maybe because of wrong file extension.").arg(dest));
}
lastFile = dest;
}
}
int Petrack::calculateRealTracker()
{
bool autoCorrectOnlyExport = (mReco.getRecoMethod() == reco::RecognitionMethod::MultiColor) && // multicolor
mMultiColorMarkerWidget->autoCorrect->isChecked() &&
mMultiColorMarkerWidget->autoCorrectOnlyExport->isChecked();
int anz = mTrackerReal->calculate(
mWorldImageCorrespondence,
mControlWidget->getAnaMissingFrames(),
mStereoWidget->stereoUseForExport->isChecked(),
mControlWidget->getTrackAlternateHeight(),
mControlWidget->getCameraAltitude(),
mStereoWidget->stereoUseCalibrationCenter->isChecked(),
mControlWidget->isExportElimTpChecked(),
mControlWidget->isExportElimTrjChecked(),
mControlWidget->isExportSmoothChecked(),
mControlWidget->isExportViewDirChecked(),
mControlWidget->isExportAngleOfViewChecked(),
mControlWidget->isExportMarkerIDChecked(),
void Petrack::exportTracker(QString dest) // default = ""
Schrödter, Tobias
committed
try
Schrödter, Tobias
committed
if(!mTracker)
{
return;
}
QFileDialog fileDialog(
this,
Schrödter, Tobias
committed
tr("Select file for exporting tracking paths"),
tr("Tracker (*.*);;Petrack tracker (*.trc);;Text (*.txt);;Text for gnuplot(*.dat);;XML Travisto "
"(*.trav);;All supported types (*.txt *.trc *.dat *.trav *.);;All files (*.*)"));
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
fileDialog.setFileMode(QFileDialog::AnyFile);
fileDialog.setDefaultSuffix("");
Schrödter, Tobias
committed
if(dest.isEmpty())
{
return;
}
Schrödter, Tobias
committed
QList<int> pers, frame;
bool autoCorrectOnlyExport = (mReco.getRecoMethod() == reco::RecognitionMethod::MultiColor) && // multicolor
mMultiColorMarkerWidget->autoCorrect->isChecked() &&
mMultiColorMarkerWidget->autoCorrectOnlyExport->isChecked();
if(dest.endsWith(".trc", Qt::CaseInsensitive))
{
QTemporaryFile file;
Schrödter, Tobias
committed
if(!file.open() /*!file.open(QIODevice::WriteOnly | QIODevice::Text)*/)
{
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString()));
return;
}
QProgressDialog progress(
"Export TRC-File", nullptr, 0, static_cast<int>(mPersonStorage.nbPersons() + 1), this->window());
progress.setWindowTitle("Export .trc-File");
progress.setWindowModality(Qt::WindowModal);
progress.setVisible(true);
progress.setValue(0);
progress.setLabelText(QString("Export tracking data ..."));
Schrödter, Tobias
committed
qApp->processEvents();
Schrödter, Tobias
committed
trcVersion = 4;
Schrödter, Tobias
committed
SPDLOG_INFO(
"export tracking data to {} ({} person(s), file version {})",
dest,
mPersonStorage.nbPersons(),
trcVersion);
QTextStream out(&file);
out << "version " << trcVersion << Qt::endl;
out << mPersonStorage.nbPersons() << Qt::endl;
const auto &persons = mPersonStorage.getPersons();
for(size_t i = 0; i < persons.size(); ++i)
{
progress.setLabelText(QString("Export person %1 of %2 ...").arg(i + 1).arg(mPersonStorage.nbPersons()));
progress.setValue(static_cast<int>(i + 1));
out << persons[i] << Qt::endl;
}
file.flush();
file.close();
progress.setLabelText(QString("Save file ..."));
qApp->processEvents();
Schrödter, Tobias
committed
if(QFile::exists(dest))
{
QFile::remove(dest);
}
Schrödter, Tobias
committed
if(!file.copy(dest))
{
PCritical(
this,
tr("PeTrack"),
tr("Could not export tracking data.\n"
"Please try again!"));
}
else
{
statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000);
}
Schrödter, Tobias
committed
progress.setValue(static_cast<int>(mPersonStorage.nbPersons() + 1));
Schrödter, Tobias
committed
SPDLOG_INFO("finished.");
mAutosave.resetTrackPersonCounter();
mTrcFileName =
dest; // fuer Project-File, dann koennte track path direkt mitgeladen werden, wenn er// noch da ist
Schrödter, Tobias
committed
}
else if(dest.endsWith(".txt", Qt::CaseInsensitive))
Schrödter, Tobias
committed
{
QTemporaryFile file;
Schrödter, Tobias
committed
if(!file.open())
{
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString()));
return;
}
Schrödter, Tobias
committed
SPDLOG_INFO("export tracking data to {} ({} person(s))...", dest, mPersonStorage.nbPersons());
// recalcHeight true, wenn personenhoehe ueber trackpoints neu berechnet werden soll (z.b. um
Schrödter, Tobias
committed
// waehrend play mehrfachberuecksichtigung von punkten auszuschliessen, aenderungen in altitude neu
// in berechnung einfliessen zu lassen)
if(mControlWidget->isTrackRecalcHeightChecked())
{
if(mControlWidget->getCalibCoordDimension() == 0) // 3D
; // Nothing to be done because z already the right height
}
else // 2D
{
mPersonStorage.recalcHeight(mControlWidget->getCameraAltitude());
mTrackerReal->calculate(
this,
mTracker,
mWorldImageCorrespondence,
mControlWidget->getColorPlot(),
mMissingFrames,
getImageBorderSize(),
mControlWidget->isTrackMissingFramesChecked(),
mStereoWidget->stereoUseForExport->isChecked(),
mControlWidget->getTrackAlternateHeight(),
mControlWidget->getCameraAltitude(),
mStereoWidget->stereoUseCalibrationCenter->isChecked(),
mControlWidget->isExportElimTpChecked(),
mControlWidget->isExportElimTrjChecked(),
mControlWidget->isExportSmoothChecked(),
mControlWidget->isExportViewDirChecked(),
mControlWidget->isExportAngleOfViewChecked(),
mControlWidget->isExportMarkerIDChecked(),
autoCorrectOnlyExport);
Schrödter, Tobias
committed
QTextStream out(&file);
Schrödter, Tobias
committed
out << "# PeTrack project: " << QFileInfo(getProFileName()).fileName() << Qt::endl;