Newer
Older
debout << "go update: " << getElapsedTime() <<endl;
#endif
mCodeMarkerItem->resetSavedMarkers();
static int lastRecoFrame = -10000;
static bool borderChangedForTracking = false;
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
// 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;
#endif
if (imageChanged || swapChanged)
mImgFiltered = mSwapFilter.apply(mImgFiltered);
else
mImgFiltered = mSwapFilter.getLastResult();
if (imageChanged || swapChanged || brightContrastChanged)
mImgFiltered = mBrightContrastFilter.apply(mImgFiltered);
else
mImgFiltered = mBrightContrastFilter.getLastResult();
if (imageChanged || swapChanged || brightContrastChanged || borderChanged)
mImgFiltered = mBorderFilter.apply(mImgFiltered); // mIplImg
else
mImgFiltered = mBorderFilter.getLastResult();
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "nch filter: " << getElapsedTime() <<endl;
#endif
if (borderChanged)
updateControlImage(mImgFiltered);
#ifndef STEREO_DISABLED
if (imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged)
{
if (mStereoContext)
mStereoContext->init(mImgFiltered);
}
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "vor calib: " << getElapsedTime() <<endl;
#endif
if (imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged)
mImgFiltered = mCalibFilter->apply(mImgFiltered);
else
mImgFiltered = mCalibFilter->getLastResult();
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "nach calib: " << getElapsedTime() <<endl;
#endif
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;
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
else
mBackgroundFilter.reset(); // alle gesammelten hintergrundinfos werden verworfen und bg.changed auf true gesetzt
}
if (imageChanged || mBackgroundFilter.changed())
mImgFiltered = mBackgroundFilter.apply(mImgFiltered);
else
mImgFiltered = mBackgroundFilter.getLastResult();
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "nach bg: " << getElapsedTime() <<endl;
#endif
// delete track list, if intrinsic param have changed
if (calibChanged && mTracker->size() > 0) //mCalibFilter.getEnabled() &&
{
// Evtl. nicht Tracker loeschen sondern entsprechend der neuen Calibration verschieben?!?!?
mTracker->clear();
mTracker->reset();
if( !isLoading() )
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();
mTracker->calcPosition(frameNum);
}
}
if (borderChanged)
borderChangedForTracking = true;
// tracking vor recognition, da dann neu gefundene punkte mit getrackten bereits ueberprueft werden koennen
if ((trackChanged() || imageChanged) && (mControlWidget->trackOnlineCalc->checkState() == Qt::Checked)) // borderChanged ???
{
// Rect for tracking area
QRect roi(myRound(mTrackingRoiItem->rect().x()+getImageBorderSize()),
myRound(mTrackingRoiItem->rect().y()+getImageBorderSize()),
myRound(mTrackingRoiItem->rect().width()),
myRound(mTrackingRoiItem->rect().height()));
if (borderChangedForTracking)
{
size.width = mImgFiltered.cols;
size.height = mImgFiltered.rows;
mTracker->resize(size);
mTrackingRoiItem->checkRect();
}
#ifndef STEREO_DISABLED
// buildt disparity picture if it should be used for height detection
if (mStereoContext && mStereoWidget->stereoUseForHeight->isChecked())
mStereoContext->getDisparity();
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
#ifdef TIME_MEASUREMENT
debout << "vor track: " << getElapsedTime() <<endl;
#endif
// debout << "test" << endl;
int anz = mTracker->track(mImgFiltered, rect, frameNum,
mControlWidget->trackRepeatQual->value(), getImageBorderSize(),
mReco.getRecoMethod(), mControlWidget->trackRegionLevels->value(),
Schrödter, Tobias
committed
getPedestriansToTrack());
#ifdef TIME_MEASUREMENT
debout << "nach track: " << getElapsedTime() <<endl;
#endif
mControlWidget->trackNumberNow->setText(QString("%1").arg(anz));
mTrackChanged = false;
borderChangedForTracking = false;
}
else
mControlWidget->trackNumberNow->setText(QString("0"));
// hier muesste fuer ameisen etc allgemeinABC.getPosList(...)
if (((((lastRecoFrame+mControlWidget->recoStep->value()) <= frameNum) ||
((lastRecoFrame-mControlWidget->recoStep->value()) >= 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
if (mControlWidget->performRecognition->checkState() == Qt::Checked)
{
QRect rect(myRound(mRecognitionRoiItem->rect().x()+getImageBorderSize()),
myRound(mRecognitionRoiItem->rect().y()+getImageBorderSize()),
myRound(mRecognitionRoiItem->rect().width()),
myRound(mRecognitionRoiItem->rect().height()));
QList<TrackPoint> persList;
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "vor reco: " << getElapsedTime() <<endl;
#endif
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())
{
PersonList pl;
pl.calcPersonPos(mImgFiltered, rect, &persList, mStereoContext, getBackgroundFilter(), markerLess);
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "nach reco: " << getElapsedTime() <<endl;
#endif
mTracker->addPoints(persList, frameNum, mReco.getRecoMethod());
// folgendes lieber im Anschluss, ggf beim exportieren oder statt test direkt del:
if (mStereoContext && mStereoWidget->stereoUseForReco->isChecked())
mTracker->purge(frameNum); // bereinigen wenn weniger als 0.2 recognition und nur getrackt
mControlWidget->recoNumberNow->setText(QString("%1").arg(persList.size()));
mRecognitionChanged = false;
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???
}
else
mControlWidget->recoNumberNow->setText(QString("0"));
lastRecoFrame = frameNum;
}
else
mControlWidget->recoNumberNow->setText(QString("0"));
mControlWidget->trackNumberAll->setText(QString("%1").arg(mTracker->size())); // kann sich durch reco und tracker aendern
mControlWidget->trackShowOnlyNr->setMaximum(MAX(mTracker->size(),1)); // kann sich durch reco und tracker aendern
mControlWidget->trackNumberVisible->setText(QString("%1").arg(mTracker->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);
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
if (borderChanged)
mImageItem->setImage(mImage);
else
{
getScene()->update(); //repaint();
// update pixel color (because image pixel moves)
setStatusColor();
}
#ifdef QWT
mControlWidget->getAnalysePlot()->setActFrame(frameNum);
if (mControlWidget->anaMarkAct->isChecked())
{
mControlWidget->getAnalysePlot()->replot();
}
#endif
semaphore.release();
}
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "stp update: " << getElapsedTime() <<endl;
#endif
}
void Petrack::updateImage(const cv::Mat &img)
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
{
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
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
void Petrack::setHeadSize(double hS)
{
if (hS == -1)
{
mCmPerPixel = getImageItem()->getCmPerPixel();
//debout << mCmPerPixel <<endl;
mHeadSize = (HEAD_SIZE*mControlWidget->coordAltitude->value() / (mControlWidget->coordAltitude->value()-mControlWidget->mapDefaultHeight->value())) /
mCmPerPixel;
}
else
mHeadSize = hS;
}
// 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 < mTracker->size()) && mTracker->at(pers).trackPointExist(frame))
{
if( mControlWidget->getCalibCoordDimension() == 0 )
{
int diff;
cv::Point3f p3d = getExtrCalibration()->get3DPoint(cv::Point2f(mTracker->at(pers).trackPointAt(frame).x(),
mTracker->at(pers).trackPointAt(frame).y()),
mControlWidget->mapDefaultHeight->value());
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 = mTracker->at(pers).trackPointAt(frame).sp().z();
h = mTracker->at(pers).height();
if (z > 0)
return (HEAD_SIZE*mControlWidget->coordAltitude->value() / z) / getImageItem()->getCmPerPixel();
else if (h > MIN_HEIGHT)
return (HEAD_SIZE*mControlWidget->coordAltitude->value() / (mControlWidget->coordAltitude->value()-h)) / getImageItem()->getCmPerPixel();
else
return mHeadSize;
}
}
return mHeadSize; // muss noch aus density map gelesen werden!!!
else //(pos == NULL) && (pers == -1)
return mHeadSize;
}
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)
Schrödter, Tobias
committed
QSet<int> Petrack::getPedestrianUserSelection()
Schrödter, Tobias
committed
if (mControlWidget->trackShowOnly->checkState() == Qt::Checked) {
QSet<int> onlyVisible;
onlyVisible.insert(mControlWidget->trackShowOnlyNr->value() - 1);
return onlyVisible;
}
if (mControlWidget->trackShowOnlyList->checkState() == Qt::Checked) {
QStringList list = mControlWidget->trackShowOnlyNrList->text().split(
",", Qt::SkipEmptyParts);
QSet<int> onlyVisible;
foreach (QString s, list)
Schrödter, Tobias
committed
bool ok = false;
int nr = s.toInt(&ok);
if (ok /* && nr <= maxPed && nr > 0*/) // einzelne ID
Schrödter, Tobias
committed
onlyVisible.insert(nr - 1);
}
else // error or IDs range (e.g. 1-3, 6-10, etc.)
{
QStringList range = s.split("-", Qt::SkipEmptyParts);
int last, first = range[0].toInt(&ok);
Schrödter, Tobias
committed
if (ok /* && first <= maxPed && nr > 0*/)
{
last = range[1].toInt(&ok);
if (ok /* && last <= maxPed && nr > 0*/)
Schrödter, Tobias
committed
if (first > last)
{
std::swap(first, last);
}
for (int i = first; i <= last; i++)
{
onlyVisible.insert(i - 1);
}
Schrödter, Tobias
committed
if (!ok)
{
debout << "Warning: error while reading showOnlyVisible list from input line!"
<< std::endl;
}
Schrödter, Tobias
committed
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
return onlyVisible; // in anzeige wird ab 1 gezaehlt, in datenstruktur ab 0
}
return QSet<int>();
}
/**
* @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
*/
QSet<int> Petrack::getPedestriansToTrack()
{
if (mControlWidget->trackOnlySelected->checkState() == Qt::Checked)
{
return getPedestrianUserSelection();
}
return QSet<int>();
void Petrack::addManualTrackPointOnlyVisible(const QPointF& pos)
int pers = addOrMoveManualTrackPoint(pos)+1;
if (pers == 0)
pers = mTracker->size()+1;
pers = mControlWidget->trackShowOnlyNr->maximum();
mControlWidget->trackShowOnlyNr->setValue(pers);
mControlWidget->trackShowOnly->setChecked(true);
}
void Petrack::updateControlWidget()
{
mControlWidget->trackNumberAll->setText(QString("%1").arg(mTracker->size()));
mControlWidget->trackShowOnlyNr->setMaximum(MAX(mTracker->size(),1));
mControlWidget->trackNumberVisible->setText(QString("%1").arg(mTracker->visible(mAnimation->getCurrentFrameNum())));
}
void Petrack::splitTrackPerson(QPointF pos)
{
Schrödter, Tobias
committed
mTracker->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)
int pers = -1;
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)
Schrödter, Tobias
committed
mTracker->addPoint(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
{
Schrödter, Tobias
committed
mTracker->delPoint((Vec2F) pos, direction, mAnimation->getCurrentFrameNum(),
getPedestrianUserSelection());
updateControlWidget();
}
void Petrack::editTrackPersonComment(QPointF pos)
{
Schrödter, Tobias
committed
mTracker->editTrackPersonComment((Vec2F) pos, mAnimation->getCurrentFrameNum(),
getPedestrianUserSelection());
updateControlWidget();
}
void Petrack::setTrackPersonHeight(QPointF pos)
{
Schrödter, Tobias
committed
mTracker->setTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(),
getPedestrianUserSelection());
updateControlWidget();
}
void Petrack::resetTrackPersonHeight(QPointF pos)
{
Schrödter, Tobias
committed
mTracker->resetTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(),
getPedestrianUserSelection());
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
updateControlWidget();
}
// direction zeigt an, ob bis zum aktuellen (-1), ab dem aktuellen (1) oder ganzer trackpath (0)
// loeschen von Trackpoints aller Trajektorien
void Petrack::deleteTrackPointAll(int direction) //const QPoint &pos
{
mTracker->delPointAll(direction, mAnimation->getCurrentFrameNum());
updateControlWidget();
}
void Petrack::deleteTrackPointROI()
{
mTracker->delPointROI();
updateControlWidget();
mScene->update();
}
void Petrack::deleteTrackPointInsideROI()
{
mTracker->delPointInsideROI();
updateControlWidget();
mScene->update();
}
void Petrack::updateSourceInOutFrames()
{
mPlayerWidget->setFrameInNum(mAnimation->getSourceInFrameNum());
mPlayerWidget->setFrameOutNum(mAnimation->getSourceOutFrameNum());
}
// delta gibt menge an Umdrehungen und richtung an
void Petrack::skipToFrameWheel(int delta)
{
mPlayerWidget->skipToFrame(mPlayerWidget->getPos()+delta);
}
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
void Petrack::setPeTrackVersion(const std::string& petrackVersion)
{
mPetrackVersion = QString::fromStdString(petrackVersion);
}
void Petrack::setGitInformation(
const std::string& gitCommitID,
const std::string& gitCommitDate,
const std::string& gitCommitBranch)
{
mGitCommitID= QString::fromStdString(gitCommitID);
mGitCommitDate = QString::fromStdString(gitCommitDate);
mGitCommitBranch = QString::fromStdString(gitCommitBranch);
}
void Petrack::setCompileInformation(const std::string &compileTimeStamp, const std::string &compilerID,
const std::string &compilerVersion)
{
mCompileDate = QString::fromStdString(compileTimeStamp);
mCompilerID = QString::fromStdString(compilerID);
mCompilerVersion = QString::fromStdString(compilerVersion);
}
#include "moc_petrack.cpp"