Newer
Older
3001
3002
3003
3004
3005
3006
3007
3008
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
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;
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
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(),
mControlWidget->trackRegionLevels->value(), getOnlyVisible());
#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;
auto recoMethod = mControlWidget->getRecoMethod();
#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
{
reco::getMarkerPos(mImgFiltered, rect, &persList, 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);
// 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);
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
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)
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
{
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
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
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;
}
/**
* @brief Petrack::getOnlyVisible Returns trajectories which should be evaluated
*
* If "only for visible people" is checked, then only people visible via
* "show only people" (single person) or "show only people list"(multiple persons)
* are going to be evaluated. If "only for visible people" is not checked,
* everyone gets evaluated, not only the ones selected for visibility.
*
* @return all trajectories which should be evaluated; empty when all should be evaluated
*/
if ((mControlWidget->trackOnlySelected->checkState() == Qt::Checked) && (mControlWidget->trackShowOnly->checkState() == Qt::Checked || mControlWidget->trackShowOnlyList->checkState() == Qt::Checked))
{
if( mControlWidget->trackShowOnlyList->checkState() == Qt::Checked)
{
QStringList list = mControlWidget->trackShowOnlyNrList->text().split(",", Qt::SkipEmptyParts);
QSet<int> onlyVisible;
foreach(QString s, list)
{
bool ok = false;
int nr = s.toInt(&ok);
if(ok/* && nr <= maxPed && nr > 0*/) // einzelne ID
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);
if(ok/* && first <= maxPed && nr > 0*/)
{
last = range[1].toInt(&ok);
if(ok/* && last <= maxPed && nr > 0*/)
{
if(first>last)
std::swap(first,last);
for(int i=first;i<=last;i++)
onlyVisible.insert(i-1);
}
}
}
if(!ok)
debout << "Warning: error while reading showOnlyVisible list from input line!" << std::endl;
return onlyVisible; //in anzeige wird ab 1 gezaehlt, in datenstruktur ab 0
{
QSet<int> onlyVisible;
onlyVisible.insert(mControlWidget->trackShowOnlyNr->value()-1);
return onlyVisible;
}
}else
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)
{
mTracker->splitPersonAt((Vec2F) pos, mAnimation->getCurrentFrameNum(), getOnlyVisible());
updateControlWidget();
}
* @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)
mTracker->addPoint(tP, mAnimation->getCurrentFrameNum(), getOnlyVisible(), &pers);
updateControlWidget();
return pers;
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
}
// 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
{
mTracker->delPoint((Vec2F) pos, direction, mAnimation->getCurrentFrameNum(), getOnlyVisible());
updateControlWidget();
}
void Petrack::editTrackPersonComment(QPointF pos)
{
mTracker->editTrackPersonComment((Vec2F) pos, mAnimation->getCurrentFrameNum(), getOnlyVisible());
updateControlWidget();
}
void Petrack::setTrackPersonHeight(QPointF pos)
{
mTracker->setTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(), getOnlyVisible());
updateControlWidget();
}
void Petrack::resetTrackPersonHeight(QPointF pos)
{
mTracker->resetTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(), getOnlyVisible());
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);
}
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
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"