Skip to content
Snippets Groups Projects
petrack.cpp 180 KiB
Newer Older
  • Learn to ignore specific revisions
  • d.kilic's avatar
    d.kilic committed
    //        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() == 5) && // 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)*/)
                    {
                        QMessageBox::critical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString()));
                        return;
                    }
                    QProgressDialog progress("Export TRC-File",NULL,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())
    
    d.kilic's avatar
    d.kilic committed
                    //else
                    //    trcVersion = 2;
    
    
                    debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s), file version " << trcVersion << ")..." << std::endl;
    
    d.kilic's avatar
    d.kilic committed
                    QTextStream out(&file);
    
    
                    out << "version " << trcVersion << Qt::endl;
                    out << mTracker->size() << Qt::endl;
    
    d.kilic's avatar
    d.kilic committed
                    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;
    
    d.kilic's avatar
    d.kilic committed
                    }
                    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) )
                        QMessageBox::critical(this, tr("PeTrack"),
                                                       tr("Could not export tracking data.\n"
                                                          "Please try again!"),
                                                       QMessageBox::Ok);
                    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;
    
    d.kilic's avatar
    d.kilic committed
    
    #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))
                    {
                        QMessageBox::critical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString()));
                        return;
                    }
    
                    debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s))..." << endl;
    
    #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;
    
    d.kilic's avatar
    d.kilic committed
    
                    if (mControlWidget->exportComment->isChecked())
                    {
    
                        out << "# personal information:" << Qt::endl;
                        out << "# ID| Comment" << Qt::endl;
    
    d.kilic's avatar
    d.kilic committed
    
                        // std out
    
                        std::cout << std::endl << "Printing comment table..." << std::endl << std::endl;
                        std::cout << "ID  | Comment" << std::endl;
                        std::cout << "----|----------------" << std::endl;
    
    d.kilic's avatar
    d.kilic committed
    
                        for(int i=0;i<mTracker->size();++i)
                        {
    
                            auto commentSplit = mTracker->at(i).comment().split("\n", Qt::KeepEmptyParts);
                            out << "#" << qSetFieldWidth(3) << (i+1) << qSetFieldWidth(0) << "|" << commentSplit.at(0) << Qt::endl;
                            std::cout  << 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;
                            }
    
    d.kilic's avatar
    d.kilic committed
                        }
                    }
                    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) )
                        QMessageBox::critical(this, tr("PeTrack"),
                                                       tr("Could not export tracking data.\n"
                                                          "Please try again!"),
                                                       QMessageBox::Ok);
                    else
                        statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000);
    
    
                    std::cout << " finished" << std::endl;
    
    d.kilic's avatar
    d.kilic committed
    
    #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))
                    {
                        QMessageBox::critical(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;
    
    d.kilic's avatar
    d.kilic committed
                    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) )
                        QMessageBox::critical(this, tr("PeTrack"),
                                                       tr("Could not export tracking data.\n"
                                                          "Please try again!"),
                                                       QMessageBox::Ok);
                    else
                        statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000);
    
    
                    std::cout << " finished" << std::endl;
    
    d.kilic's avatar
    d.kilic committed
    
    
    //                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))
                    {
                        QMessageBox::critical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(fileXml.errorString()));
                        return;
                    }
    
                    debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s))..." << std::endl;
    
    d.kilic's avatar
    d.kilic committed
                    // 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;
    
    d.kilic's avatar
    d.kilic committed
                    // 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;
    
    d.kilic's avatar
    d.kilic committed
    
                    mTrackerReal->exportXml(outXml, mControlWidget->trackAlternateHeight->checkState(), mStereoWidget->stereoUseForExport->isChecked());
    
    
                    outXml << "</trajectoriesDataset>" << Qt::endl;
    
    d.kilic's avatar
    d.kilic committed
                    fileXml.flush();
                    fileXml.close();
    
                    if (QFile::exists(dest))
                        QFile::remove(dest);
    
                    if( !fileXml.copy(dest) )
                        QMessageBox::critical(this, tr("PeTrack"),
                                                       tr("Could not export tracking data.\n"
                                                          "Please try again!"),
                                                       QMessageBox::Ok);
                    else
                        statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000);
    
                    cout << " finished" << endl;
                }
                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.
     */
    
    d.kilic's avatar
    d.kilic committed
    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();
    
    
    d.kilic's avatar
    d.kilic committed
        static int lastRecoFrame = -10000;
        static bool borderChangedForTracking = false;
    
    d.kilic's avatar
    d.kilic committed
        //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
    
    d.kilic's avatar
    d.kilic committed
            if (imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged)
            {
                if (mStereoContext)
                    mStereoContext->init(mImgFiltered);
            }
    
    d.kilic's avatar
    d.kilic committed
    
    #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!" <<endl;
                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." << endl;
            }
            else
            {
    
    #ifndef STEREO_DISABLED
    
    d.kilic's avatar
    d.kilic committed
                // 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);
                }
    
    d.kilic's avatar
    d.kilic committed
            }
            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 size;
                    size.width = mImgFiltered.cols;
                    size.height = mImgFiltered.rows;
                    mTracker->resize(size);
    
                    mTrackingRoiItem->checkRect();
                }
    
    #ifndef STEREO_DISABLED
    
    d.kilic's avatar
    d.kilic committed
                // buildt disparity picture if it should be used for height detection
                if (mStereoContext && mStereoWidget->stereoUseForHeight->isChecked())
                    mStereoContext->getDisparity();
    
    d.kilic's avatar
    d.kilic committed
    
                Rect rect;
                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,
    
    d.kilic's avatar
    d.kilic committed
                                          mControlWidget->trackRepeat->isChecked(),
    
    d.kilic's avatar
    d.kilic committed
                                          mControlWidget->trackRepeatQual->value(), getImageBorderSize(),
    
    d.kilic's avatar
    d.kilic committed
                                          mControlWidget->trackRegionLevels->value(), getOnlyVisible());
    
    d.kilic's avatar
    d.kilic committed
    #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
    
    d.kilic's avatar
    d.kilic committed
                // 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
    
    d.kilic's avatar
    d.kilic committed
                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;
    
    d.kilic's avatar
    d.kilic committed
                    int recoMethod = mControlWidget->getRecoMethod();
    #ifdef TIME_MEASUREMENT
                    //        "==========: "
                    debout << "vor   reco: " << getElapsedTime() <<endl;
    #endif
                    if ((recoMethod == 0) || (recoMethod == 1) || (recoMethod == 3) || (recoMethod == 4) || (recoMethod == 5) || (recoMethod == 6)) //else
                    { // 0 == Kaserne, 1 == Hermes, 2 == Ohne, 3 == Color, 4 == Japan, 5 == MultiColor, 6 == CodeMarker
                        // persList == crossList
                        //                    getMarkerPos(mIplImgFiltered, rect, &persList, mControlWidget->markerBrightness->value(),
                        //                                getImageBorderSize(), (mControlWidget->markerIgnoreWithout->checkState() == Qt::Checked),
                        //                                (mControlWidget->recoAutoWB->checkState() == Qt::Checked), getBackgroundFilter(), recoMethod); //#tempImg
                        getMarkerPos(mImgFiltered, rect, &persList, mControlWidget, getImageBorderSize(), getBackgroundFilter());
    
    d.kilic's avatar
    d.kilic committed
    //                    debout << "Testausgabe persList: [Frame " << frameNum << "] " << endl;
    //                    for (int i = 0; i < persList.size(); ++i)
    //                    {
    //                        cout << persList.at(i) << endl;
    //                    }
                    }
    
    #ifndef STEREO_DISABLED
    
    d.kilic's avatar
    d.kilic committed
                    if (mStereoContext && mStereoWidget->stereoUseForReco->isChecked())
                    {
                        PersonList pl;
                        pl.calcPersonPos(mImgFiltered, rect, persList, mStereoContext, getBackgroundFilter(), markerLess);
                    }
    
    d.kilic's avatar
    d.kilic committed
    #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\">&nbsp;%1</font>").arg(s));
                    //     else
                    //         mStatusLabelColor->setText(QString("<font color=\"#000000\">&nbsp;%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);
    
    d.kilic's avatar
    d.kilic committed
    
            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 Mat &img)
    {
        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());
    
        Size size2;
        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
     */
    
    d.kilic's avatar
    d.kilic committed
    double Petrack::getCmPerPixel()
    {
        return mCmPerPixel;
    }
    
    d.kilic's avatar
    d.kilic committed
    // 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
     */
    
    d.kilic's avatar
    d.kilic committed
    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 )
            {
    
                //debout << "getHeadSize: " << pers << " " << frame << endl;