Skip to content
Snippets Groups Projects
petrack.cpp 179 KiB
Newer Older
d.kilic's avatar
d.kilic committed
        {
            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)
                    {
                        out << "#" << qSetFieldWidth(3) << (i+1) << qSetFieldWidth(0) << "|" << mTracker->at(i).comment() << Qt::endl;
                        std::cout << setw(4) << (i+1) << "|" << mTracker->at(i).comment() << 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);
}

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

    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);
}


//// calculate background for backgroud subtraction
//// WIRD NICHT MEHR BENOETIGT, DA HINTERGRUNDMODELL IM BETRIEB AKTUALISIERT WIRD!!!
//void Petrack::calcBackground()
//{
//    int memPos = mPlayerWidget->getPos();
//    if (memPos != -1) // video loaded
//    {
//        int progVal = 0;
//        int from = mControlWidget->filterBgFrom->value(); // from - frame where background begins
//        int num  = mControlWidget->filterBgNum->value(); // num  - frame number for averaging because of stabilization

//        if (from < mAnimation->getNumFrames())
//        {
//            QProgressDialog progress("Calculating background...", "Abort calculation", 0, num, this);
//            progress.setWindowModality(Qt::WindowModal); // blocks main window
//            mPlayerWidget->skipToFrame(from);

//            cvNamedWindow("BG", 1);
//            cvNamedWindow("FG", 1);
//            CvBGStatModel* bg_model = cvCreateGaussianBGModel(getIplImageFiltered());
//            //CvBGStatModel* bg_model = cvCreateFGDStatModel(getIplImageFiltered());

//            while ((++progVal < num) && (mPlayerWidget->frameForward()))
//            {
//                cvUpdateBGStatModel(getIplImageFiltered(), bg_model);
//                cvShowImage("BG", bg_model->background);
//                cvShowImage("FG", bg_model->foreground);

//                progress.setValue(progVal);
//                qApp->processEvents();
//                if (progress.wasCanceled())
//                    break;
//            }

//            cvReleaseBGStatModel(&bg_model);

//            mPlayerWidget->skipToFrame(memPos); // ruecksprung zur urspruenglichen Position
//        }
//        else
//        {
//            QMessageBox::critical(this, tr("PeTrack"), tr("from has to be smaller than %1.").arg(mAnimation->getNumFrames()));
//            return;
//        }
//    }
//}

// gibt cm pro pixel zurueck
// wert wir nur neu bestimmt, wenn auch kopfgroesse berechnet wird
double Petrack::getCmPerPixel()
{
    return mCmPerPixel;
}
// 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
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;
            //debout << mTracker->at(pers).trackPointAt(frame) << endl;

//            debout << "mTracker->at(pers).height(): " << mTracker->at(pers).height() << endl;
//            debout << "mControlWidget->mapDefaultHeight->value(): " << mControlWidget->mapDefaultHeight->value() << endl;
//            debout << "mControlWidget->mapHeight->value(): " << mControlWidget->mapHeight->value() << endl;
            int diff;
            Point3f p3d = getExtrCalibration()->get3DPoint(Point2f(mTracker->at(pers).trackPointAt(frame).x(),
                                                            mTracker->at(pers).trackPointAt(frame).y()),
                                                           mControlWidget->mapDefaultHeight->value());
                                                           //mTracker->at(pers).height()); // mStatusPosRealHeight->value());

//            debout << "Track position: (" << mTracker->at(pers).trackPointAt(frame).x() << ", " << mTracker->at(pers).trackPointAt(frame).y() << ")" << endl;
//            debout << "P3D: (" << p3d.x << ", " << p3d.y << ", " << p3d.z << ")" << endl;

            //debout << "3D Punkt: x: " << p3d.x << ", y: " << p3d.y << ", z: " << p3d.z << endl;

            Point2f p3d_x1 = getExtrCalibration()->getImagePoint( Point3f(p3d.x+HEAD_SIZE*0.5, p3d.y, p3d.z) );
            Point2f p3d_x2 = getExtrCalibration()->getImagePoint( Point3f(p3d.x-HEAD_SIZE*0.5, p3d.y, p3d.z) );
            Point2f p3d_y1 = getExtrCalibration()->getImagePoint( Point3f(p3d.x, p3d.y+HEAD_SIZE*0.5, p3d.z) );
            Point2f p3d_y2 = getExtrCalibration()->getImagePoint( Point3f(p3d.x, p3d.y-HEAD_SIZE*0.5, p3d.z) );

            diff = (int) max(sqrt(pow(p3d_x2.x-p3d_x1.x,2)+pow(p3d_x2.y-p3d_x1.y,2)),
                           sqrt(pow(p3d_y2.x-p3d_y1.x,2)+pow(p3d_y2.y-p3d_y1.y,2)));
//                    max(abs(getExtrCalibration()->getImagePoint(Point3f(p3d.x+HEAD_SIZE*0.5, p3d.y,               p3d.z)).x-
//                                 getExtrCalibration()->getImagePoint(Point3f(p3d.x-HEAD_SIZE*0.5, p3d.y,               p3d.z)).x)
//                                ,abs(getExtrCalibration()->getImagePoint(Point3f(p3d.x,           p3d.y+HEAD_SIZE*0.5, p3d.z)).y-
//                                 getExtrCalibration()->getImagePoint(Point3f(p3d.x,               p3d.y-HEAD_SIZE*0.5, p3d.z)).y));
//            debout << "HeadSize: " << diff << endl;
            return diff;// < 8 ? 8 : diff;
        }else
        {
            z = mTracker->at(pers).trackPointAt(frame).sp().z();
            h = mTracker->at(pers).height();
            if (z > 0)
                return (HEAD_SIZE*mControlWidget->coordAltitude->value() / z) / getImageItem()->getCmPerPixel();
            else if (h > MIN_HEIGHT)
                return (HEAD_SIZE*mControlWidget->coordAltitude->value() / (mControlWidget->coordAltitude->value()-h)) / getImageItem()->getCmPerPixel();
            else
                return mHeadSize;
        }
    }

    if (pos != NULL)
        return mHeadSize; // muss noch aus density map gelesen werden!!!
    else //(pos == NULL) && (pers == -1)