Newer
Older
#ifdef TIME_MEASUREMENT
// time1 += clock() - tstart;
// time1 = time1/CLOCKS_PER_SEC;
// cout << " time(checkPlausibility) = " << time1 << " sec." << endl;
#endif
}
else if(dest.right(4) == ".dat")
if(!fileDat.open()) //! fileDat.open(QIODevice::WriteOnly | QIODevice::Text))
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(fileDat.errorString()));
// recalcHeight true, wenn personenhoehe ueber trackpoints neu berechnet werden soll (z.b. um waehrend
// play mehrfachberuecksichtigung von punkten auszuschliessen, aenderungen in altitude neu in berechnung
// einfliessen zu lassen)
if(mControlWidget->isTrackRecalcHeightChecked())
mPersonStorage.recalcHeight(mControlWidget->getCameraAltitude());
mTracker,
mImageItem,
mControlWidget->getColorPlot(),
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(),
debout << "export tracking data to " << dest << " (" << mPersonStorage.nbPersons() << " person(s))..."
outDat, mControlWidget->getTrackAlternateHeight(), mStereoWidget->stereoUseForExport->isChecked());
PCritical(
this,
tr("PeTrack"),
tr("Could not export tracking data.\n"
"Please try again!"));
statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000);
std::cout << " finished" << std::endl;
else if(dest.right(5) == ".trav")
// recalcHeight true, wenn personenhoehe ueber trackpoints neu berechnet werden soll (z.b. um waehrend
// play mehrfachberuecksichtigung von punkten auszuschliessen, aenderungen in altitude neu in berechnung
// einfliessen zu lassen)
if(mControlWidget->isTrackRecalcHeightChecked())
mPersonStorage.recalcHeight(mControlWidget->getCameraAltitude());
mTracker,
mImageItem,
mControlWidget->getColorPlot(),
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(),
if(!fileXml.open()) //! fileXml.open(QIODevice::WriteOnly | QIODevice::Text))
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(fileXml.errorString()));
debout << "export tracking data to " << dest << " (" << mPersonStorage.nbPersons() << " person(s))..."
<< std::endl;
// already done: mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(),
// getImageBorderSize(), mControlWidget->isTrackMissingFramesChecked());
outXml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << Qt::endl;
outXml << "<trajectoriesDataset>" << Qt::endl;
outXml << " <header version=\"1.0\">" << Qt::endl;
outXml << " <roomCaption>PeTrack: " << mAnimation->getFileBase() << "</roomCaption>" << Qt::endl;
outXml << " <roomID>0</roomID>" << Qt::endl;
outXml << " <agents>" << mPersonStorage.nbPersons() << "</agents>" << Qt::endl;
outXml << " <frameRate>" << mAnimation->getFPS() << "</frameRate> <!--per second-->" << Qt::endl;
// outXml << " <timeStep>" << 1000./mAnimation->getFPS() << "</timeStep> <!-- millisecond-->"
// << endl; inverse von
outXml << " <timeFirstFrame sec=\"" << mAnimation->getFirstFrameSec() << "\" microsec=\""
<< mAnimation->getFirstFrameMicroSec() << "\"/> <!-- " << mAnimation->getTimeString(0) << " -->"
<< Qt::endl;
outXml << " </header>" << Qt::endl << Qt::endl;
mTrackerReal->exportXml(
outXml, mControlWidget->getTrackAlternateHeight(), mStereoWidget->stereoUseForExport->isChecked());
outXml << "</trajectoriesDataset>" << Qt::endl;
PCritical(
this,
tr("PeTrack"),
tr("Could not export tracking data.\n"
"Please try again!"));
statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000);
std::cout << " finished" << std::endl;
}
else
{ // wenn keine Dateiendung, dann wird trc und txt herausgeschrieben
exportTracker(dest + ".trc");
exportTracker(dest + ".txt");
}
mLastTrackerExport = dest;
}
}
}
// fuer anschliessende groessenberechnung
void Petrack::playAll()
{
int memPos = mPlayerWidget->getPos();
int progVal = 0;
QProgressDialog progress("Playing whole sequence...", "Abort playing", 0, mAnimation->getNumFrames(), this);
progress.setWindowModality(Qt::WindowModal); // blocks main window
// vorwaertslaufen ab aktueller Stelle und trackOnlineCalc zum tracken nutzen
do
{
progress.setValue(++progVal); // mPlayerWidget->getPos()
} while(mPlayerWidget->frameForward());
/**
* @brief Activates tracking and reco; calcs through the video (in both ways)
*
* This method activates tracking and reco and plays the whole video (from current
* frame on) till the end. Then, if mAutoBackTrack is set, it jumps back to the
* largest first frame, i.e. the last time a new person was added/recognized, and
* tracks backwards till the beginning of the video.
*
* The old settings for tracking and reco will be restored. No interaction with the
* main window is possible for the time of tracking.
*/
int memPos = mPlayerWidget->getPos();
int progVal = 0;
bool memCheckState = mControlWidget->isOnlineTrackingChecked();
bool memRecoState = mControlWidget->isPerformRecognitionChecked();
mControlWidget->setOnlineTrackingChecked(true);
mControlWidget->setPerformRecognitionChecked(true);
QProgressDialog progress(
"Tracking pedestrians through all frames...",
"Abort tracking",
0,
2 * mAnimation->getNumFrames() - memPos,
this);
progress.setWindowModality(Qt::WindowModal); // blocks main window
// vorwaertslaufen ab aktueller Stelle und trackOnlineCalc zum tracken nutzen
do
{
progress.setValue(++progVal); // mPlayerWidget->getPos()
} while(mPlayerWidget->frameForward());
{
// zuruecksprinegn an die stelle, wo der letzte trackPath nicht vollstaendig
// etwas spaeter, da erste punkte in reco path meist nur ellipse ohne markererkennung
mControlWidget->setOnlineTrackingChecked(false);
mPlayerWidget->skipToFrame(mPersonStorage.largestFirstFrame() + 5);
mControlWidget->setOnlineTrackingChecked(true);
// progVal = 2*mAnimation->getNumFrames()-memPos-mPlayerWidget->getPos();
progVal += mAnimation->getNumFrames() - mPlayerWidget->getPos();
progress.setValue(progVal); // mPlayerWidget->getPos()
// recognition abstellen, bis an die stelle, wo trackAll begann
// UEBERPRUEFEN, OB TRACKPATH NICHT RECOGNITION PUNKTE UEBERSCHREIBT!!!!!!!!!!
// repeate und repaetQual koennte temporaer umgestellt werden
mControlWidget->setPerformRecognitionChecked(false);
if(progVal + 1 < 2 * mAnimation->getNumFrames() - memPos)
progress.setValue(++progVal); // mPlayerWidget->getPos()
if(mPlayerWidget->getPos() == memPos + 1)
mControlWidget->setPerformRecognitionChecked(true);
} while(mPlayerWidget->frameBackward());
// bei abbruch koennen es auch mPlayerWidget->getPos() frames sein, die bisher geschrieben wurden
progress.setValue(2 * mAnimation->getNumFrames() - memPos);
mPersonStorage.optimizeColor();
mControlWidget->setPerformRecognitionChecked(memRecoState);
mControlWidget->setOnlineTrackingChecked(false);
mControlWidget->setOnlineTrackingChecked(memCheckState);
}
// default: (QPointF *pos=NULL, int pers=-1, int frame=-1);
int Petrack::winSize(QPointF *pos, int pers, int frame, int level)
{
// default of mControlWidget->trackRegionScale->value() is 16, so that
// a factor of 1.6 of the headsize is used
level = mControlWidget->getTrackRegionLevels();
return (int) ((getHeadSize(pos, pers, frame) / pow(2., level)) * (mControlWidget->getTrackRegionScale() / 10.));
}
void Petrack::updateImage(bool imageChanged) // default = false (only true for new animation frame)
{
#ifdef TIME_MEASUREMENT
// die reine Ausgabe folgender Zeile kostet 1-2 Millisekunden
// "==========: "
debout << "go update: " << getElapsedTime() << endl;
mCodeMarkerItem->resetSavedMarkers();
static int lastRecoFrame = -10000;
// need semaphore to guarrantee that updateImage only called once
// updateValue of control automatically calls updateImage!!!
static QSemaphore semaphore(1);
if(!mImg.empty() && mImage && semaphore.tryAcquire())
{
int frameNum = mAnimation->getCurrentFrameNum();
setStatusTime();
updateShowFPS();
mImgFiltered = mImg;
// have to store because evaluation sets the filter parameter to unchanged
bool brightContrastChanged = mBrightContrastFilter.changed();
bool swapChanged = mSwapFilter.changed();
bool borderChanged = mBorderFilter.changed();
bool calibChanged = mCalibFilter->changed();
// speicherverwaltung wird komplett von filtern ueberneommen
// Filter anwenden, Reihenfolge wichtig - Rechenintensive moeglichst frueh
// fkt so nur mit kopierenden filtern
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "vor filter: " << getElapsedTime() << endl;
if(imageChanged || swapChanged || brightContrastChanged)
if(imageChanged || swapChanged || brightContrastChanged || borderChanged)
// "==========: "
debout << "nch filter: " << getElapsedTime() << endl;
#ifndef STEREO_DISABLED
if(imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged)
// "==========: "
debout << "vor calib: " << getElapsedTime() << endl;
if(imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged)
// "==========: "
debout << "nach calib: " << getElapsedTime() << endl;
if(brightContrastChanged || swapChanged || borderChanged || calibChanged)
// abfrage hinzugenommen, damit beim laden von .pet bg-file angegeben werden kann fuer mehrere versuche und
// beim nachladen von versuch nicht bg geloescht wird
if(mBackgroundFilter.getFilename() != "")
debout << "Warning: No background reset, because of explicit loaded background image!" << std::endl;
mBackgroundFilter
.reset(); // alle gesammelten hintergrundinfos werden verworfen und bg.changed auf true gesetzt
if(imageChanged || mBackgroundFilter.changed())
// "==========: "
debout << "nach bg: " << getElapsedTime() << endl;
#endif
// delete track list, if intrinsic param have changed
if(calibChanged && mPersonStorage.nbPersons() > 0) // mCalibFilter.getEnabled() &&
{
// Evtl. nicht Tracker loeschen sondern entsprechend der neuen Calibration verschieben?!?!?
debout << "Warning: deleted all tracking pathes because intrinsic parameters have changed."
<< std::endl;
#ifndef STEREO_DISABLED
// calculate position in 3D space and height of person for "old" trackPoints, if checked "even"
if(mStereoContext && mStereoWidget->stereoUseForHeightEver->isChecked() &&
mStereoWidget->stereoUseForHeight->isChecked())
{
// buildt disparity picture if it should be used for height detection
mStereoContext->getDisparity();
mPersonStorage.calcPosition(frameNum);
// tracking vor recognition, da dann neu gefundene punkte mit getrackten bereits ueberprueft werden koennen
if((trackChanged() || imageChanged) && (mControlWidget->isOnlineTrackingChecked())) // borderChanged ???
QRect roi(
myRound(mTrackingRoiItem->rect().x() + getImageBorderSize()),
myRound(mTrackingRoiItem->rect().y() + getImageBorderSize()),
myRound(mTrackingRoiItem->rect().width()),
myRound(mTrackingRoiItem->rect().height()));
size.height = mImgFiltered.rows;
mTracker->resize(size);
mTrackingRoiItem->restoreSize();
#ifndef STEREO_DISABLED
// buildt disparity picture if it should be used for height detection
if(mStereoContext && mStereoWidget->stereoUseForHeight->isChecked())
getRoi(mImgFiltered, roi, rect);
// Ignore all tracking points outside of rect
// if (mPrevIplImgFiltered) // wenn ein vorheriges bild vorliegt
// mPrevIplImgFiltered == NULL zeigt an, dass neue bildfolge && mPrevFrame == -1 ebenso
// winSize(), wurde mal uebergeben
debout << "vor track: " << getElapsedTime() << endl;
// debout << "test" << endl;
int anz = mTracker->track(
mImgFiltered,
rect,
frameNum,
mControlWidget->isTrackRepeatChecked(),
mControlWidget->getTrackRepeatQual(),
getImageBorderSize(),
mReco.getRecoMethod(),
mControlWidget->getTrackRegionLevels(),
debout << "nach track: " << getElapsedTime() << endl;
mControlWidget->setTrackNumberNow(QString("%1").arg(anz));
mControlWidget->setTrackNumberNow(QString("0"));
// hier muesste fuer ameisen etc allgemeinABC.getPosList(...)
if(((((lastRecoFrame + mControlWidget->getRecoStep()) <= frameNum) ||
((lastRecoFrame - mControlWidget->getRecoStep()) >= frameNum)) &&
imageChanged) ||
mAnimation->isCameraLiveStream() || swapChanged || brightContrastChanged || borderChanged || calibChanged ||
recognitionChanged())
#ifndef STEREO_DISABLED
// buildt disparity picture if it should be used for height detection or recognition
if(mStereoContext &&
(mStereoWidget->stereoUseForHeight->isChecked() || mStereoWidget->stereoUseForReco->isChecked()))
mStereoContext->getDisparity(); // wird nicht neu berechnet, wenn vor tracking schon berechnet wurde
mRecognitionRoiItem->restoreSize();
if(mControlWidget->isPerformRecognitionChecked())
QRect rect(
myRound(mRecognitionRoiItem->rect().x() + getImageBorderSize()),
myRound(mRecognitionRoiItem->rect().y() + getImageBorderSize()),
myRound(mRecognitionRoiItem->rect().width()),
myRound(mRecognitionRoiItem->rect().height()));
auto recoMethod = mReco.getRecoMethod();
debout << "vor reco: " << getElapsedTime() << endl;
if((recoMethod == reco::RecognitionMethod::Casern) || (recoMethod == reco::RecognitionMethod::Hermes) ||
(recoMethod == reco::RecognitionMethod::Color) || (recoMethod == reco::RecognitionMethod::Japan) ||
(recoMethod == reco::RecognitionMethod::MultiColor) ||
(recoMethod == reco::RecognitionMethod::Code)) // else
persList = mReco.getMarkerPos(
mImgFiltered, rect, mControlWidget, getImageBorderSize(), getBackgroundFilter());
#ifndef STEREO_DISABLED
if(mStereoContext && mStereoWidget->stereoUseForReco->isChecked())
pl.calcPersonPos(mImgFiltered, rect, &persList, mStereoContext, getBackgroundFilter(), markerLess);
debout << "nach reco: " << getElapsedTime() << endl;
mPersonStorage.addPoints(persList, frameNum, mReco.getRecoMethod());
// folgendes lieber im Anschluss, ggf beim exportieren oder statt test direkt del:
if(mStereoContext && mStereoWidget->stereoUseForReco->isChecked())
mPersonStorage.purge(frameNum); // bereinigen wenn weniger als 0.2 recognition und nur getrackt
mControlWidget->setRecoNumberNow(QString("%1").arg(persList.size()));
if(false) // hier muss Abfage hin ob kasernen marker genutzt wird
mControlWidget->getColorPlot()
->replot(); // oder nur wenn tab offen oder wenn sich mtracker geaendert hat???
mControlWidget->setRecoNumberNow(QString("0"));
mControlWidget->setRecoNumberNow(QString("0"));
mControlWidget->setTrackNumberAll(
QString("%1").arg(mPersonStorage.nbPersons())); // kann sich durch reco und tracker aendern
mControlWidget->setTrackShowOnlyNrMaximum(
static_cast<int>(MAX(mPersonStorage.nbPersons(), 1))); // kann sich durch reco und tracker aendern
mControlWidget->setTrackNumberVisible(
QString("%1").arg(mPersonStorage.visible(frameNum))); // kann sich durch reco und tracker aendern
// in anzuzeigendes Bild kopieren
// erst hier wird die bildgroesse von mimage an filteredimg mit border angepasst
copyToQImage(*mImage, mImgFiltered);
getScene()->update(); // repaint();
// update pixel color (because image pixel moves)
setStatusColor();
}
#ifdef QWT
mControlWidget->getAnalysePlot()->setActFrame(frameNum);
if(mControlWidget->isAnaMarkActChecked())
{
mControlWidget->getAnalysePlot()->replot();
}
#endif
semaphore.release();
}
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "stp update: " << getElapsedTime() << endl;
void Petrack::updateImage(const cv::Mat &img)
{
mImg = img;
updateImage(true);
}
void Petrack::updateSequence()
{
QImage *oldImage = mImage;
QSize size = mAnimation->getSize();
size.setWidth(size.width() + 2 * getImageBorderSize()); // border is inside the mImage!
size.setHeight(size.height() + 2 * getImageBorderSize());
mImage = new QImage(size, QImage::Format_RGB888); // 32); //wird in updateImage gemacht
// set roi for recognition if image size changes or roi is zero
// in oldImage steckt border drin, mIplImg->height zeigt noch auf altes ursprungsbild
// mRecognitionRoiItem->rect().width() != 0 && oldImage == NULL wenn projektdatei eingelesen wird!!!!!
if((mRecognitionRoiItem->rect().width() == 0) || // default while initialization, after that >= MIN_SIZE
(oldImage && ((oldImage->width() != mImage->width()) || (oldImage->height() != mImage->height()))))
mRecognitionRoiItem->setRect(-getImageBorderSize(), -getImageBorderSize(), mImage->width(), mImage->height());
if((mTrackingRoiItem->rect().width() == 0) ||
(oldImage && ((oldImage->width() != mImage->width()) || (oldImage->height() != mImage->height()))))
mTrackingRoiItem->setRect(-getImageBorderSize(), -getImageBorderSize(), mImage->width(), mImage->height());
size2.width = mTrackingRoiItem->rect().width();
size2.height = mTrackingRoiItem->rect().height();
mTracker->init(size2);
mPlayerWidget->setAnim(mAnimation);
mPlayerWidget->skipToFrame(0);
mImageItem->setImage(mImage); // wird in updateImage gemacht
delete oldImage;
mSaveSeqVidAct->setEnabled(true);
mSaveSeqVidViewAct->setEnabled(true);
mSaveSeqImgAct->setEnabled(true);
mSaveSeqViewAct->setEnabled(true);
mSaveImageAct->setEnabled(true);
mSaveViewAct->setEnabled(true);
mPrintAct->setEnabled(true);
mResetSettingsAct->setEnabled(true);
}
/**
* @brief Gets cm per pixel. Only recalculates when calculating head size.
* @return cm per pixel
*/
double Petrack::getCmPerPixel() const
/**
* @brief Sets the size of the circle of the average head circumference in pixel.
*
* Assumption for default calculation: <br>
* 21cm avg head length <br>
* default height of person according to mapDefaultHeigt <br>
*
* Default case recalculates mCmPerPixel
*
* If headsize get recalulated also mCmPerPixel will be calculated!
* @see Petrack::getCmPerPixel
* @param hS new headsize, if hS==-1 mHeadSize will be calculated instead of set
// debout << mCmPerPixel <<endl;
mHeadSize = (HEAD_SIZE * mControlWidget->getCameraAltitude() /
(mControlWidget->getCameraAltitude() - mControlWidget->getDefaultHeight())) /
}
// gibt Kopfgroesse zurueck
// default: (QPointF *pos=NULL, int pers=-1, int frame=-1)
double Petrack::getHeadSize(QPointF *pos, int pers, int frame)
{
double z, h;
if((pers >= 0) && (pers < static_cast<int>(mPersonStorage.nbPersons())) &&
mPersonStorage.at(pers).trackPointExist(frame))
if(mControlWidget->getCalibCoordDimension() == 0)
int diff;
cv::Point3f p3d = getExtrCalibration()->get3DPoint(
cv::Point2f(
mPersonStorage.at(pers).trackPointAt(frame).x(), mPersonStorage.at(pers).trackPointAt(frame).y()),
mControlWidget->getDefaultHeight());
cv::Point2f p3d_x1 =
getExtrCalibration()->getImagePoint(cv::Point3f(p3d.x + HEAD_SIZE * 0.5, p3d.y, p3d.z));
cv::Point2f p3d_x2 =
getExtrCalibration()->getImagePoint(cv::Point3f(p3d.x - HEAD_SIZE * 0.5, p3d.y, p3d.z));
cv::Point2f p3d_y1 =
getExtrCalibration()->getImagePoint(cv::Point3f(p3d.x, p3d.y + HEAD_SIZE * 0.5, p3d.z));
cv::Point2f p3d_y2 =
getExtrCalibration()->getImagePoint(cv::Point3f(p3d.x, p3d.y - HEAD_SIZE * 0.5, p3d.z));
diff = (int) std::max(
sqrt(pow(p3d_x2.x - p3d_x1.x, 2) + pow(p3d_x2.y - p3d_x1.y, 2)),
sqrt(pow(p3d_y2.x - p3d_y1.x, 2) + pow(p3d_y2.y - p3d_y1.y, 2)));
return diff; // < 8 ? 8 : diff;
}
else
z = mPersonStorage.at(pers).trackPointAt(frame).sp().z();
h = mPersonStorage.at(pers).height();
return (HEAD_SIZE * mControlWidget->getCameraAltitude() / z) / getImageItem()->getCmPerPixel();
return (HEAD_SIZE * mControlWidget->getCameraAltitude() / (mControlWidget->getCameraAltitude() - h)) /
getImageItem()->getCmPerPixel();
return mHeadSize; // muss noch aus density map gelesen werden!!!
}
else //(pos == NULL) && (pers == -1)
{
void Petrack::setProFileName(const QString &fileName)
{
// don't change project Name to an autosave
if(mAutosave.isAutosave(fileName) || fileName == mProFileName)
{
return;
}
// Change project => delete old autosave
mAutosave.deleteAutosave();
// NOTE: Use only the global variant in future?
// global one in helper.h because it is needed to use getFileList and shouldn't depend on Petrack
proFileName = fileName;
mProFileName = fileName;
updateWindowTitle();
}
Schrödter, Tobias
committed
* @brief Return the user's selection of pedestrians/trajectories
Schrödter, Tobias
committed
* Only people selected via "show only people" (single person) or "show only
* people list"(multiple persons) are going to be selected.
Schrödter, Tobias
committed
* @return All user selected pedestrian (empty for all pedestrians)
QSet<size_t> Petrack::getPedestrianUserSelection()
if(mControlWidget->isTrackShowOnlyChecked())
// subtraction needed as in UI ID start at 1 and internally at 0
onlyVisible.insert(mControlWidget->getTrackShowOnlyNr() - 1);
Schrödter, Tobias
committed
return onlyVisible;
}
if(mControlWidget->isTrackShowOnlyListChecked())
auto enteredIDs = util::splitStringToInt(mControlWidget->trackShowOnlyNrList()->text());
if(enteredIDs.has_value())
for(auto id : enteredIDs.value())
// subtraction needed as in UI ID start at 1 and internally at 0
selectedIDs.insert(id - 1);
Schrödter, Tobias
committed
}
mControlWidget->trackShowOnlyNrList()->setStyleSheet("");
return selectedIDs;
}
else
{
mControlWidget->trackShowOnlyNrList()->setStyleSheet("border: 1px solid red");
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
/**
* @brief Splits the given text to get a set of integers.
*
* The given text will be split on ',' and then each element will be checked if it is a range. Ranges are marked with
* '-' as divider. Only positive integer values are allowed.
*
* Examples:
* '1,5,6' -> (1, 5, 6)
* '1-5' -> (1, 2, 3, 4, 5)
*
* @param input given text
* @return Set of int in the given text
*/
std::optional<QSet<int>> util::splitStringToInt(const QString &input)
{
QSet<int> ids;
for(const auto &id : input.split(",", Qt::SkipEmptyParts))
{
bool ok = false;
int enteredID = id.toInt(&ok);
if(ok && enteredID >= 0) // parse single values
{
ids.insert(enteredID);
}
else // error or IDs range (e.g. 1-3, 6-10, etc.)
{
if(id.startsWith("-"))
{
ok = false;
}
auto range = id.split("-");
int first = range[0].toInt(&ok);
ok = ok && range.size() == 2 && !range[1].isEmpty();
if(ok)
{
int last = range[1].toInt(&ok);
if(ok)
Schrödter, Tobias
committed
{
std::swap(first, last);
}
for(int i = first; i <= last; i++)
{
ids.insert(i);
if(!ok)
{
return std::nullopt;
}
Schrödter, Tobias
committed
}
Schrödter, Tobias
committed
}
/**
* @brief Checks which pedestrians/trajectories are selected for evaluation.
*
* If "only for selected" is checked, then only selected people (@see
* Petrack::getPedestrianUserSelection()) are going to be tracked, all people
* otherwise.
*
* @return all trajectories which should be evaluated; empty when all should be evaluated
*/
Schrödter, Tobias
committed
{
if(mControlWidget->isTrackOnlySelectedChecked())
Schrödter, Tobias
committed
{
return getPedestrianUserSelection();
Schrödter, Tobias
committed
}
void Petrack::addManualTrackPointOnlyVisible(const QPointF &pos)
int pers = addOrMoveManualTrackPoint(pos) + 1;
if(pers == 0)
pers = static_cast<int>(mPersonStorage.nbPersons()) + 1;
mControlWidget->setTrackShowOnlyNr(pers);
mControlWidget->setTrackShowOnly(Qt::Checked);
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())));
mPersonStorage.splitPersonAt((Vec2F) pos, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection());
* @brief Lets the user add or move a TrackPoint manually
*
* There is an check inside addPoint which inhibits adding a point,
* if only selected trajectories are visualized, since one wouldn't
* see the newly added TrackPoint.
*
* @param pos pixel position of mouse on image
* @return index of person whose point was moved; -1 if failed or new trajectory is started
int Petrack::addOrMoveManualTrackPoint(const QPointF &pos)
TrackPoint tP(Vec2F{pos}, 110); // 110 is higher than 100 (max. quality) and gets clamped to 100 after insertion
// allows replacemet of every point (check for better quality always passes)
tP, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection(), mReco.getRecoMethod(), &pers);
}
// direction zeigt an, ob bis zum aktuellen (-1), ab dem aktuellen (1) oder ganzer trackpath (0)
// loeschen von Trackpoints einer Trajektorie
void Petrack::deleteTrackPoint(QPointF pos, int direction) // const QPoint &pos
mPersonStorage.delPoint((Vec2F) pos, direction, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection());
updateControlWidget();
}
void Petrack::editTrackPersonComment(QPointF pos)
{
mPersonStorage.editTrackPersonComment((Vec2F) pos, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection());
updateControlWidget();
}
void Petrack::setTrackPersonHeight(QPointF pos)
{
mPersonStorage.setTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection());
updateControlWidget();
}
void Petrack::resetTrackPersonHeight(QPointF pos)
{
mPersonStorage.resetTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection());
/**
* @brief Delete the following, previous or whole trajectory of **all** trajectories
* @param direction previous, following or whole
*/
void Petrack::deleteTrackPointAll(PersonStorage::Direction direction) // const QPoint &pos
mPersonStorage.delPointAll(direction, mAnimation->getCurrentFrameNum());
updateControlWidget();
}
void Petrack::deleteTrackPointROI()
{
mPersonStorage.delPointROI();
updateControlWidget();
mScene->update();
}
void Petrack::deleteTrackPointInsideROI()
{
getPersonStorage().delPointInsideROI();