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
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
// {
// QMessageBox::critical(this, tr("PeTrack"), tr("File format is not supported for 3D calibration input files: %1 (supported: .3dc ").arg(src.right(4)));
// return;
// }
// }else // src empty ?
// {
// QMessageBox::critical(this, tr("PeTrack"), tr("Cannot open 3D calibration file: file is missing."));
// return;
// }
//}
void Petrack::exportTracker(QString dest) //default = ""
{
static QString lastFile;
if (lastFile == "")
lastFile = mTrcFileName;
if (mTracker)
{
// if no destination file or folder is given
if (dest.isEmpty())
{
// if (lastFile.isEmpty() && !mSeqFileName.isEmpty())
// lastFile = QFileInfo(mSeqFileName).path();
//getSaveFileName( ==> Wird keine Dateiendung angegeben wird automatisch die erste aus dem Filter angehangen
//QUrl url = QFileDialog::getSaveFileUrl(this,
// tr("Select file for exporting tracking pathes"),
// lastFile,
// tr("Tracker (*.*);;Petrack tracker (*.trc);;Text (*.txt);;Text for gnuplot(*.dat);;XML Travisto (*.trav);;All supported types (*.txt *.trc *.dat *.trav *.);;All files (*.*)"));
//dest = url.toLocalFile();//path();//toString();
QFileDialog fileDialog(this,
tr("Select file for exporting tracking pathes"),
lastFile,
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("");
//fileDialog.setOption();
// foreach (QString filter, fileDialog.mimeTypeFilters()) {
// debout << "MIME-Typ Filter: " << filter << endl;
// }
// foreach (QString filter, fileDialog.nameFilters()) {
// debout << "Name Filter: " << filter << endl;
// }
if( fileDialog.exec() ){
dest = fileDialog.selectedFiles().at(0);
// debout << "selectedFiles" << endl;
}
//dest = QFileDialog::getSaveFileName(this,
// tr("Select file for exporting tracking pathes"),
// lastFile,
// tr("Tracker (*.*);;Petrack tracker (*.trc);;Text (*.txt);;Text for gnuplot(*.dat);;XML Travisto (*.trav);;All supported types (*.txt *.trc *.dat *.trav *.);;All files (*.*)"));
}
if (!dest.isEmpty())
{
QList<int> pers, frame;
bool autoCorrectOnlyExport = (mControlWidget->getRecoMethod() == reco::RecognitionMethod::MultiColor) && // multicolor
mMultiColorMarkerWidget->autoCorrect->isChecked() &&
mMultiColorMarkerWidget->autoCorrectOnlyExport->isChecked();
// debout << "dest: " << dest << " suffix: " << dest.right(4) << endl;
if (dest.right(4) == ".trc")
{
#ifdef TIME_MEASUREMENT
double time1 = 0.0, tstart;
tstart = clock();
#endif
//QFile file(dest);
QTemporaryFile file;
int i;
if (!file.open()/*!file.open(QIODevice::WriteOnly | QIODevice::Text)*/)
{
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString()));
QProgressDialog progress("Export TRC-File",nullptr,0,mTracker->size()+1,this->window());
progress.setWindowTitle("Export .trc-File");
progress.setWindowModality(Qt::WindowModal);
progress.setVisible(true);
progress.setValue(0);
progress.setLabelText(QString("Export tracking data ..."));
qApp->processEvents();
//if (mControlWidget->exportComment->isChecked())
trcVersion = 4;
debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s), file version " << trcVersion << ")..." << std::endl;
out << "version " << trcVersion << Qt::endl;
out << mTracker->size() << Qt::endl;
for (i = 0; i < mTracker->size(); ++i)
{
qApp->processEvents();
progress.setLabelText(QString("Export person %1 of %2 ...").arg(i+1).arg(mTracker->size()));
progress.setValue(i+1);
//if(mControlWidget->exportComment->isChecked())
// out << "# " << (*mTracker)[i].comment() << endl;
out << (*mTracker)[i] << Qt::endl;
}
file.flush();
file.close();
#ifdef TIME_MEASUREMENT
time1 += clock() - tstart;
time1 = time1/CLOCKS_PER_SEC;
cout << " time(writing) = " << time1 << " sec." << endl;
time1 = 0.0;
tstart = clock();
#endif
progress.setLabelText(QString("Save file ..."));
qApp->processEvents();
if (QFile::exists(dest))
QFile::remove(dest);
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);
// kurz Alternative zu oben aber schlechter lesbar
//while(!file.copy(dest)) QFile::remove(dest);
progress.setValue(mTracker->size()+1);
std::cout << " finished " << std::endl;
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
#ifdef TIME_MEASUREMENT
time1 += clock() - tstart;
time1 = time1/CLOCKS_PER_SEC;
cout << " time(copying) = " << time1 << " sec." << endl;
// time1 = 0.0;
// tstart = clock();
#endif
// mTracker->checkPlausibility(pers, frame,
// mControlWidget->testEqual->isChecked(),
// mControlWidget->testVelocity->isChecked(),
// mControlWidget->testInside->isChecked(),
// mControlWidget->testLength->isChecked());
#ifdef TIME_MEASUREMENT
// time1 += clock() - tstart;
// time1 = time1/CLOCKS_PER_SEC;
// cout << " time(checkPlausibility) = " << time1 << " sec." << endl;
#endif
mTrcFileName = dest; // fuer Project-File, dann koennte track path direkt mitgeladen werden, wenn er noch da ist
}
else if (dest.right(4) == ".txt")
{
QTemporaryFile file;
if (!file.open()) //!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString()));
debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s))..." << std::endl;
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
#ifdef TIME_MEASUREMENT
double time1 = 0.0, tstart;
tstart = clock();
#endif
// 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->trackRecalcHeight->checkState())
{
if ( mControlWidget->getCalibCoordDimension() == 0 ) // 3D
;//Nothing to be done because z already the right height
else // 2D
mTracker->recalcHeight(mControlWidget->coordAltitude->value());
}
#ifdef TIME_MEASUREMENT
time1 += clock() - tstart;
time1 = time1/CLOCKS_PER_SEC;
cout << " time(recalcHeight) = " << time1 << " sec." << endl;
time1 = 0.0;
tstart = clock();
#endif
mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), getImageBorderSize(),
mControlWidget->trackMissingFrames->checkState(),
mStereoWidget->stereoUseForExport->isChecked(),
mControlWidget->trackAlternateHeight->checkState(), mControlWidget->coordAltitude->value(), mStereoWidget->stereoUseCalibrationCenter->isChecked(),
mControlWidget->exportElimTp->isChecked(), mControlWidget->exportElimTrj->isChecked(), mControlWidget->exportSmooth->isChecked(),
mControlWidget->exportViewDir->isChecked(), mControlWidget->exportAngleOfView->isChecked(), mControlWidget->exportMarkerID->isChecked(),
autoCorrectOnlyExport);
#ifdef TIME_MEASUREMENT
time1 += clock() - tstart;
time1 = time1/CLOCKS_PER_SEC;
cout << " time(calculate) = " << time1 << " sec." << endl;
time1 = 0.0;
tstart = clock();
#endif
QTextStream out(&file);
out << "# PeTrack project: " << QFileInfo(getProFileName()).fileName() << Qt::endl;
out << "# raw trajectory file: " << QFileInfo(getTrackFileName()).fileName() << Qt::endl;
out << "# framerate: " << mAnimation->getFPS() << " fps" << Qt::endl;
out << "# personal information:" << Qt::endl;
out << "# ID| Comment" << Qt::endl;
std::cout << std::endl << "Printing comment table..." << std::endl << std::endl;
std::cout << "ID | Comment" << std::endl;
std::cout << "----|----------------" << std::endl;
auto commentSplit = mTracker->at(i).comment().split("\n", Qt::KeepEmptyParts);
out << "#" << qSetFieldWidth(3) << (i+1) << qSetFieldWidth(0) << "|" << commentSplit.at(0) << Qt::endl;
std::cout << std::setw(4) << (i+1) << "|" << commentSplit.at(0) << std::endl;
commentSplit.pop_front();
for (const auto& line : commentSplit)
{
out << "#" << qSetFieldWidth(3) << " " << qSetFieldWidth(0) << "|" << line << Qt::endl;
std::cout << " |" << line << std::endl;
}
}
}
mTrackerReal->exportTxt(out,
mControlWidget->trackAlternateHeight->checkState(),
mStereoWidget->stereoUseForExport->isChecked(),
mControlWidget->exportViewDir->isChecked(),
mControlWidget->exportAngleOfView->isChecked(),
mControlWidget->exportUseM->isChecked(),
mControlWidget->exportMarkerID->isChecked());
//out << *mTrackerReal;
file.flush();
file.close();
if (QFile::exists(dest))
QFile::remove(dest);
if( !file.copy(dest) )
PCritical(this, tr("PeTrack"),
"Please try again!"));
else
statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000);
std::cout << " finished" << std::endl;
3264
3265
3266
3267
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
3293
3294
3295
3296
3297
3298
#ifdef TIME_MEASUREMENT
time1 += clock() - tstart;
time1 = time1/CLOCKS_PER_SEC;
cout << " time(export) = " << time1 << " sec." << endl;
// time1 = 0.0;
// tstart = clock();
#endif
// mTracker->checkPlausibility(pers, frame,
// mControlWidget->testEqual->isChecked(),
// mControlWidget->testVelocity->isChecked(),
// mControlWidget->testInside->isChecked(),
// mControlWidget->testLength->isChecked());
#ifdef TIME_MEASUREMENT
// time1 += clock() - tstart;
// time1 = time1/CLOCKS_PER_SEC;
// cout << " time(checkPlausibility) = " << time1 << " sec." << endl;
#endif
}
else if (dest.right(4) == ".dat")
{
// // war: immer wenn txt exportiert wird, wird auch fuer dat fuer excel exportiert
// QString destDat(dest.left(dest.length()-4)+".dat");
// QFile fileDat(destDat);
// if (!fileDat.open(QIODevice::WriteOnly | QIODevice::Text))
// {
// QMessageBox::critical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(destDat).arg(fileDat.errorString()));
// return;
// }
QTemporaryFile fileDat;
if (!fileDat.open()) //!fileDat.open(QIODevice::WriteOnly | QIODevice::Text))
{
PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(fileDat.errorString()));
return;
}
// 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->trackRecalcHeight->checkState())
{
mTracker->recalcHeight(mControlWidget->coordAltitude->value());
}
mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), getImageBorderSize(),
mControlWidget->trackMissingFrames->checkState(),
mStereoWidget->stereoUseForExport->isChecked(),
mControlWidget->trackAlternateHeight->checkState(), mControlWidget->coordAltitude->value(), mStereoWidget->stereoUseCalibrationCenter->isChecked(),
mControlWidget->exportElimTp->isChecked(), mControlWidget->exportElimTrj->isChecked(), mControlWidget->exportSmooth->isChecked(),
mControlWidget->exportViewDir->isChecked(), mControlWidget->exportAngleOfView->isChecked(), mControlWidget->exportMarkerID->isChecked(),
autoCorrectOnlyExport);
debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s))..." << std::endl;
QTextStream outDat(&fileDat);
mTrackerReal->exportDat(outDat, mControlWidget->trackAlternateHeight->checkState(), mStereoWidget->stereoUseForExport->isChecked());
fileDat.flush();
fileDat.close();
if (QFile::exists(dest))
QFile::remove(dest);
if( !fileDat.copy(dest) )
PCritical(this, tr("PeTrack"),
"Please try again!"));
else
statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000);
std::cout << " finished" << std::endl;
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
// mTracker->checkPlausibility(pers, frame,
// mControlWidget->testEqual->isChecked(),
// mControlWidget->testVelocity->isChecked(),
// mControlWidget->testInside->isChecked(),
// mControlWidget->testLength->isChecked());
//
// // immer wenn txt exportiert wird, wird auch fuer visu-software xml nach ulrich kemlow exportiert
// QString destXml(dest.left(dest.length()-4)+".trav");
// QFile fileXml(destXml);
// if (!fileXml.open(QIODevice::WriteOnly | QIODevice::Text))
// {
// QMessageBox::critical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(destXml).arg(fileXml.errorString()));
// return;
// }
// debout << "export tracking data to " << destXml << " (" << mTracker->size() << " person(s))..." << endl;
// // already done: mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), getImageBorderSize(), mControlWidget->trackMissingFrames->checkState());
// QTextStream outXml(&fileXml);
// outXml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" <<endl;
// outXml << "<trajectoriesDataset>" <<endl;
// outXml << " <header>" <<endl;
// outXml << " <roomCaption>PeTrack: " << mAnimation->getFileBase() << "</roomCaption>" << endl;
// outXml << " <roomID>0</roomID>" <<endl;
// outXml << " <agents>" << mTracker->size() << "</agents>" << endl;
// outXml << " <frameRate>" << mAnimation->getFPS() << "</frameRate> <!--per second-->" << endl;
// // outXml << " <timeStep>" << 1000./mAnimation->getFPS() << "</timeStep> <!-- millisecond-->" << endl; inverse von
// outXml << " <timeFirstFrame sec=\"" << mAnimation->getFirstFrameSec() << "\" microsec=\"" << mAnimation->getFirstFrameMicroSec()
// << "\"/> <!-- " << mAnimation->getTimeString(0) << " -->" << endl;
// outXml << " </header>" <<endl<<endl;
//
// mTrackerReal->exportXml(outXml, mControlWidget->trackAlternateHeight->checkState(), mStereoWidget->stereoUseForExport->isChecked());
//
// outXml << "</trajectoriesDataset>" <<endl;
// fileXml.close();
// cout << " finished" << 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->trackRecalcHeight->checkState())
{
mTracker->recalcHeight(mControlWidget->coordAltitude->value());
}
mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), getImageBorderSize(),
mControlWidget->trackMissingFrames->checkState(),
mStereoWidget->stereoUseForExport->isChecked(),
mControlWidget->trackAlternateHeight->checkState(), mControlWidget->coordAltitude->value(), mStereoWidget->stereoUseCalibrationCenter->isChecked(),
mControlWidget->exportElimTp->isChecked(), mControlWidget->exportElimTrj->isChecked(), mControlWidget->exportSmooth->isChecked(),
mControlWidget->exportViewDir->isChecked(), mControlWidget->exportAngleOfView->isChecked(), mControlWidget->exportMarkerID->isChecked(),
autoCorrectOnlyExport);
// mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), getImageBorderSize(),
// mControlWidget->trackMissingFrames->checkState(),
// mStereoWidget->stereoUseForExport->isChecked(),
// mControlWidget->trackAlternateHeight->checkState(), mControlWidget->coordAltitude->value(), mStereoWidget->stereoUseCalibrationCenter->isChecked(),
// mControlWidget->exportElimTp->isChecked(), mControlWidget->exportElimTrj->isChecked(), mControlWidget->exportSmooth->isChecked());
QTemporaryFile fileXml;
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 << " (" << mTracker->size() << " person(s))..." << std::endl;
// already done: mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), getImageBorderSize(), mControlWidget->trackMissingFrames->checkState());
QTextStream outXml(&fileXml);
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>" << mTracker->size() << "</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->trackAlternateHeight->checkState(), mStereoWidget->stereoUseForExport->isChecked());
outXml << "</trajectoriesDataset>" << Qt::endl;
fileXml.flush();
fileXml.close();
if (QFile::exists(dest))
QFile::remove(dest);
if( !fileXml.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);
std::cout << " finished" << std::endl;
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
}
else
{ // wenn keine Dateiendung, dann wird trc und txt herausgeschrieben
exportTracker(dest + ".trc");
exportTracker(dest + ".txt");
}
// else
// {
// QMessageBox::critical(this, tr("PeTrack"), tr("Cannot save %1 maybe because of wrong file extension.").arg(dest));
// }
lastFile = 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()
qApp->processEvents();
if (progress.wasCanceled())
break;
}
while (mPlayerWidget->frameForward());
mPlayerWidget->skipToFrame(memPos);
}
/**
* @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.
*/
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
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
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
void Petrack::trackAll()
{
int memPos = mPlayerWidget->getPos();
int progVal = 0;
enum Qt::CheckState memCheckState = mControlWidget->trackOnlineCalc->checkState();
enum Qt::CheckState memRecoState = mControlWidget->performRecognition->checkState();
mControlWidget->trackOnlineCalc->setCheckState(Qt::Checked);
mControlWidget->performRecognition->setCheckState(Qt::Checked);
QProgressDialog progress("Tracking pedestrians through all frames...", "Abort tracking", 0, 2*mAnimation->getNumFrames()-memPos, this);
progress.setWindowModality(Qt::WindowModal); // blocks main window
// mTracker()->init(); // wenn vorherige Daten weggenommen werden sollen
// mPlayerWidget->skipToFrame(0); //man koennte an den Anfang springen
// vorwaertslaufen ab aktueller Stelle und trackOnlineCalc zum tracken nutzen
do
{
progress.setValue(++progVal); //mPlayerWidget->getPos()
qApp->processEvents();
if (progress.wasCanceled())
break;
}
while (mPlayerWidget->frameForward());
if (mAutoBackTrack)
{
// zuruecksprinegn an die stelle, wo der letzte trackPath nicht vollstaendig
// etwas spaeter, da erste punkte in reco path meist nur ellipse ohne markererkennung
mControlWidget->trackOnlineCalc->setCheckState(Qt::Unchecked);
mPlayerWidget->skipToFrame(mTracker->largestFirstFrame()+5);
mControlWidget->trackOnlineCalc->setCheckState(Qt::Checked);
//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->performRecognition->setCheckState(Qt::Unchecked);
// rueckwaertslaufen
do
{
if (progVal+1 < 2*mAnimation->getNumFrames()-memPos)
progress.setValue(++progVal); //mPlayerWidget->getPos()
qApp->processEvents();
if (progress.wasCanceled())
break;
if (mPlayerWidget->getPos() == memPos+1)
mControlWidget->performRecognition->setCheckState(Qt::Checked);
}
while (mPlayerWidget->frameBackward());
// bei abbruch koennen es auch mPlayerWidget->getPos() frames sein, die bisher geschrieben wurden
// debout << "wrote " << mPlayerWidget->getPos()+1 << " of " << mAnimation->getNumFrames() << " frames." << endl;
progress.setValue(2*mAnimation->getNumFrames()-memPos);
}
if (mAutoTrackOptimizeColor)
mTracker->optimizeColor();
mControlWidget->performRecognition->setCheckState(memRecoState);
mControlWidget->trackOnlineCalc->setCheckState(Qt::Unchecked);
mPlayerWidget->skipToFrame(memPos);
mControlWidget->trackOnlineCalc->setCheckState(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
if (level == -1)
level = mControlWidget->trackRegionLevels->value();
return (int)((getHeadSize(pos, pers, frame) / pow(2.,level)) * (mControlWidget->trackRegionScale->value() / 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;
#endif
mCodeMarkerItem->resetSavedMarkers();
static int lastRecoFrame = -10000;
static bool borderChangedForTracking = false;
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
//static QTime updateTime; // ergibt die gleichen werte wie benutzte native systemroutinben!!!
// 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 brightChanged = mBrightFilter.changed();
// bool contrastChanged = mContrastFilter.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
// debout << "swap: " << mIplImgFiltered << " " << mIplImg << endl;
if (imageChanged || swapChanged)
mImgFiltered = mSwapFilter.apply(mImgFiltered);
else
mImgFiltered = mSwapFilter.getLastResult();
// debout << "b-c: " << mIplImgFiltered << " " << mIplImg << endl;
if (imageChanged || swapChanged || brightContrastChanged)
mImgFiltered = mBrightContrastFilter.apply(mImgFiltered);
else
mImgFiltered = mBrightContrastFilter.getLastResult();
// debout << "border: " << mIplImgFiltered << " " << mIplImg << endl;
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;
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
else
mBackgroundFilter.reset(); // alle gesammelten hintergrundinfos werden verworfen und bg.changed auf true gesetzt
}
// debout << "bg: " << mIplImgFiltered << " " << mIplImg << endl;
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() &&
{
//CvSize size;
//size.width = mIplImgFiltered->width;
//size.height = mIplImgFiltered->height;
//mTracker->init(size);
// 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()));
// mTracker->resize(Size(roi.width(),roi.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
// debout << "track anz: " << anz << endl;
mControlWidget->trackNumberNow->setText(QString("%1").arg(anz));
mTrackChanged = false;
borderChangedForTracking = false;
}
else
mControlWidget->trackNumberNow->setText(QString("0"));
// hier muesste fuer ameisen etc allgemeinABC.getPosList(...)
//#static IplImage *tempImg = NULL;
// debout << "reco: " << mIplImgFiltered << " " << mIplImg << endl;
// debout << "imageChanged: " << imageChanged << " swapChanged: " << swapChanged << " b-c-Changed: " << brightContrastChanged << " borderChanged: "<< borderChanged << " calibChanged: " << calibChanged << " recognitionChanged: " << recognitionChanged() << endl;
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 (borderChanged)
mRecognitionRoiItem->checkRect();
//#cvReleaseImage(&tempImg);
//#tempImg = cvCloneImage(mIplImgFiltered); // must be deleted, if marker in ebene darueber gemalt werden!!!!!
// QPointF p = mRecognitionRoiItem->mapToItem(mImageItem, QPointF(0.,0.)); nicht noetig da drag nun selber gemacht wird
// debout << "start reco" << endl;
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;
// bool markerLess = true;
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
{
// persList == crossList
// getMarkerPos(mIplImgFiltered, rect, &persList, mControlWidget->markerBrightness->value(),
// getImageBorderSize(), (mControlWidget->markerIgnoreWithout->checkState() == Qt::Checked),
// (mControlWidget->recoAutoWB->checkState() == Qt::Checked), getBackgroundFilter(), recoMethod); //#tempImg
reco::getMarkerPos(mImgFiltered, rect, &persList, mControlWidget, getImageBorderSize(), getBackgroundFilter());
// markerLess = false;
// debout << "Testausgabe persList: [Frame " << frameNum << "] " << endl;
// for (int i = 0; i < persList.size(); ++i)
// {
// cout << persList.at(i) << endl;
// }
}
#ifndef STEREO_DISABLED
if (mStereoContext && mStereoWidget->stereoUseForReco->isChecked())
{
PersonList pl;
pl.calcPersonPos(mImgFiltered, rect, persList, mStereoContext, getBackgroundFilter(), markerLess);
}
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
#ifdef TIME_MEASUREMENT
// "==========: "
debout << "nach reco: " << getElapsedTime() <<endl;
#endif
mTracker->addPoints(persList, frameNum);
// debout << "reco anz: " << persList.size() << endl;
// 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;
// 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));
// else
// mStatusLabelColor->setText(QString("<font color=\"#000000\"> %1</font>").arg(s));
// mControlWidget->getColorPlot()->updateTracker(); // oder nur wenn tab offen oder wenn sich mtracker geaendert hat???
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;
// debout << "end reco" << endl;
}
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);
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
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
// debout << " ############ out ############## " << mIplImgFiltered << " " << mIplImg << endl;
// debout << "mIplImage ok ? " << (mIplImg != NULL) << " +++ mIplImageFiltered ok ? " << (mIplImgFiltered != NULL) << endl;
}
void Petrack::updateImage(const cv::Mat &img)
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
{
mImg = img;
// namedWindow("Test");
// imshow("Test",mImg);
// waitKey();
updateImage(true);
}
//void Petrack::updateImage(IplImage *iplImg)
//{
// // static int prevFrame = -1; // only 1 instanze allowed!!!!!!
// //if (iplImg != mIplImg)
// //{
// //cvReleaseImage(&mIplImg); wird nun in animation gemacht
// mIplImg = iplImg;
// //}
// // //if ( online calculation || calc all)
// // if (mIplImgFiltered) // != if mIplImgFiltered != NULL a picture was shown before
// // {
// // if (mPrevIplImgFiltered)
// // cvReleaseImage(&mPrevIplImgFiltered);
// // mPrevIplImgFiltered = cvCreateImage(cvGetSize(mIplImgFiltered),8,3);
// // }
// // mPrevFrame = prevFrame;
// // prevFrame = mAnimation->getCurrentFrameNum();
//// debout << "test" << endl;
// updateImage(true);
//// debout << "test" << endl;
//}
void Petrack::updateSequence()
{
QImage *oldImage = mImage;
//cvReleaseImage(&mIplImg); darf niiiiiie gemacht werden - ewig nach fehler gesucht - kommt bei filern durcheinander!!!
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
// cvReleaseImage(&mPrevIplImgFiltered); // vorheriges bild ; NULL zeigt an, dass neue bildfolge
// mPrevFrame = -1;
// 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());
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
size2.width = mTrackingRoiItem->rect().width();
size2.height = mTrackingRoiItem->rect().height();
mTracker->init(size2);
mPlayerWidget->setAnim(mAnimation);
// debout << "test" << endl;
mPlayerWidget->skipToFrame(0);
// debout << "test" << endl;
mImageItem->setImage(mImage);//wird in updateImage gemacht
// debout << "test" << endl;
delete oldImage;
// debout << "test" << endl;
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
// die Groesse des kreises des durchschnittlichen Kopfdurchmessers, der ganzen kopf umfasst in Pixel
// annahmen: 21cm avg kopflaenge, mapDefaultheight genommen statt: 173cm avg koerpergroesse mann / frau mit Schuhen (180cm waere nur Mann)
// hS ==-1 als default besagt, dass mHeadSize neu berechnet statt gesetzt werden soll
// WENN HEADSIZE NEU BERECHNET WIRD WIRD AUTOMATISCH AUCH CMPERPIXEL MITBERECHNET
/**
* @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 accoring to mapDefaultHeigt <br>
*
* Default case recalculates mCmPerPixel
*
* @see Petrack::getCmPerPixel
* @param hS new headsize or -1, for calculating default
*/
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))