diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..8d7803d2c5bf9b41a45fbeaaf3a50372a4f374e0 --- /dev/null +++ b/.clang-format @@ -0,0 +1,46 @@ +--- +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveMacros: true +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BreakBeforeBraces: Allman +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: AfterColon +ColumnLimit: 120 +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +Cpp11BracedListStyle: true +FixNamespaceComments: true +IncludeBlocks: Regroup +IndentCaseLabels: true +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: Inner +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: Never +SpaceBeforeRangeBasedForLoopColon: true +Standard: c++17 +TabWidth: 4 +UseTab: Never +... diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e74958b1b7a4866098f39bae5bd216a77277b71d..ac343277d6351c5c10959424041ff238f94c5e5f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,6 +19,7 @@ ## stages: - build_environment + - pre-build-checks - build - test - build_installer @@ -41,6 +42,12 @@ build_container: - changes: - container/ubuntu/Dockerfile +pre-build-checks: + image: $CI_REGISTRY_IMAGE:${CI_COMMIT_REF_SLUG}_linux + stage: pre-build-checks + script: + - scripts/check-format-cpp.sh + # Build petrack and petrack unit_tests build_linux: image: $CI_REGISTRY_IMAGE:${CI_COMMIT_REF_SLUG}_linux diff --git a/container/ubuntu/Dockerfile b/container/ubuntu/Dockerfile index 0e727fb7b6322b2043ea240d725ffe0ac7e17b57..1df2d999be1fe3c3ac73bff425fe8696c70443da 100644 --- a/container/ubuntu/Dockerfile +++ b/container/ubuntu/Dockerfile @@ -4,12 +4,18 @@ FROM ubuntu:20.10 RUN apt-get update && apt-get install -y software-properties-common # Install the needed tools -RUN apt-get update && apt-get install -y wget \ - git \ - g++ \ - make \ - ninja-build \ - cmake +RUN echo "deb [trusted=yes] http://apt.llvm.org/groovy/ llvm-toolchain-groovy-12 main" | tee /etc/apt/sources.list.d/clang.list && \ + apt-get update && \ + apt-get install -y \ + wget \ + git \ + g++ \ + make \ + ninja-build \ + cmake \ + parallel \ + catch2 \ + clang-format-12 # Install the needed libraries RUN apt-get update && apt-get install -y \ diff --git a/include/IO.h b/include/IO.h index 67ec126394fd0bf6fdf56a65c0f4a0c1f4411b95..1d07623b0ed7757d8dc28eee28810a7d5f30a2d9 100644 --- a/include/IO.h +++ b/include/IO.h @@ -21,12 +21,12 @@ #ifndef IO_H #define IO_H -#include <variant> -#include <unordered_map> -#include <string> #include <QString> #include <ezc3d_all.h> #include <opencv2/opencv.hpp> +#include <string> +#include <unordered_map> +#include <variant> class MoCapStorage; class MoCapPerson; class MoCapPersonMetadata; @@ -34,19 +34,16 @@ class MoCapPersonMetadata; namespace IO { - std::variant<std::unordered_map<int, float>, std::string> - readHeightFile(const QString& heightFileName); +std::variant<std::unordered_map<int, float>, std::string> readHeightFile(const QString &heightFileName); - void readMoCapC3D(MoCapStorage &storage, const MoCapPersonMetadata &metadata); - void readSkeletonC3D_XSENS( - const ezc3d::c3d &c3d, - MoCapPerson &person, - const std::function<cv::Point3f(const ezc3d::DataNS::Points3dNS::Point&)>& c3dToPoint3f - ); +void readMoCapC3D(MoCapStorage &storage, const MoCapPersonMetadata &metadata); +void readSkeletonC3D_XSENS( + const ezc3d::c3d & c3d, + MoCapPerson & person, + const std::function<cv::Point3f(const ezc3d::DataNS::Points3dNS::Point &)> &c3dToPoint3f); - std::variant<std::unordered_map<int, int>, std::string> - readMarkerIDFile(const QString& markerFileName); +std::variant<std::unordered_map<int, int>, std::string> readMarkerIDFile(const QString &markerFileName); - std::vector<std::string> readAuthors(const QString & authorsFile); -} -#endif //IO_H +std::vector<std::string> readAuthors(const QString &authorsFile); +} // namespace IO +#endif // IO_H diff --git a/include/aboutDialog.h b/include/aboutDialog.h index ecec73a297d82582641bc0c1f998d00743af16f4..19f5920feac20c09296055eebe15ee0eec95582a 100644 --- a/include/aboutDialog.h +++ b/include/aboutDialog.h @@ -22,32 +22,35 @@ #ifndef ABOUTDIALOG_H #define ABOUTDIALOG_H -namespace Ui { - class About; +namespace Ui +{ +class About; } -class AboutDialog : public QDialog { - Q_OBJECT +class AboutDialog : public QDialog +{ + Q_OBJECT public: - AboutDialog(QWidget *parent, - const QString & version, - const QString & commitHash, - const QString & commitDate, - const QString & commitBranch, - const QString & compiler, - const QString & compilerVersion, - const QString & compileDate, - const std::vector<std::string> & authors); + AboutDialog( + QWidget * parent, + const QString & version, + const QString & commitHash, + const QString & commitDate, + const QString & commitBranch, + const QString & compiler, + const QString & compilerVersion, + const QString & compileDate, + const std::vector<std::string> &authors); AboutDialog(const AboutDialog &) = delete; - AboutDialog & operator=(AboutDialog) = delete; - AboutDialog(const AboutDialog &&) = delete; - AboutDialog & operator=(AboutDialog &&) = delete; + AboutDialog &operator=(AboutDialog) = delete; + AboutDialog(const AboutDialog &&) = delete; + AboutDialog &operator=(AboutDialog &&) = delete; ~AboutDialog() override; private: - Ui::About * mUi; + Ui::About *mUi; }; #endif // ABOUTDIALOG_H diff --git a/include/analysePlot.h b/include/analysePlot.h index 8c3e861a2349cfc9c919688511ceac5712865931..3a5c97e1a7bc44623c64194141e833c2e4459a46 100644 --- a/include/analysePlot.h +++ b/include/analysePlot.h @@ -21,39 +21,35 @@ #ifndef ANALYSEPLOT_H #define ANALYSEPLOT_H -#include <QPen> - -#include <qwt_plot.h> -#include <qwt_plot_zoomer.h> -#include <qwt_plot_item.h> - #include "helper.h" #include "tracker.h" #include "trackerReal.h" -class Control; +#include <QPen> +#include <qwt_plot.h> +#include <qwt_plot_item.h> +#include <qwt_plot_zoomer.h> -//----------------------------------------------------------------- +class Control; -class TrackerRealPlotItem: public QwtPlotItem +class TrackerRealPlotItem : public QwtPlotItem { public: TrackerRealPlotItem(); - void draw(QPainter* p, const QwtScaleMap& mapX, const QwtScaleMap& mapY, const QRectF& re) const; + void draw(QPainter *p, const QwtScaleMap &mapX, const QwtScaleMap &mapY, const QRectF &re) const; void setPen(const QPen &pen); - void setTrackerReal(TrackerReal* trackerReal); + void setTrackerReal(TrackerReal *trackerReal); private: TrackerReal *mTrackerReal; - QPen mPen; + QPen mPen; }; -//----------------------------------------------------------------------------------------- -class AnalysePlot: public QwtPlot +class AnalysePlot : public QwtPlot { Q_OBJECT @@ -62,55 +58,28 @@ public: QPoint getPos(const QColor &col) const; - inline void setControlWidget(Control *control) - { - mControlWidget = control; - } - inline Control * getControlWidget() const - { - return mControlWidget; - } - inline void setActFrame(int f) - { - mActFrame = f; - } - inline int getActFrame() const - { - return mActFrame; - } - void setTrackerReal(TrackerReal* TR); - void setScale(); - - inline double symbolSize() const - { - return mSymbolSize; - } - inline void setSymbolSize(double s) - { - mSymbolSize = s; - } - QwtPlotZoomer * getZoomer() - { - return mZoomer; - } - - inline double xMax() const - { - return mXMax; - } - inline double yMax() const - { - return mYMax; - } + inline void setControlWidget(Control *control) { mControlWidget = control; } + inline Control *getControlWidget() const { return mControlWidget; } + inline void setActFrame(int f) { mActFrame = f; } + inline int getActFrame() const { return mActFrame; } + void setTrackerReal(TrackerReal *TR); + void setScale(); + + inline double symbolSize() const { return mSymbolSize; } + inline void setSymbolSize(double s) { mSymbolSize = s; } + QwtPlotZoomer *getZoomer() { return mZoomer; } + + inline double xMax() const { return mXMax; } + inline double yMax() const { return mYMax; } private: - double mSymbolSize; - double mXMin, mXMax, mYMin, mYMax; - Control *mControlWidget; - TrackerReal *mTrackerReal; + double mSymbolSize; + double mXMin, mXMax, mYMin, mYMax; + Control * mControlWidget; + TrackerReal * mTrackerReal; TrackerRealPlotItem *mTrackerRealItem; - QwtPlotZoomer *mZoomer; - int mActFrame; + QwtPlotZoomer * mZoomer; + int mActFrame; }; #endif diff --git a/include/animation.h b/include/animation.h index e08dbd4c5877d16dd300fabd85edb965cb5a63ef..bfe5043ad074f30fbe0005efd74ff8e3623da79b 100644 --- a/include/animation.h +++ b/include/animation.h @@ -21,15 +21,14 @@ #ifndef ANIMATION_H #define ANIMATION_H -#include <QWidget> +#include <QFileInfo> +#include <QImage> #include <QPair> #include <QPixmap> #include <QSize> -#include <QImage> #include <QStringList> #include <QTime> -#include <QFileInfo> - +#include <QWidget> #include <opencv2/opencv.hpp> #ifdef STEREO @@ -51,23 +50,22 @@ class Petrack; * (FPS, resolution, etc.) and to the sequene itself is managed by * this class. */ -class Animation{ - +class Animation +{ public: - // Constructor & Destructor Animation(QWidget *wParent); ~Animation(); - + // Returns the next frame of the animation cv::Mat getNextFrame(); - + // Returns the previous frame of the animation cv::Mat getPreviousFrame(); - + // Returns the frame at the index index cv::Mat getFrameAtIndex(int index); - + // Returns the frame at the position position // positions is a double between 0 and 1 that indicates the position in the animation cv::Mat getFrameAtPos(double position); @@ -91,40 +89,40 @@ public: // Opens a live stream of the camera with id ID bool openCameraStream(int camID); - // Returns the number of frames in the current animation - int getNumFrames(); + // Returns the number of frames in the current animation + int getNumFrames(); // Returns the maximum number of frames in the source file int getMaxFrames() const; - - // Returns the index of the current frame + + // Returns the index of the current frame int getCurrentFrameNum() const; // Sets the sourceIn/Out frame numbers - void updateSourceInFrameNum(int in=-1); - void updateSourceOutFrameNum(int out=-1); + void updateSourceInFrameNum(int in = -1); + void updateSourceOutFrameNum(int out = -1); // Returns the sourceIn/Out frame numbers int getSourceInFrameNum() const; int getSourceOutFrameNum() const; - - // Returns the filename of the current frame + + // Returns the filename of the current frame QString getCurrentFileName(); - + // Returns the FPS of the current animation if it is a video double getFPS(); double getOriginalFPS() const; void setFPS(double fps); - + // Returns the size of the original frames (could made bigger after filtering) QSize getSize(); - + // free's all the data in animation void free(); void reset(); - + bool isVideo() const; bool isStereoVideo() const; bool isImageSequence() const; @@ -132,12 +130,12 @@ public: #ifndef STEREO_DISABLED enum Camera getCamera(); - void setCamera(enum Camera); + void setCamera(enum Camera); #endif int getFirstFrameSec() const; int getFirstFrameMicroSec() const; - QString getFileBase(); + QString getFileBase(); QFileInfo getFileInfo(); #ifndef STEREO_DISABLED @@ -150,11 +148,10 @@ public: #endif private: - Petrack *mMainWindow; // name, info of the video or sequence - QString mFileBase; - QString mFileSuffix; + QString mFileBase; + QString mFileSuffix; QFileInfo mFileInfo; // Indicate if the current animation is a video or a photo or a stereo video @@ -163,26 +160,27 @@ private: #ifndef STEREO_DISABLED // indicates which camera is used for stereo video enum Camera mCamera; - #endif +#endif // Image that will be used by the animation and that will be returned in the public functions cv::Mat mImage; - - // Size of the frame + + // Size of the frame QSize mSize; - - // Number of frames in the whole animation + + // Number of frames in the whole animation int mMaxFrames; - + // Number of frames per second in video double mFps; double mOriginalFps; - // the time (seconds since 1.1.1970 0 uhr, microseconds (.000001s)) when the first frame was recorded (bumblebee .time file) + // the time (seconds since 1.1.1970 0 uhr, microseconds (.000001s)) when the first frame was recorded (bumblebee + // .time file) int mFirstSec; int mFirstMicroSec; - // Index of the current opened frame + // Index of the current opened frame int mCurrentFrame; // Index of sourceIn/Out frame @@ -195,16 +193,16 @@ private: // indicates, if time file is loaded inside the open sequence bool mTimeFileLoaded; - /******************************************/ + /******************************************/ /*** Sequence of photos implementation ***/ /******************************************/ // Methods // Implementation of the openAnimation function for photo series - // Opens an animation made of photos + // Opens an animation made of photos bool openAnimationPhoto(QString fileName); - + // Implementation of getFrameAtIndex for photo series // Returns the frame at index index in the serie cv::Mat getFramePhoto(int index); @@ -217,15 +215,15 @@ private: void freePhoto(); // Sets the sourceIn/Out frame numbers - void setSourceInFrameNum(int in=-1); - void setSourceOutFrameNum(int out=-1); + void setSourceInFrameNum(int in = -1); + void setSourceOutFrameNum(int out = -1); - // Variables + // Variables // A list with all the filenames of the series QStringList mImgFilesList; - - /******************************************/ + + /******************************************/ /*** Video implementation ***/ /******************************************/ @@ -234,7 +232,7 @@ private: // fileNumber indicates the number of the successive files splited while writing // nur bei einer ganz neuen sequenz ist stereoImgBuffer != 0 #ifndef STEREO_DISABLED - bool openAnimationStereoVideo(int fileNumber, IplImage* stereoImgLeft, IplImage* stereoImgRight); + bool openAnimationStereoVideo(int fileNumber, IplImage *stereoImgLeft, IplImage *stereoImgRight); #endif bool openAnimationStereoVideo(int fileNumber, cv::Mat &stereoImgLeft, cv::Mat &stereoImgRight); @@ -242,20 +240,20 @@ private: bool openAnimationStereoVideo(QString fileName); // Implementation of the openAnimation function for videos - // Opens an animation from a video file + // Opens an animation from a video file bool openAnimationVideo(QString fileName); - + // Implementation of getFrameAtIndex for videos // Returns the frame at index index in the video cv::Mat getFrameVideo(int index); - + // Gets Size and Frame number information of the recently open animation // It is thought to be called once just at the opening of an animation bool getInfoVideo(QString fileName); bool getCameraInfo(); - - // Free's the video data + + // Free's the video data void freeVideo(); @@ -276,7 +274,7 @@ private: // A list with all the filenames of the stereo video series QStringList mStereoVideoFilesList; - #endif +#endif }; #endif diff --git a/include/autoCalib.h b/include/autoCalib.h index 582ffea34ff7d92f7c11a1a73170a92c6b38f650..d1aebe8d3a51976984c04e1ba7f195e1eaa11240 100644 --- a/include/autoCalib.h +++ b/include/autoCalib.h @@ -21,8 +21,9 @@ #ifndef AUTOCALIB_H #define AUTOCALIB_H -#include<QString> -#include<QStringList> +#include <QString> +#include <QStringList> +#include <opencv2/core/types.hpp> class Petrack; class Control; @@ -47,13 +48,13 @@ public: AutoCalib(); ~AutoCalib(); - void setMainWindow(Petrack *mw); - bool isEmptyCalibFiles(); - void addCalibFile(const QString &f); - QString getCalibFile(int i); + void setMainWindow(Petrack *mw); + bool isEmptyCalibFiles(); + void addCalibFile(const QString &f); + QString getCalibFile(int i); QStringList getCalibFiles(); - void setCalibFiles(const QStringList &fl); - bool openCalibFiles(); // return true if at least one file is selected + void setCalibFiles(const QStringList &fl); + bool openCalibFiles(); // return true if at least one file is selected inline void setBoardSizeX(int i) // 6 { mBoardSizeX = i; @@ -82,15 +83,22 @@ public: void autoCalib(); private: - int runCalibration(std::vector<std::vector<cv::Point2f> > corners, cv::Size img_size, cv::Size board_size, - float square_size, float aspect_ratio, int flags, - cv::Mat &camera_matrix, cv::Mat &dist_coeffs, double *reproj_errs); + int runCalibration( + std::vector<std::vector<cv::Point2f>> corners, + cv::Size img_size, + cv::Size board_size, + float square_size, + float aspect_ratio, + int flags, + cv::Mat & camera_matrix, + cv::Mat & dist_coeffs, + double * reproj_errs); - Petrack *mMainWindow; - Control *mControlWidget; + Petrack * mMainWindow; + Control * mControlWidget; QStringList mCalibFiles; - int mBoardSizeX, mBoardSizeY; - float mSquareSize; + int mBoardSizeX, mBoardSizeY; + float mSquareSize; }; #endif diff --git a/include/aviFileWriter.h b/include/aviFileWriter.h index 71e5cc6cfe3a88b50072cf2a5b1d13400f60ce7a..b8654a078d0f89e4fd674faae838173baf69d060 100644 --- a/include/aviFileWriter.h +++ b/include/aviFileWriter.h @@ -28,7 +28,7 @@ // Byte Number (nicht alle Zahlen gehen?: 2*1280*960*32*20) enstehen avi mit einem bild // unter 2GB fuer reader und unter 4 GB fuer writer bleiben!!! // 2*1280*960*32*20 = 1,5 GB = 40 Sekunden = 640 Bilder -inline constexpr int AVI_FILE_SPLIT_SIZE = ( ( 2*1280*960*32*20 ) ); +inline constexpr int AVI_FILE_SPLIT_SIZE = ((2 * 1280 * 960 * 32 * 20)); /** * A simple wrapper for an .AVI file . @@ -36,134 +36,117 @@ inline constexpr int AVI_FILE_SPLIT_SIZE = ( ( 2*1280*960*32*20 ) ); class AviFileWriter { public: - /** Default constructor. */ - AviFileWriter(); - - /** Default destructor. */ - virtual ~AviFileWriter(); - - /** - * Open an AVI for writing. - * - * @param iCols Width, in pixels, of each frame. - * @param iRows Hight, in pixels, of each frame. - * @param ibpp Bits per pixel -- 24 (BGR), 32 (BGRU). or 8 bit greyscale. - * @param dFramerate Framerate that the .avi will play back in. - */ - bool open( - const char* pszFilename, - int iCols, - int iRows, - int ibpp, - double dFramerate ); - - /** - * Open an AVI for writing. Deprecated. - * - * @param iCols Width, in pixels, of each frame. - * @param iRows Hight, in pixels, of each frame. - * @param ibpp Bits per pixel -- 24 (BGR), 32 (BGRU). or 8 bit greyscale. - * @param iFramerate Framerate that the .avi will play back in. - */ - bool open( - const char* pszFilename, - int iCols, - int iRows, - int ibpp, - int iFramerate ); - - /** - * Open an .avi for writing. The size of the avi file will be limited to SPLIT_SIZE bytes. - * The file is splited automatically. - * - * @param iCols Width, in pixels, of each frame. - * @param iRows Hight, in pixels, of each frame. - * @param ibpp Bits per pixel -- 24 (BGR), 32 (BGRU). or 8 bit greyscale. - * @param iFramerate Framerate that the .avi will play back in. - */ - bool openSizeLimitedAVI( - const char* pszFilename, - int iCols, - int iRows, - int ibpp, - double iFramerate ); - - /** Get the the bytes written */ - long int bytesWritten() const; - - /** - * Load a bitmap from a file and append it to the current open .avi. - * Must be in the correct format. - */ - bool appendBMP( const char* pszFilename ); - - /** - * Add a frame (in the specified format) to the open .avi - */ - bool appendFrame( const unsigned char* pBuffer, bool bInvert = true ); - - /** Close the .avi file. This is also done by the destructor. */ - bool close(); + /** Default constructor. */ + AviFileWriter(); + + /** Default destructor. */ + virtual ~AviFileWriter(); + + /** + * Open an AVI for writing. + * + * @param iCols Width, in pixels, of each frame. + * @param iRows Hight, in pixels, of each frame. + * @param ibpp Bits per pixel -- 24 (BGR), 32 (BGRU). or 8 bit greyscale. + * @param dFramerate Framerate that the .avi will play back in. + */ + bool open(const char *pszFilename, int iCols, int iRows, int ibpp, double dFramerate); + + /** + * Open an AVI for writing. Deprecated. + * + * @param iCols Width, in pixels, of each frame. + * @param iRows Hight, in pixels, of each frame. + * @param ibpp Bits per pixel -- 24 (BGR), 32 (BGRU). or 8 bit greyscale. + * @param iFramerate Framerate that the .avi will play back in. + */ + bool open(const char *pszFilename, int iCols, int iRows, int ibpp, int iFramerate); + + /** + * Open an .avi for writing. The size of the avi file will be limited to SPLIT_SIZE bytes. + * The file is splited automatically. + * + * @param iCols Width, in pixels, of each frame. + * @param iRows Hight, in pixels, of each frame. + * @param ibpp Bits per pixel -- 24 (BGR), 32 (BGRU). or 8 bit greyscale. + * @param iFramerate Framerate that the .avi will play back in. + */ + bool openSizeLimitedAVI(const char *pszFilename, int iCols, int iRows, int ibpp, double iFramerate); + + /** Get the the bytes written */ + long int bytesWritten() const; + + /** + * Load a bitmap from a file and append it to the current open .avi. + * Must be in the correct format. + */ + bool appendBMP(const char *pszFilename); + + /** + * Add a frame (in the specified format) to the open .avi + */ + bool appendFrame(const unsigned char *pBuffer, bool bInvert = true); + + /** Close the .avi file. This is also done by the destructor. */ + bool close(); protected: + /** Height, in pixels, of each frame in the .avi. */ + int m_iRows; - /** Height, in pixels, of each frame in the .avi. */ - int m_iRows; + /** Width, in pixels, of each frame in the .avi. */ + int m_iCols; - /** Width, in pixels, of each frame in the .avi. */ - int m_iCols; + /** Bits per pixel of the .avi. */ + int m_iBPP; - /** Bits per pixel of the .avi. */ - int m_iBPP; + /** Row increment, in bytes. */ + int m_iRowInc; - /** Row increment, in bytes. */ - int m_iRowInc; + /** Image size in bytes. */ + int m_iSize; - /** Image size in bytes. */ - int m_iSize; + /** Frame rate */ + double m_frameRate; - /** Frame rate */ - double m_frameRate; + /** Time index for current frame. */ + int m_iTimeIndex; - /** Time index for current frame. */ - int m_iTimeIndex; + /** Temporary image buffer. */ + unsigned char *m_pTempBuffer; - /** Temporary image buffer. */ - unsigned char* m_pTempBuffer; + /** Temporary image buffer */ + cv::Mat m_frame; - /** Temporary image buffer */ - cv::Mat m_frame; + /** Temporary buffer for saving .bmps. */ + unsigned char *m_pTempBMPBuffer; - /** Temporary buffer for saving .bmps. */ - unsigned char* m_pTempBMPBuffer; + /** Avi file counter. */ + int m_iSplitFile; - /** Avi file counter. */ - int m_iSplitFile; + /** Flag indicating if the size of the avi file is limited to AVI_FILE_SPLIT_SIZE bytes */ + bool m_bSizeLimited; - /** Flag indicating if the size of the avi file is limited to AVI_FILE_SPLIT_SIZE bytes */ - bool m_bSizeLimited; + /** Total bytes written. */ + long int m_liBytesWritten; - /** Total bytes written. */ - long int m_liBytesWritten; + /** avi file name */ + std::string m_szAVIDestFile; - /** avi file name */ - std::string m_szAVIDestFile; + char *m_fourCC; - char* m_fourCC; - - /** Defines is color avi */ - bool m_isColor; + /** Defines is color avi */ + bool m_isColor; private: + /** Read and verify the OpenCV version. */ + bool checkOpenCVVersion(); - /** Read and verify the OpenCV version. */ - bool checkOpenCVVersion(); - - /** Read the opened AVI-File */ - cv::VideoCapture m_vReader; + /** Read the opened AVI-File */ + cv::VideoCapture m_vReader; - /** Writes to the opened AVI-File */ - cv::VideoWriter m_vWriter; + /** Writes to the opened AVI-File */ + cv::VideoWriter m_vWriter; }; #endif // #ifndef AVIFILEWRITER_H diff --git a/include/backgroundFilter.h b/include/backgroundFilter.h index fb2c4a0d1abb2f689f8c1be00da08220cf56a76c..a2a01b3388c047f6257465ac5f7a453534194f7f 100644 --- a/include/backgroundFilter.h +++ b/include/backgroundFilter.h @@ -22,27 +22,24 @@ #define BACKGROUNDFILTER_H #include "filter.h" +#include "stereoContext.h" #include <QString> - #include <opencv2/opencv.hpp> #include <opencv2/video/background_segm.hpp> -#include "stereoContext.h" - class BackgroundFilter : public Filter { private: - cv::Ptr<cv::BackgroundSubtractorMOG2> mBgModel; - bool mUpdate; // if 0, kein update des models, sonst schon - pet::StereoContext** mStereoContext; ///< zeiger auf den zeiger in petrack mit stereocontext - cv::Mat mBgPointCloud; - cv::Mat mForeground; - QString mLastFile; - double mDefaultHeight; + bool mUpdate; // if 0, kein update des models, sonst schon + pet::StereoContext **mStereoContext; ///< zeiger auf den zeiger in petrack mit stereocontext + cv::Mat mBgPointCloud; + cv::Mat mForeground; + QString mLastFile; + double mDefaultHeight; public: BackgroundFilter(); @@ -54,16 +51,16 @@ public: bool update() const; QString getFilename(); - void setFilename(const QString &fn); + void setFilename(const QString &fn); bool load(QString dest = ""); bool save(QString dest = ""); - void setStereoContext(pet::StereoContext **sc); - pet::StereoContext** stereoContext(); + void setStereoContext(pet::StereoContext **sc); + pet::StereoContext **stereoContext(); cv::Mat getForeground(); ///< nutzen, wenn ueber ganzes bild foreground benutzt wird - bool isForeground(int i, int j); + bool isForeground(int i, int j); void reset(); diff --git a/include/backgroundItem.h b/include/backgroundItem.h index af4cb006e10982c4251ae68bff8e0bd8b48e7ca2..1c22bed0e2632d1bc89f916cfc0b61240b264b21 100644 --- a/include/backgroundItem.h +++ b/include/backgroundItem.h @@ -31,12 +31,12 @@ class BackgroundItem : public QGraphicsItem { private: Petrack *mMainWindow; - QImage *mImage; + QImage * mImage; public: - BackgroundItem(QWidget *wParent, QGraphicsItem * parent = nullptr); + BackgroundItem(QWidget *wParent, QGraphicsItem *parent = nullptr); QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); }; #endif diff --git a/include/blurFilter.h b/include/blurFilter.h index f57a4b8f51ab1a5bc316d52a6d6266ea41314db5..c973c85a8896952a0522e677a38c275a3e4751ea 100644 --- a/include/blurFilter.h +++ b/include/blurFilter.h @@ -21,22 +21,18 @@ #ifndef BLURFILTER_H #define BLURFILTER_H -#include <opencv2/opencv.hpp> #include "filter.h" +#include <opencv2/opencv.hpp> + class BlurFilter : public Filter { public: - BlurFilter() - :Filter() - { - p=1; - } + BlurFilter() : Filter() { p = 1; } cv::Mat act(cv::Mat &img, cv::Mat &res); - void setParam(double newp); + void setParam(double newp); private: - //parameter double p; }; diff --git a/include/calibFilter.h b/include/calibFilter.h index 9c1e22a067ad357dae54a5c4045033d9c8090e56..b92bab6e4f7ce7e4c474720d35a14e74065d873a 100644 --- a/include/calibFilter.h +++ b/include/calibFilter.h @@ -36,16 +36,16 @@ private: Parameter mFy; Parameter mCx; Parameter mCy; - Parameter mR2;//mK1 - Parameter mR4;//mK2 + Parameter mR2; // mK1 + Parameter mR4; // mK2 Parameter mTx; Parameter mTy; - Parameter mR6;//mK3 + Parameter mR6; // mK3 Parameter mK4; Parameter mK5; Parameter mK6; - cv::Mat map1; - cv::Mat map2; + cv::Mat map1; + cv::Mat map2; public: CalibFilter(); diff --git a/include/calibStereoFilter.h b/include/calibStereoFilter.h index 21d2088a288736153eaee341505a7519e81f10c1..a33c17537b2cf43e3f6fbd510cf56c74cdab9e42 100644 --- a/include/calibStereoFilter.h +++ b/include/calibStereoFilter.h @@ -34,9 +34,8 @@ public: cv::Mat act(cv::Mat &img, cv::Mat &res); - void setStereoContext(pet::StereoContext* stereoContext); + void setStereoContext(pet::StereoContext *stereoContext); }; - #endif diff --git a/include/codeMarkerItem.h b/include/codeMarkerItem.h index 1263cce759d98134985a420917e7647b1155e0a1..a1a957569c939ce019cce000b1942986a8d1ee81 100644 --- a/include/codeMarkerItem.h +++ b/include/codeMarkerItem.h @@ -21,49 +21,52 @@ #ifndef CODEMARKERITEM_H #define CODEMARKERITEM_H -#include <QGraphicsItem> - #include "vector.h" +#include <QGraphicsItem> + class Petrack; class Control; class Tracker; -namespace reco { - class CodeMarkerOptions; +namespace reco +{ +class CodeMarkerOptions; } -struct OffsetMarker { +struct OffsetMarker +{ std::vector<cv::Point2f> corners; - Vec2F offset; + Vec2F offset; - OffsetMarker(std::vector<cv::Point2f> corn, Vec2F off) : corners(corn), offset(off) {}; + OffsetMarker(std::vector<cv::Point2f> corn, Vec2F off) : corners(corn), offset(off){}; }; class CodeMarkerItem : public QGraphicsItem { private: - Petrack *mMainWindow; + Petrack * mMainWindow; const reco::CodeMarkerOptions &mArucoOptions; - const QColor mRejectedColor = QColor(255,0,0); // red - const QColor mCornerColor = QColor(0,0,255); // blue - const QColor mAcceptedColor = QColor(0,255,0); // green + const QColor mRejectedColor = QColor(255, 0, 0); // red + const QColor mCornerColor = QColor(0, 0, 255); // blue + const QColor mAcceptedColor = QColor(0, 255, 0); // green - std::vector<int> mIds; + std::vector<int> mIds; std::vector<OffsetMarker> mCorners, mRejected; - Vec2F mUlc; // upper left corner to draw + Vec2F mUlc; // upper left corner to draw public: - CodeMarkerItem(QWidget *wParent, const reco::CodeMarkerOptions &options, QGraphicsItem * parent = nullptr); + CodeMarkerItem(QWidget *wParent, const reco::CodeMarkerOptions &options, QGraphicsItem *parent = nullptr); QRectF boundingRect() const override; - void setRect(Vec2F& v); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; - void addDetectedMarkers(std::vector<std::vector<cv::Point2f> > corners, std::vector<int> ids, Vec2F offset = Vec2F(0,0)); - void addRejectedMarkers(std::vector<std::vector<cv::Point2f> > rejected, Vec2F offset = Vec2F(0,0)); + void setRect(Vec2F &v); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + void + addDetectedMarkers(std::vector<std::vector<cv::Point2f>> corners, std::vector<int> ids, Vec2F offset = Vec2F(0, 0)); + void addRejectedMarkers(std::vector<std::vector<cv::Point2f>> rejected, Vec2F offset = Vec2F(0, 0)); void resetSavedMarkers(); private: - void drawMarker(const OffsetMarker& currentMarker, int id, const QColor& borderColor, QPainter *painter); + void drawMarker(const OffsetMarker ¤tMarker, int id, const QColor &borderColor, QPainter *painter); static constexpr int numCorners = 4; }; diff --git a/include/codeMarkerWidget.h b/include/codeMarkerWidget.h index 658a18568b0f38fd62ad8f59e8ccdbfde2b7c943..2587102f99cee479844058cbe244a0933a396325 100644 --- a/include/codeMarkerWidget.h +++ b/include/codeMarkerWidget.h @@ -21,26 +21,24 @@ #ifndef CODEMARKERWIDGET_H #define CODEMARKERWIDGET_H -#include <QtWidgets> -#include <opencv2/aruco.hpp> - - - -#include "petrack.h" #include "codeMarkerItem.h" +#include "petrack.h" #include "recognition.h" -namespace Ui{ - class CodeMarker; -} +#include <QtWidgets> +#include <opencv2/aruco.hpp> +namespace Ui +{ +class CodeMarker; +} -class CodeMarkerWidget: public QWidget +class CodeMarkerWidget : public QWidget { Q_OBJECT public: - CodeMarkerWidget(QWidget *parent, reco::CodeMarkerOptions& opt, Ui::CodeMarker *mUi); + CodeMarkerWidget(QWidget *parent, reco::CodeMarkerOptions &opt, Ui::CodeMarker *mUi); // store data in xml node void setXml(QDomElement &elem); @@ -68,7 +66,7 @@ private slots: private: Ui::CodeMarker *mUi; - Petrack *mMainWindow; + Petrack * mMainWindow; reco::CodeMarkerOptions &mCodeMarkerOpt; }; diff --git a/include/colorMarkerItem.h b/include/colorMarkerItem.h index 2bb7ef52e65bc1aa8b2f2d6cd675a2765f6c89c9..ed08803fa6b3a319cc289857c0a51a458a2d7199 100644 --- a/include/colorMarkerItem.h +++ b/include/colorMarkerItem.h @@ -21,10 +21,10 @@ #ifndef COLORMARKERITEM_H #define COLORMARKERITEM_H -#include <QGraphicsItem> - #include "vector.h" +#include <QGraphicsItem> + class Petrack; class Control; class Tracker; @@ -33,20 +33,17 @@ class ColorMarkerItem : public QGraphicsItem { private: Petrack *mMainWindow; - QImage *mImage; - cv::Mat mMask; - Vec2F mUlc; // upper left corner to draw + QImage * mImage; + cv::Mat mMask; + Vec2F mUlc; // upper left corner to draw public: - ColorMarkerItem(QWidget *wParent, QGraphicsItem * parent = nullptr); - QRectF boundingRect() const; - void setRect(Vec2F& v); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - cv::Mat getMask() - { - return mMask; - } - void setMask(cv::Mat &mask); + ColorMarkerItem(QWidget *wParent, QGraphicsItem *parent = nullptr); + QRectF boundingRect() const; + void setRect(Vec2F &v); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + cv::Mat getMask() { return mMask; } + void setMask(cv::Mat &mask); cv::Mat createMask(int w, int h); }; diff --git a/include/colorMarkerWidget.h b/include/colorMarkerWidget.h index a5c67e6957292fed5c9a7c7a73fd096387bee8d9..c7a1f25e483524197d7f27dbfbfca840c6740ec0 100644 --- a/include/colorMarkerWidget.h +++ b/include/colorMarkerWidget.h @@ -21,13 +21,13 @@ #ifndef COLORMARKERWIDGET_H #define COLORMARKERWIDGET_H -#include <QtWidgets> +#include "colorMarkerItem.h" +#include "petrack.h" #include "ui_colorMarker.h" -#include "petrack.h" -#include "colorMarkerItem.h" +#include <QtWidgets> -class ColorMarkerWidget: public QWidget, public Ui::ColorMarker +class ColorMarkerWidget : public QWidget, public Ui::ColorMarker { Q_OBJECT @@ -55,63 +55,64 @@ private slots: mMainWindow->getColorMarkerItem()->setVisible(i); mMainWindow->getScene()->update(); } - void on_maskMask_stateChanged(int /*i*/) - { - mMainWindow->getScene()->update(); - } - void on_opacity_valueChanged(int /*i*/) - { - mMainWindow->getScene()->update(); - } + + void on_maskMask_stateChanged(int /*i*/) { mMainWindow->getScene()->update(); } + void on_opacity_valueChanged(int /*i*/) { mMainWindow->getScene()->update(); } // functions which force a new recognition void on_inversHue_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void on_useOpen_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void on_useClose_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void on_closeRadius_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void on_openRadius_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void on_minArea_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void on_maxArea_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void on_maxRatio_valueChanged(double /*d*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } diff --git a/include/colorPlot.h b/include/colorPlot.h index b5825203d48c6e6ab6319b86d7a536f70eb4b12f..8bddf6cbddd0b6e7e04a73e00043d547c719a09b 100644 --- a/include/colorPlot.h +++ b/include/colorPlot.h @@ -21,12 +21,11 @@ #ifndef COLORPLOT_H #define COLORPLOT_H -#include <QPen> +#include "helper.h" +#include <QPen> #include <qwt_plot.h> -#include "helper.h" - inline constexpr double DEFAULT_HEIGHT = 180.0; class ImagePlotItem; @@ -37,148 +36,115 @@ class Zoomer; class RectPlotItem; class ViewColorPlotItem; -//----------------------------------------------------------------- -class TrackerPlotItem: public QwtPlotItem +class TrackerPlotItem : public QwtPlotItem { public: TrackerPlotItem(); - void draw(QPainter* p, const QwtScaleMap& mapX, const QwtScaleMap& mapY, const QRectF& re) const; + void draw(QPainter *p, const QwtScaleMap &mapX, const QwtScaleMap &mapY, const QRectF &re) const; void setPen(const QPen &pen); void setModel(int model, int x, int y); - void setTracker(Tracker *tracker); - Tracker * getTracker(); + void setTracker(Tracker *tracker); + Tracker *getTracker(); private: Tracker *mTracker; - QPen mPen; + QPen mPen; }; -//----------------------------------------------------------------- -class RectMap: public QRectF +class RectMap : public QRectF { public: - RectMap() - : mColored(true), mMapHeight(DEFAULT_HEIGHT), mInversHue(false) + RectMap() : mColored(true), mMapHeight(DEFAULT_HEIGHT), mInversHue(false) { setRect(0., 0., 0., 0.); - mFromCol = QColor::fromHsv(0,0,0); - mToCol = QColor::fromHsv(359,255,255); + mFromCol = QColor::fromHsv(0, 0, 0); + mToCol = QColor::fromHsv(359, 255, 255); } - RectMap(QRectF r) - : QRectF(r), mInversHue(false) + RectMap(QRectF r) : QRectF(r), mInversHue(false) { setRect(0., 0., 0., 0.); - mFromCol = QColor::fromHsv(0,0,0); - mToCol = QColor::fromHsv(359,255,255); - } - RectMap(double x, double y, double w, double h, bool colored, double mapHeight) - : QRectF(x, y, w, h), mColored(colored), mMapHeight(mapHeight), mInversHue(false) - { - mFromCol = QColor::fromHsv(0,0,0); - mToCol = QColor::fromHsv(359,255,255); - } - RectMap(QRectF r, bool colored, double mapHeight) - : QRectF(r), mColored(colored), mMapHeight(mapHeight), mInversHue(false) - { - mFromCol = QColor::fromHsv(0,0,0); - mToCol = QColor::fromHsv(359,255,255); - } - inline bool colored() const - { - return mColored; - } - inline void setColored(bool b) - { - mColored = b; - } - inline double mapHeight() const - { - return mMapHeight; - } - inline void setMapHeight(double height) - { - mMapHeight = height; - } - inline void setInvHue(bool b) - { - mInversHue = b; - } - inline void setFromColor(const QColor &fromCol) - { - mFromCol = fromCol; - } - inline void setToColor(const QColor &toCol) - { - mToCol = toCol; + mFromCol = QColor::fromHsv(0, 0, 0); + mToCol = QColor::fromHsv(359, 255, 255); } - inline bool invHue() const + RectMap(double x, double y, double w, double h, bool colored, double mapHeight) : + QRectF(x, y, w, h), mColored(colored), mMapHeight(mapHeight), mInversHue(false) { - return mInversHue; + mFromCol = QColor::fromHsv(0, 0, 0); + mToCol = QColor::fromHsv(359, 255, 255); } - inline QColor & toColor() + RectMap(QRectF r, bool colored, double mapHeight) : + QRectF(r), mColored(colored), mMapHeight(mapHeight), mInversHue(false) { - return mToCol; - } - inline QColor & fromColor() - { - return mFromCol; + mFromCol = QColor::fromHsv(0, 0, 0); + mToCol = QColor::fromHsv(359, 255, 255); } + inline bool colored() const { return mColored; } + inline void setColored(bool b) { mColored = b; } + inline double mapHeight() const { return mMapHeight; } + inline void setMapHeight(double height) { mMapHeight = height; } + inline void setInvHue(bool b) { mInversHue = b; } + inline void setFromColor(const QColor &fromCol) { mFromCol = fromCol; } + inline void setToColor(const QColor &toCol) { mToCol = toCol; } + inline bool invHue() const { return mInversHue; } + inline QColor &toColor() { return mToCol; } + inline QColor &fromColor() { return mFromCol; } - bool mColored; + bool mColored; double mMapHeight; QColor mFromCol; QColor mToCol; - bool mInversHue; + bool mInversHue; }; -//----------------------------------------------------------------------------------------- -class RectPlotItem: public QwtPlotItem +class RectPlotItem : public QwtPlotItem { public: RectPlotItem(); - double map(const QColor &col) const; //TrackPerson &tp RectMap ... double x, double y - - int addMap(double x, double y, double w, double h, bool colored, double height, QColor &fromCol, QColor &toCol, bool invHue); - int addMap(); - void changeMap(int index, double x, double y, double w, double h, bool colored, double mapHeight); - void changeActMapInvHue(bool b); - void changeActMapFromColor(const QColor &fromCol); - void changeActMapToColor(const QColor &toCol); - bool getActMapInvHue(); - QColor getActMapToColor(); - QColor getActMapFromColor(); - RectMap getMap(int index) const; - void delMap(int index); - inline void delMaps() - { - mMaps.clear(); - } - inline int mapNum() const - { - return mMaps.size(); - } - - void draw(QPainter* p, const QwtScaleMap& mapX, const QwtScaleMap& mapY, const QRectF& re) const; + double map(const QColor &col) const; // TrackPerson &tp RectMap ... double x, double y + + int addMap( + double x, + double y, + double w, + double h, + bool colored, + double height, + QColor &fromCol, + QColor &toCol, + bool invHue); + int addMap(); + void changeMap(int index, double x, double y, double w, double h, bool colored, double mapHeight); + void changeActMapInvHue(bool b); + void changeActMapFromColor(const QColor &fromCol); + void changeActMapToColor(const QColor &toCol); + bool getActMapInvHue(); + QColor getActMapToColor(); + QColor getActMapFromColor(); + RectMap getMap(int index) const; + void delMap(int index); + inline void delMaps() { mMaps.clear(); } + inline int mapNum() const { return mMaps.size(); } + + void draw(QPainter *p, const QwtScaleMap &mapX, const QwtScaleMap &mapY, const QRectF &re) const; void setPen(const QPen &pen); private: QList<RectMap> mMaps; - QPen mPen; - int mActIndex; + QPen mPen; + int mActIndex; }; -//----------------------------------------------------------------- -class ColorPlot: public QwtPlot +class ColorPlot : public QwtPlot { Q_OBJECT @@ -189,65 +155,41 @@ public: void setCursor(const QColor &col); - QPoint getPos(const QColor &col, int *z=nullptr) const; + QPoint getPos(const QColor &col, int *z = nullptr) const; bool isGrey(const QColor &col) const; double map(const QColor &col) const; - bool printDistribution() const; + bool printDistribution() const; void setControlWidget(Control *control); void setTracker(Tracker *tracker); void setScale(); void generateImage(); - inline double symbolSize() const - { - return mSymbolSize; - } - inline void setSymbolSize(double s) - { - mSymbolSize = s; - } + inline double symbolSize() const { return mSymbolSize; } + inline void setSymbolSize(double s) { mSymbolSize = s; } - inline int greyDiff() const - { - return mGreyDiff; - } - inline void setGreyDiff(int s) - { - mGreyDiff = s; - } - inline double xMax() const - { - return mXMax; - } - inline double yMax() const - { - return mYMax; - } - int zValue() const; + inline int greyDiff() const { return mGreyDiff; } + inline void setGreyDiff(int s) { mGreyDiff = s; } + inline double xMax() const { return mXMax; } + inline double yMax() const { return mYMax; } + int zValue() const; - inline TrackerPlotItem *getTrackerItem() const - { - return mTrackerItem; - } - inline RectPlotItem *getMapItem() const - { - return mRectItem; - } + inline TrackerPlotItem *getTrackerItem() const { return mTrackerItem; } + inline RectPlotItem * getMapItem() const { return mRectItem; } private: - double mSymbolSize; - double mXMax; - double mYMax; - Control *mControlWidget; - ImagePlotItem *mImageItem; - TrackerPlotItem *mTrackerItem; - RectPlotItem *mRectItem; + double mSymbolSize; + double mXMax; + double mYMax; + Control * mControlWidget; + ImagePlotItem * mImageItem; + TrackerPlotItem * mTrackerItem; + RectPlotItem * mRectItem; ViewColorPlotItem *mViewColorItem; - Zoomer *mZoomer; - int mGreyDiff; + Zoomer * mZoomer; + int mGreyDiff; }; #endif diff --git a/include/colorRangeWidget.h b/include/colorRangeWidget.h index 260a8d72930539ca4cc278bb92677a0b5b9dfa23..7d2262f8ca86ecdec40e60b11d2afa37a81a1d2a 100644 --- a/include/colorRangeWidget.h +++ b/include/colorRangeWidget.h @@ -21,13 +21,13 @@ #ifndef COLORRANGEWIDGET_H #define COLORRANGEWIDGET_H -#include <QtWidgets> +#include "colorPlot.h" +#include "petrack.h" #include "ui_colorRange.h" -#include "petrack.h" -#include "colorPlot.h" +#include <QtWidgets> -class ColorRangeWidget: public QWidget, public Ui::ColorRange +class ColorRangeWidget : public QWidget, public Ui::ColorRange { Q_OBJECT @@ -57,7 +57,7 @@ private slots: void on_toColor_clicked(); private: - Petrack *mMainWindow; + Petrack * mMainWindow; ColorPlot *mColorPlot; }; diff --git a/include/compilerInformation.h b/include/compilerInformation.h index d332c5113ecec53a2b6598a5ee1069d182ae336d..57a575cbb119a1757a8689ecf912b4c4e707b927 100644 --- a/include/compilerInformation.h +++ b/include/compilerInformation.h @@ -32,7 +32,8 @@ std::string versionString(int major, int minor, int patch) // Taken from: // https://sourceforge.net/p/predef/wiki/Compilers/ -constexpr const char * COMPILER_ID{ +constexpr const char *COMPILER_ID +{ #ifdef __clang__ "clang++" #elif defined(__GNUC__) @@ -53,8 +54,8 @@ const std::string COMPILER_VERSION = versionString(__clang_major__, __clang_minor__, __clang_patchlevel__); #elif defined(__GNUC__) #if defined(__MINGW32__) - versionString(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) - + "(" +versionString(__MINGW32__, __MINGW32_MAJOR_VERSION, __MINGW32_MINOR_VERSION) + ")"; + versionString(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) + "(" + + versionString(__MINGW32__, __MINGW32_MAJOR_VERSION, __MINGW32_MINOR_VERSION) + ")"; #else versionString(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); #endif @@ -66,4 +67,4 @@ const std::string COMPILER_VERSION = const std::string COMPILE_TIMESTAMP = __TIMESTAMP__; -#endif //COMPILERINFORMATION_H +#endif // COMPILERINFORMATION_H diff --git a/include/control.h b/include/control.h index 7073b5045dcbd9c26e26b0b84a36d60a1cb25428..06dd5a6aab644558c4d3213d2d89a3837310a933 100644 --- a/include/control.h +++ b/include/control.h @@ -21,32 +21,33 @@ #ifndef CONTROL_H #define CONTROL_H -#include <QtWidgets> -#include <Qt> -#include "ui_control.h" #include "recognition.h" +#include "ui_control.h" + +#include <Qt> +#include <QtWidgets> class Petrack; class QGraphicsScene; class QDomElement; -class Control: public QWidget, public Ui::Control +class Control : public QWidget, public Ui::Control { Q_OBJECT public: - Control(QWidget& parent, QGraphicsScene &scene, reco::Recognizer& recognizer); + Control(QWidget &parent, QGraphicsScene &scene, reco::Recognizer &recognizer); void setScene(QGraphicsScene *sc); - bool getTrackShow(); - void setTrackShow(bool b); - bool getTrackFix(); - void setTrackFix(bool b); + bool getTrackShow(); + void setTrackShow(bool b); + bool getTrackFix(); + void setTrackFix(bool b); QColor getTrackPathColor(); - void setTrackPathColor(QColor col); + void setTrackPathColor(QColor col); QColor getTrackGroundPathColor(); - void setTrackGroundPathColor(QColor col); + void setTrackGroundPathColor(QColor col); QColor getMoCapColor(); bool getRecoRoiShow(); @@ -64,103 +65,103 @@ public: int getFilterBorderSize(); double getCalibFxValue(); - void setCalibFxValue(double d); - void setCalibFxMin(double d); - void setCalibFxMax(double d); + void setCalibFxValue(double d); + void setCalibFxMin(double d); + void setCalibFxMax(double d); double getCalibFyValue(); - void setCalibFyValue(double d); - void setCalibFyMin(double d); - void setCalibFyMax(double d); + void setCalibFyValue(double d); + void setCalibFyMin(double d); + void setCalibFyMax(double d); double getCalibCxValue(); - void setCalibCxValue(double d); - void setCalibCxMin(double d); - void setCalibCxMax(double d); + void setCalibCxValue(double d); + void setCalibCxMin(double d); + void setCalibCxMax(double d); double getCalibCyValue(); - void setCalibCyValue(double d); - void setCalibCyMin(double d); - void setCalibCyMax(double d); + void setCalibCyValue(double d); + void setCalibCyMin(double d); + void setCalibCyMax(double d); double getCalibR2Value(); - void setCalibR2Value(double d); - void setCalibR2Min(double d); - void setCalibR2Max(double d); + void setCalibR2Value(double d); + void setCalibR2Min(double d); + void setCalibR2Max(double d); double getCalibR4Value(); - void setCalibR4Value(double d); - void setCalibR4Min(double d); - void setCalibR4Max(double d); + void setCalibR4Value(double d); + void setCalibR4Min(double d); + void setCalibR4Max(double d); double getCalibTxValue(); - void setCalibTxValue(double d); - void setCalibTxMin(double d); - void setCalibTxMax(double d); + void setCalibTxValue(double d); + void setCalibTxMin(double d); + void setCalibTxMax(double d); double getCalibTyValue(); - void setCalibTyValue(double d); - void setCalibTyMin(double d); - void setCalibTyMax(double d); + void setCalibTyValue(double d); + void setCalibTyMin(double d); + void setCalibTyMax(double d); double getCalibR6Value(); - void setCalibR6Value(double d); - void setCalibR6Min(double d); - void setCalibR6Max(double d); + void setCalibR6Value(double d); + void setCalibR6Min(double d); + void setCalibR6Max(double d); double getCalibK4Value(); - void setCalibK4Value(double d); - void setCalibK4Min(double d); - void setCalibK4Max(double d); + void setCalibK4Value(double d); + void setCalibK4Min(double d); + void setCalibK4Max(double d); double getCalibK5Value(); - void setCalibK5Value(double d); - void setCalibK5Min(double d); - void setCalibK5Max(double d); + void setCalibK5Value(double d); + void setCalibK5Min(double d); + void setCalibK5Max(double d); double getCalibK6Value(); - void setCalibK6Value(double d); - void setCalibK6Min(double d); - void setCalibK6Max(double d); + void setCalibK6Value(double d); + void setCalibK6Min(double d); + void setCalibK6Max(double d); double getCalibExtrRot1(); - void setCalibExtrRot1(double d); + void setCalibExtrRot1(double d); double getCalibExtrRot2(); - void setCalibExtrRot2(double d); + void setCalibExtrRot2(double d); double getCalibExtrRot3(); - void setCalibExtrRot3(double d); + void setCalibExtrRot3(double d); double getCalibExtrTrans1(); - void setCalibExtrTrans1(double d); + void setCalibExtrTrans1(double d); double getCalibExtrTrans2(); - void setCalibExtrTrans2(double d); + void setCalibExtrTrans2(double d); double getCalibExtrTrans3(); - void setCalibExtrTrans3(double d); - void setEnabledExtrParams(bool enable); - - int /*Petrack::Dimension*/ getCalibCoordDimension(); - bool getCalibExtrCalibPointsShow(); - bool getCalibExtrVanishPointsShow(); - bool getCalibCoordShow(); - void setCalibCoordShow(bool b); - bool getCalibCoordFix(); - void setCalibCoordFix(bool b); - bool getIs3DView(); - void setIs3DView(bool b); - int getCalibCoordRotate(); - void setCalibCoordRotate(int i); - int getCalibCoordTransX(); - void setCalibCoordTransX(int i); - int getCalibCoordTransXMax(); - void setCalibCoordTransXMax(int i); - int getCalibCoordTransXMin(); - void setCalibCoordTransXMin(int i); - int getCalibCoordTransY(); - void setCalibCoordTransY(int i); - int getCalibCoordTransYMax(); - void setCalibCoordTransYMax(int i); - int getCalibCoordTransYMin(); - void setCalibCoordTransYMin(int i); - int getCalibCoordScale(); - void setCalibCoordScale(int i); + void setCalibExtrTrans3(double d); + void setEnabledExtrParams(bool enable); + + int getCalibCoordDimension(); + bool getCalibExtrCalibPointsShow(); + bool getCalibExtrVanishPointsShow(); + bool getCalibCoordShow(); + void setCalibCoordShow(bool b); + bool getCalibCoordFix(); + void setCalibCoordFix(bool b); + bool getIs3DView(); + void setIs3DView(bool b); + int getCalibCoordRotate(); + void setCalibCoordRotate(int i); + int getCalibCoordTransX(); + void setCalibCoordTransX(int i); + int getCalibCoordTransXMax(); + void setCalibCoordTransXMax(int i); + int getCalibCoordTransXMin(); + void setCalibCoordTransXMin(int i); + int getCalibCoordTransY(); + void setCalibCoordTransY(int i); + int getCalibCoordTransYMax(); + void setCalibCoordTransYMax(int i); + int getCalibCoordTransYMin(); + void setCalibCoordTransYMin(int i); + int getCalibCoordScale(); + void setCalibCoordScale(int i); double getCalibCoordUnit(); - void setCalibCoordUnit(double d); + void setCalibCoordUnit(double d); - int getCalibCoord3DTransX(); + int getCalibCoord3DTransX(); void setCalibCoord3DTransX(int i); - int getCalibCoord3DTransY(); + int getCalibCoord3DTransY(); void setCalibCoord3DTransY(int i); - int getCalibCoord3DTransZ(); + int getCalibCoord3DTransZ(); void setCalibCoord3DTransZ(int i); - int getCalibCoord3DAxeLen(); + int getCalibCoord3DAxeLen(); void setCalibCoord3DAxeLen(int i); bool getCalibCoord3DSwapX(); void setCalibCoord3DSwapX(bool b); @@ -169,56 +170,44 @@ public: bool getCalibCoord3DSwapZ(); void setCalibCoord3DSwapZ(bool b); - int /*Petrack::Dimension*/ getCalibGridDimension(); + int getCalibGridDimension(); bool getCalibGridShow(); void setCalibGridShow(bool b); bool getCalibGridFix(); void setCalibGridFix(bool b); - int getCalibGridRotate(); + int getCalibGridRotate(); void setCalibGridRotate(int i); - int getCalibGridTransX(); + int getCalibGridTransX(); void setCalibGridTransX(int i); - int getCalibGridTransY(); + int getCalibGridTransY(); void setCalibGridTransY(int i); - int getCalibGridScale(); + int getCalibGridScale(); void setCalibGridScale(int i); - int getCalibGrid3DTransX(); + int getCalibGrid3DTransX(); void setCalibGrid3DTransX(int i); - int getCalibGrid3DTransY(); + int getCalibGrid3DTransY(); void setCalibGrid3DTransY(int i); - int getCalibGrid3DTransZ(); + int getCalibGrid3DTransZ(); void setCalibGrid3DTransZ(int i); void setGridMinMaxTranslation(int minx, int maxx, int miny, int maxy); - int getCalibGrid3DResolution(); + int getCalibGrid3DResolution(); void setCalibGrid3DResolution(int i); - void expandRange(QColor& fromColor, QColor& toColor, const QColor& clickedColor) const; - void saveChange(const QColor& fromColor, const QColor& toColor, RectPlotItem* map); - bool getColors(QColor& clickedColor, QColor& toColor, QColor& fromColor, RectPlotItem*& map); + void expandRange(QColor &fromColor, QColor &toColor, const QColor &clickedColor) const; + void saveChange(const QColor &fromColor, const QColor &toColor, RectPlotItem *map); + bool getColors(QColor &clickedColor, QColor &toColor, QColor &fromColor, RectPlotItem *&map); - void setXml(QDomElement &elem); - void getXml(QDomElement &elem); - bool isLoading() - { - return mMainWindow->isLoading(); - } - inline ColorPlot *getColorPlot() const - { - return colorPlot; - } + void setXml(QDomElement &elem); + void getXml(QDomElement &elem); + bool isLoading() { return mMainWindow->isLoading(); } + inline ColorPlot *getColorPlot() const { return colorPlot; } #ifdef QWT - inline AnalysePlot *getAnalysePlot() const - { - return analysePlot; - } + inline AnalysePlot *getAnalysePlot() const { return analysePlot; } #endif - inline Petrack *getMainWindow() const - { - return mMainWindow; - } + inline Petrack *getMainWindow() const { return mMainWindow; } private: reco::RecognitionMethod getRecoMethod() const; @@ -278,36 +267,120 @@ private slots: void on_trackRegionLevels_valueChanged(int i); void on_trackShowSearchSize_stateChanged(int i); - void on_trackShowOnlyVisible_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowCurrentPoint_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } + void on_trackShowOnlyVisible_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowCurrentPoint_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } void on_trackGotoNr_clicked(); void on_trackGotoStartNr_clicked(); void on_trackGotoEndNr_clicked(); void on_trackHeadSized_stateChanged(int i); - void on_trackShowPoints_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowPointsColored_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowPath_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowColColor_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowColorMarker_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowNumber_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowGroundPosition_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowGroundPath_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowHeightIndividual_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackNumberBold_stateChanged(int /*i*/) { if (!isLoading()) mScene->update(); } + void on_trackShowPoints_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowPointsColored_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowPath_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowColColor_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowColorMarker_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowNumber_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowGroundPosition_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowGroundPath_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowHeightIndividual_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackNumberBold_stateChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } void on_showMoCap_stateChanged(int i); - void on_trackCurrentPointSize_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackPointSize_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackPathWidth_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackColColorSize_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } + void on_trackCurrentPointSize_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackPointSize_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackPathWidth_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackColColorSize_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } void on_trackColorMarkerSize_valueChanged(int /*i*/) { mScene->update(); } - void on_trackNumberSize_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackGroundPositionSize_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackGroundPathSize_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowBefore_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } - void on_trackShowAfter_valueChanged(int /*i*/) { if (!isLoading()) mScene->update(); } + void on_trackNumberSize_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackGroundPositionSize_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackGroundPathSize_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowBefore_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } + void on_trackShowAfter_valueChanged(int /*i*/) + { + if(!isLoading()) + mScene->update(); + } void on_moCapSize_valueChanged(int i); void on_recoMethod_currentIndexChanged(int index); @@ -426,12 +499,13 @@ signals: void userChangedRecoMethod(reco::RecognitionMethod method); private: - Petrack *mMainWindow; + Petrack * mMainWindow; QGraphicsScene *mScene; - bool mColorChanging; - bool mIndexChanging; // shows, if the index of the color model is really changing; nor while constructor (initialer durchlauf) and may be while loading xml file - bool mLoading; // shows, if new project is just loading - QDoubleSpinBox *k4,*k5,*k6; // Muss noch in die Oberflaeche eingebaut werden - }; + bool mColorChanging; + bool mIndexChanging; // shows, if the index of the color model is really changing; nor while constructor (initialer + // durchlauf) and may be while loading xml file + bool mLoading; // shows, if new project is just loading + QDoubleSpinBox *k4, *k5, *k6; // Muss noch in die Oberflaeche eingebaut werden +}; #endif diff --git a/include/coordItem.h b/include/coordItem.h index b3ac2cacef34e613a0202b32edef7c070c6b334a..623ecb641fa1caecd17196ae66da2c5f29709f43 100644 --- a/include/coordItem.h +++ b/include/coordItem.h @@ -23,7 +23,7 @@ #include <QGraphicsItem> #include <QtWidgets> -#include <petrack.h> +#include <opencv2/core/types.hpp> class Petrack; class Control; @@ -32,28 +32,22 @@ class ExtrCalibration; class CoordItem : public QGraphicsItem { private: - Petrack *mMainWindow; + Petrack * mMainWindow; ExtrCalibration *extCalib; - Control *mControlWidget; - cv::Point2f ursprung, x, y, z; - cv::Point2f calibPointsMin, calibPointsMax; - cv::Point3f x3D, y3D, z3D; - float mouse_x,mouse_y; - int coordTrans_x,coordTrans_y; - int coordDimension; + Control * mControlWidget; + cv::Point2f ursprung, x, y, z; + cv::Point2f calibPointsMin, calibPointsMax; + cv::Point3f x3D, y3D, z3D; + float mouse_x, mouse_y; + int coordTrans_x, coordTrans_y; + int coordDimension; public: - inline void setCoordDimension(int dim) - { - this->coordDimension = dim; - } - inline int getCoordDimension() const - { - return this->coordDimension; - } + inline void setCoordDimension(int dim) { this->coordDimension = dim; } + inline int getCoordDimension() const { return this->coordDimension; } + + CoordItem(QWidget *wParent, QGraphicsItem *parent = nullptr); - // Constructor - CoordItem(QWidget *wParent, QGraphicsItem * parent = nullptr); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/include/ellipse.h b/include/ellipse.h index b471bb2fe211922829b88fdb8807112ce2672452..ffe77f4e91be804ae951ab2e4862f318315f6f8b 100644 --- a/include/ellipse.h +++ b/include/ellipse.h @@ -21,21 +21,22 @@ #ifndef ELLIPSE_H #define ELLIPSE_H -#include <opencv2/opencv.hpp> - #include "vector.h" +#include <opencv2/opencv.hpp> + class QPointF; class QSizeF; -class MyEllipse { +class MyEllipse +{ private: - Vec2F mC; // center - double mR1; // radii - double mR2; // guarantees that mR1 >= mR2 + Vec2F mC; // center + double mR1; // radii + double mR2; // guarantees that mR1 >= mR2 double mAngle; // 0..PI arc between pos x axis and ellipse axis with size mR1 (>mR2) - Vec2F mF1; // focal points - Vec2F mF2; + Vec2F mF1; // focal points + Vec2F mF2; public: MyEllipse(); @@ -43,40 +44,24 @@ public: MyEllipse(QPointF center, QSizeF size, double angle); MyEllipse(const MyEllipse &ellipse) = default; - Vec2F center() const; + Vec2F center() const; QSizeF size() const; - // inline fkt muessen im header definiert werden!!! - inline double x() const - { - return mC.x(); - } - inline double y() const - { - return mC.y(); - } - inline double r1() const - { - return mR1; - } - inline double r2() const - { - return mR2; - } - inline double angle() const - { - return mAngle; - } + inline double x() const { return mC.x(); } + inline double y() const { return mC.y(); } + inline double r1() const { return mR1; } + inline double r2() const { return mR2; } + inline double angle() const { return mAngle; } inline double ratio() const // >=1 { - return mR1/mR2; + return mR1 / mR2; } double area() const; // only estimation, because of complex elliptical integral double outline() const; // is point p inside or on the ellipse - bool isInside(const Vec2F& p) const; + bool isInside(const Vec2F &p) const; bool isInside(double x, double y) const; bool isNearlyCircle() const; diff --git a/include/extrCalibration.h b/include/extrCalibration.h index 4007b6fd7a66d9cae5f333e8508dc56f7c783446..a2aa96d348ef2bcf5b5a52855b9377b0519b83bc 100644 --- a/include/extrCalibration.h +++ b/include/extrCalibration.h @@ -21,22 +21,21 @@ #ifndef EXTRCALIBRATION_H #define EXTRCALIBRATION_H -#include <iostream> -#include <vector> -#include <array> - -#include <QString> #include <QDomElement> - +#include <QString> +#include <array> +#include <iostream> #include <opencv2/opencv.hpp> +#include <vector> class Petrack; class Control; -class ReprojectionError{ +class ReprojectionError +{ private: - bool mValid = false; + bool mValid = false; double mPointHeightAvg; double mPointHeightStdDev; double mPointHeightVariance; @@ -53,30 +52,44 @@ private: double mPixelMax; double mUsedDefaultHeight; + public: ReprojectionError() = default; - ReprojectionError(double pointHeightAvg, double pointHeightStdDev, - double pointHeightVariance, double pointHeightMax, - double defaultHeightAvg, double defaultHeightStdDev, - double defaultHeightVariance, double defaultHeightMax, - double pixelAvg, double pixelStdDev, - double pixelVariance, double pixelMax, - double defaultHeight): - mPointHeightAvg(pointHeightAvg), mPointHeightStdDev(pointHeightStdDev), - mPointHeightVariance(pointHeightVariance), mPointHeightMax(pointHeightMax), - mDefaultHeightAvg(defaultHeightAvg), mDefaultHeightStdDev(defaultHeightStdDev), - mDefaultHeightVariance(defaultHeightVariance), mDefaultHeightMax(defaultHeightMax), - mPixelAvg(pixelAvg), mPixelStdDev(pixelStdDev), - mPixelVariance(pixelVariance), mPixelMax(pixelMax), + ReprojectionError( + double pointHeightAvg, + double pointHeightStdDev, + double pointHeightVariance, + double pointHeightMax, + double defaultHeightAvg, + double defaultHeightStdDev, + double defaultHeightVariance, + double defaultHeightMax, + double pixelAvg, + double pixelStdDev, + double pixelVariance, + double pixelMax, + double defaultHeight) : + mPointHeightAvg(pointHeightAvg), + mPointHeightStdDev(pointHeightStdDev), + mPointHeightVariance(pointHeightVariance), + mPointHeightMax(pointHeightMax), + mDefaultHeightAvg(defaultHeightAvg), + mDefaultHeightStdDev(defaultHeightStdDev), + mDefaultHeightVariance(defaultHeightVariance), + mDefaultHeightMax(defaultHeightMax), + mPixelAvg(pixelAvg), + mPixelStdDev(pixelStdDev), + mPixelVariance(pixelVariance), + mPixelMax(pixelMax), mUsedDefaultHeight(defaultHeight) { auto data = getData(); - mValid = !std::any_of(data.begin(), data.end(), [](double a){return !std::isfinite(a) || a < 0;}); + mValid = !std::any_of(data.begin(), data.end(), [](double a) { return !std::isfinite(a) || a < 0; }); } - void getXml(QDomElement& elem); - void setXml(QDomElement& elem) const; + void getXml(QDomElement &elem); + void setXml(QDomElement &elem) const; double pointHeightAvg() const; double pointHeightStdDev() const; @@ -95,16 +108,25 @@ public: double usedDefaultHeight() const; - std::array<double, 13> getData() const { - return {mPointHeightAvg, mPointHeightStdDev, mPointHeightVariance, mPointHeightMax, - mDefaultHeightAvg, mDefaultHeightStdDev, mDefaultHeightVariance, mDefaultHeightMax, - mPixelAvg, mPixelStdDev, mPixelVariance, mPixelMax, - mUsedDefaultHeight}; + std::array<double, 13> getData() const + { + return { + mPointHeightAvg, + mPointHeightStdDev, + mPointHeightVariance, + mPointHeightMax, + mDefaultHeightAvg, + mDefaultHeightStdDev, + mDefaultHeightVariance, + mDefaultHeightMax, + mPixelAvg, + mPixelStdDev, + mPixelVariance, + mPixelMax, + mUsedDefaultHeight}; } - bool isValid() const{ - return mValid; - } + bool isValid() const { return mValid; } }; @@ -121,7 +143,6 @@ public: */ class ExtrCalibration { - private: Petrack *mMainWindow; Control *mControlWidget; @@ -135,61 +156,39 @@ private: double *camValues; double *distValues; - bool isExtCalib; - float camHeight; + bool isExtCalib; + float camHeight; ReprojectionError reprojectionError; - QString mExtrCalibFile; - void init(); + QString mExtrCalibFile; + void init(); public: - ExtrCalibration(); ~ExtrCalibration(); - void setMainWindow(Petrack *mw); - bool isEmptyExtrCalibFile(); - bool isSetExtrCalib(); - void setExtrCalibFile(const QString &f); - QString getExtrCalibFile(); - bool openExtrCalibFile(); - bool loadExtrCalibFile(); - bool saveExtrCalibPoints(); - bool fetch2DPoints(); - void calibExtrParams(); - bool calcReprojectionError(); - virtual cv::Point2f getImagePoint(cv::Point3f p3d); - cv::Point3f get3DPoint(cv::Point2f p2d, double h); - cv::Point3f transformRT(cv::Point3f p); - bool isOutsideImage(cv::Point2f p2d); - inline bool isOutsideImage(cv::Point3f p3d) - { - return isOutsideImage(getImagePoint(p3d)); - } - inline std::vector<cv::Point3f> get3DList() - { - return points3D; - } - inline void set3DList(std::vector<cv::Point3f> list3D) - { - this->points3D = list3D; - } - inline std::vector<cv::Point2f> get2DList() - { - return points2D; - } - inline void set2DList(std::vector<cv::Point2f> list2D) - { - this->points2D = list2D; - } - inline float getCamHeight() const - { - return camHeight; - } - inline void setCamHeight(float cHeight) - { - this->camHeight = cHeight; - } - inline ReprojectionError getReprojectionError() + void setMainWindow(Petrack *mw); + bool isEmptyExtrCalibFile(); + bool isSetExtrCalib(); + void setExtrCalibFile(const QString &f); + QString getExtrCalibFile(); + bool openExtrCalibFile(); + bool loadExtrCalibFile(); + bool saveExtrCalibPoints(); + bool fetch2DPoints(); + void calibExtrParams(); + bool calcReprojectionError(); + virtual cv::Point2f getImagePoint(cv::Point3f p3d); + cv::Point3f get3DPoint(cv::Point2f p2d, double h); + cv::Point3f transformRT(cv::Point3f p); + bool isOutsideImage(cv::Point2f p2d); + inline bool isOutsideImage(cv::Point3f p3d) { return isOutsideImage(getImagePoint(p3d)); } + inline std::vector<cv::Point3f> get3DList() { return points3D; } + inline void set3DList(std::vector<cv::Point3f> list3D) { this->points3D = list3D; } + inline std::vector<cv::Point2f> get2DList() { return points2D; } + inline void set2DList(std::vector<cv::Point2f> list2D) { this->points2D = list2D; } + inline float getCamHeight() const { return camHeight; } + inline void setCamHeight(float cHeight) { this->camHeight = cHeight; } + inline ReprojectionError getReprojectionError() { if(!reprojectionError.isValid()) calcReprojectionError(); diff --git a/include/filter.h b/include/filter.h index 19c155f9bc663669790794eb2141f86d770652b7..dc12935852c18a9c251675ff973490cae09cf126 100644 --- a/include/filter.h +++ b/include/filter.h @@ -37,26 +37,26 @@ class Filter; class Parameter { private: - double mValue; - double mMinimum; - double mMaximum; - bool mChg; + double mValue; + double mMinimum; + double mMaximum; + bool mChg; Filter *mFilter; // Filter where parameter is for public: Parameter(); - void setFilter(Filter *filter); - Filter * getFilter(); + void setFilter(Filter *filter); + Filter *getFilter(); double value() const; double getValue() const; - void setValue(double d); + void setValue(double d); double getMinimum() const; - void setMinimum(double d); + void setMinimum(double d); double getMaximum() const; - void setMaximum(double d); + void setMaximum(double d); bool changed() const; bool getChanged() const; @@ -75,20 +75,21 @@ public: * activation/deactivation as well as automated detection * of changed parameters. */ -class Filter { +class Filter +{ private: - bool mChg; // if filter paramater were changed - bool mEnable; // if filter is actice - bool mOnCopy; // if filter works on a copy + bool mChg; // if filter paramater were changed + bool mEnable; // if filter is actice + bool mOnCopy; // if filter works on a copy cv::Mat mRes; - + // pure virtual function, where to implement the filter conversion // returns the result over pointer res and as result - virtual cv::Mat act(cv::Mat &img, cv::Mat &res)=0; + virtual cv::Mat act(cv::Mat &img, cv::Mat &res) = 0; public: Filter(); - virtual ~Filter() {}; + virtual ~Filter(){}; bool changed() const; bool getChanged(); @@ -99,7 +100,7 @@ public: cv::Mat apply(cv::Mat &img); cv::Mat getLastResult(); - void freeLastResult(); + void freeLastResult(); void enable(); void disable(); diff --git a/include/gridItem.h b/include/gridItem.h index f1a6fce9ddc1b2939f9914060da2d1fff6cb1664..42ff6f9dc848d8d6bfcb79b0b9f202ffdf1eeedf 100644 --- a/include/gridItem.h +++ b/include/gridItem.h @@ -26,31 +26,27 @@ class Control; #include "extrCalibration.h" +#include <QGraphicsItem> + class GridItem : public QGraphicsItem { private: - Petrack *mMainWindow; + Petrack * mMainWindow; ExtrCalibration *extCalib; - Control *mControlWidget; - float mouse_x, mouse_y; - int gridTrans_x, gridTrans_y; - int gridDimension; + Control * mControlWidget; + float mouse_x, mouse_y; + int gridTrans_x, gridTrans_y; + int gridDimension; public: - inline void setGridDimension(int gDimension) - { - this->gridDimension = gDimension; - } - inline int getGridDimension() const - { - return this->gridDimension; - } - GridItem(QWidget *wParent, QGraphicsItem * parent = nullptr); + inline void setGridDimension(int gDimension) { this->gridDimension = gDimension; } + inline int getGridDimension() const { return this->gridDimension; } + GridItem(QWidget *wParent, QGraphicsItem *parent = nullptr); QRectF boundingRect() const; - void mouseMoveEvent(QGraphicsSceneMouseEvent *event); - void mousePressEvent(QGraphicsSceneMouseEvent *event); - int drawLine(QPainter *painter, cv::Point2f *p, int y_offset); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + int drawLine(QPainter *painter, cv::Point2f *p, int y_offset); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); }; #endif diff --git a/include/helper.h b/include/helper.h index b823eca2a206fbc5bc58710a5659d7d684d89c74..052fa69b29a09018974db1714d0c2c0f7f9a8eb6 100644 --- a/include/helper.h +++ b/include/helper.h @@ -21,19 +21,22 @@ #ifndef HELPER_H #define HELPER_H -#include <opencv2/opencv.hpp> #include <QFileInfo> #include <QString> +#include <opencv2/opencv.hpp> extern QString commandLineOptionsString; extern QString proFileName; ///< Path to the project (.pet) file; defined in helper.cpp -constexpr const char* file_name(const char* path) { - const char* file = path; - while (*path) { +constexpr const char *file_name(const char *path) +{ + const char *file = path; + while(*path) + { const char current = *path; ++path; - if (current == '/' || current == '\\') { + if(current == '/' || current == '\\') + { file = path; } } @@ -42,15 +45,14 @@ constexpr const char* file_name(const char* path) { // gleiche Variable wie QT benutzt, es gibt auch noch QT_NO_DEBUG and QT_NO_WARNING_OUTPUT #ifdef QT_NO_DEBUG_OUTPUT - #define debout // +#define debout // #else #define debout std::cout << __func__ << " in " << file_name(__FILE__) << " line " << __LINE__ << ": " #endif -#include <iostream> - #include <QString> -inline std::ostream& operator<<(std::ostream& s, const QString& t) +#include <iostream> +inline std::ostream &operator<<(std::ostream &s, const QString &t) { s << t.toStdString(); return s; @@ -58,10 +60,10 @@ inline std::ostream& operator<<(std::ostream& s, const QString& t) #ifndef MIN -#define MIN(a, b) ((a)<(b)?(a):(b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX -#define MAX(a, b) ((a)>(b)?(a):(b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif inline constexpr double PI = 3.141592654; @@ -89,20 +91,20 @@ cv::Mat getRoi(cv::Mat &img, const QRect &roi, cv::Rect &rect, bool evenPixelNum inline double getMedianOf3(double a, double b, double c) { - if (a<b) + if(a < b) { - if (b<c) + if(b < c) return b; // a b c - else if (c<b && c<a) + else if(c < b && c < a) return a; // c a b else return c; // a c b } else // b<=a { - if (a<c) + if(a < c) return a; // b a c - else if (c<a && c<b) + else if(c < a && c < b) return b; // c b a else return c; // b c a @@ -111,75 +113,75 @@ inline double getMedianOf3(double a, double b, double c) // d darf keine seiteneffekte haben!!! // myround genommen, da round manchmal in math.h existiert, aber nicht immer -#define myRound(d) (static_cast<int>(((d)<0 ? (d)-.5 : (d)+.5))) +#define myRound(d) (static_cast<int>(((d) < 0 ? (d) -.5 : (d) + .5))) #define myClip(d, min, max) (((d) < min) ? (min) : (((d) > max) ? (max) : (d))) // get image color from 3-channel-images with values 0..255 -#define getR(img,x,y) ((int)*(uchar*)((img)->imageData + (img)->widthStep*(y) + (img)->nChannels*(x) + 2)) -#define getG(img,x,y) ((int)*(uchar*)((img)->imageData + (img)->widthStep*(y) + (img)->nChannels*(x) + 1)) -#define getB(img,x,y) ((int)*(uchar*)((img)->imageData + (img)->widthStep*(y) + (img)->nChannels*(x))) +#define getR(img, x, y) ((int) *(uchar *) ((img)->imageData + (img)->widthStep * (y) + (img)->nChannels * (x) + 2)) +#define getG(img, x, y) ((int) *(uchar *) ((img)->imageData + (img)->widthStep * (y) + (img)->nChannels * (x) + 1)) +#define getB(img, x, y) ((int) *(uchar *) ((img)->imageData + (img)->widthStep * (y) + (img)->nChannels * (x))) // get image grey value from grey-images with values 0..255 (may be also 3 channels???) -#define getGrey(img,x,y) ((int)*(uchar*)((img)->imageData + (img)->widthStep*(y) + (x))) +#define getGrey(img, x, y) ((int) *(uchar *) ((img)->imageData + (img)->widthStep * (y) + (x))) inline cv::Scalar qcolor2scalar(QColor color) { - int r,g,b; + int r, g, b; color.getRgb(&r, &g, &b); - return cv::Scalar(b,g,r); // swap RGB-->BGR + return cv::Scalar(b, g, r); // swap RGB-->BGR } inline QColor scalar2qcolor(cv::Scalar color) { QColor ret; - ret.setHsv(0,0,color[0]); + ret.setHsv(0, 0, color[0]); return ret; // swap RGB-->BGR } -inline QColor getValue(const cv::Mat &img ,int x, int y) +inline QColor getValue(const cv::Mat &img, int x, int y) { - QColor ret; + QColor ret; cv::Scalar scalar; - cv::Vec3b val; - switch(img.channels()){ - case 1: - scalar = img.at<uchar>(cv::Point(x,y)); - ret = scalar2qcolor(scalar); - break; - case 3: - case 4: - val = img.at<cv::Vec3b>(cv::Point(x,y)); - ret.setRgb(val.val[2],val.val[1],val.val[0]); - break; - default: - ; + cv::Vec3b val; + switch(img.channels()) + { + case 1: + scalar = img.at<uchar>(cv::Point(x, y)); + ret = scalar2qcolor(scalar); + break; + case 3: + case 4: + val = img.at<cv::Vec3b>(cv::Point(x, y)); + ret.setRgb(val.val[2], val.val[1], val.val[0]); + break; + default:; } return ret; } #include <QColor> #include <QTextStream> -inline std::ostream& operator<<(std::ostream& s, const QColor& col) +inline std::ostream &operator<<(std::ostream &s, const QColor &col) { - if (col.isValid()) + if(col.isValid()) s << col.red() << " " << col.green() << " " << col.blue(); else s << -1 << " " << -1 << " " << -1; return s; } -inline QTextStream& operator<<(QTextStream& s, const QColor& col) +inline QTextStream &operator<<(QTextStream &s, const QColor &col) { - if (col.isValid()) + if(col.isValid()) s << col.red() << " " << col.green() << " " << col.blue(); else s << -1 << " " << -1 << " " << -1; return s; } -inline QTextStream& operator>>(QTextStream& s, QColor& col) +inline QTextStream &operator>>(QTextStream &s, QColor &col) { int i; // leave invalid, if one number is -1 s >> i; - if (i != -1) + if(i != -1) { col.setRed(i); s >> i; @@ -209,34 +211,34 @@ inline QString getExistingFile(const QString &fileList, const QString &relToFile { QStringList list; list = fileList.split(";", Qt::SkipEmptyParts); - for (int i = 0; i < list.size(); ++i) + for(int i = 0; i < list.size(); ++i) { - if (QFile(list.at(i)).exists()) + if(QFile(list.at(i)).exists()) return list.at(i); - if (QFile(list.at(i).trimmed()).exists()) + if(QFile(list.at(i).trimmed()).exists()) return list.at(i).trimmed(); - if (QFile(QFileInfo(relToFileName).absolutePath()+"/"+list.at(i).trimmed()).exists()) - return QFileInfo(relToFileName).absolutePath()+"/"+list.at(i).trimmed(); + if(QFile(QFileInfo(relToFileName).absolutePath() + "/" + list.at(i).trimmed()).exists()) + return QFileInfo(relToFileName).absolutePath() + "/" + list.at(i).trimmed(); } return ""; // wenn keine der Dateien existiert } -#include <QFileInfo> #include <QDir> +#include <QFileInfo> inline QString getFileList(const QString &fileName, const QString &relToFileName = proFileName) { QString seqAbs = QFileInfo(fileName).absoluteFilePath(); QString seqRelToPro = QDir(QFileInfo(relToFileName).absolutePath()).relativeFilePath(seqAbs); - if (QFileInfo(fileName).isRelative()) + if(QFileInfo(fileName).isRelative()) { - if (fileName == seqRelToPro) - return fileName+";"+seqAbs; + if(fileName == seqRelToPro) + return fileName + ";" + seqAbs; else - return fileName+";"+seqAbs+";"+seqRelToPro; + return fileName + ";" + seqAbs + ";" + seqRelToPro; } else - return fileName+";"+seqRelToPro; + return fileName + ";" + seqRelToPro; } #include <ctime> @@ -244,7 +246,7 @@ inline clock_t getElapsedTime() { static clock_t lastTime = clock(); static clock_t diffTime; // fuer performance - diffTime = clock()-lastTime; + diffTime = clock() - lastTime; lastTime = clock(); return diffTime; } diff --git a/include/imageItem.h b/include/imageItem.h index fb0890a063340aaf54e2d2bb5ed471f3cd3a187e..9e6e8bc78f95e065edb8eb27ed964fb88d6e1244 100644 --- a/include/imageItem.h +++ b/include/imageItem.h @@ -26,29 +26,30 @@ class Petrack; class Control; -class ImageItem: public QGraphicsItem +class ImageItem : public QGraphicsItem { private: - Petrack *mMainWindow; - Control *mControlWidget; - QImage *mImage; + Petrack * mMainWindow; + Control * mControlWidget; + QImage * mImage; QGraphicsItem *mCoordItem; + public: - ImageItem(QWidget *wParent, QGraphicsItem * parent = nullptr); + ImageItem(QWidget *wParent, QGraphicsItem *parent = nullptr); - QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - void setImage(QImage *img); - void setCoordItem(QGraphicsItem *ci); - double getCmPerPixel(); + void setImage(QImage *img); + void setCoordItem(QGraphicsItem *ci); + double getCmPerPixel(); QPointF getCmPerPixel(float px, float py, float h = 0.); - double getAngleToGround(float px, float py, float h = 0); + double getAngleToGround(float px, float py, float h = 0); QPointF getPosImage(QPointF pos, float height = 0.); QPointF getPosReal(QPointF pos, double height = 0.); - void mouseMoveEvent(QGraphicsSceneMouseEvent * event); - void hoverMoveEvent(QGraphicsSceneHoverEvent * event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void hoverMoveEvent(QGraphicsSceneHoverEvent *event); }; #endif diff --git a/include/logoItem.h b/include/logoItem.h index faedd838dca7f9441f819711d54cea3496626642..77960f4aff2b78612056d93bb520ee608216cabe 100644 --- a/include/logoItem.h +++ b/include/logoItem.h @@ -26,44 +26,39 @@ class Petrack; class LogoItem; -class Fader: public QObject +class Fader : public QObject { Q_OBJECT public: Fader(); - void fadeOut(LogoItem* gi, int frames); + void fadeOut(LogoItem *gi, int frames); private slots: void fadeOutStep(); + public: - LogoItem* mLogoItem; - int mFrames; - double mStep; - QTimer *mTimer; + LogoItem *mLogoItem; + int mFrames; + double mStep; + QTimer * mTimer; }; -class LogoItem: public QGraphicsItem +class LogoItem : public QGraphicsItem { public: - LogoItem(QWidget *wParent, QGraphicsItem * parent = nullptr); + LogoItem(QWidget *wParent, QGraphicsItem *parent = nullptr); QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - inline float getOpacity() const - { - return mOpacity; - } - inline void setOpacity(float o) - { - mOpacity = o; - } - void fadeOut(int frames=100); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + inline float getOpacity() const { return mOpacity; } + inline void setOpacity(float o) { mOpacity = o; } + void fadeOut(int frames = 100); private: Petrack *mMainWindow; - QImage *mImage; - float mOpacity; - Fader fader; + QImage * mImage; + float mOpacity; + Fader fader; }; #endif diff --git a/include/markerCasern.h b/include/markerCasern.h index bdba3cf2e372686f2190ce563d56c91f20c30b16..338ec69a01cddd1b65ab11c25e716810603e4a32 100644 --- a/include/markerCasern.h +++ b/include/markerCasern.h @@ -21,64 +21,49 @@ #ifndef MARKERCASERN_H #define MARKERCASERN_H -#include <QList> -#include <QColor> - #include "ellipse.h" +#include <QColor> +#include <QList> + class TrackPoint; class MarkerCasern { private: - MyEllipse mHead; - bool mHasHead; - Vec2F mQuadrangle[4]; - bool mHasQuadrangle; + MyEllipse mHead; + bool mHasHead; + Vec2F mQuadrangle[4]; + bool mHasQuadrangle; QList<MyEllipse> mSpots; - QList<int> mSpotCount; - QColor mCol; - int mCenterIndex; // index in mSpots list from cross marker - int mColorIndex; // index in mSpots list from color marker - int mOtherIndex; // index in mSpots list from round marker + QList<int> mSpotCount; + QColor mCol; + int mCenterIndex; // index in mSpots list from cross marker + int mColorIndex; // index in mSpots list from color marker + int mOtherIndex; // index in mSpots list from round marker public: MarkerCasern(MyEllipse head); MarkerCasern(); ~MarkerCasern(); - - inline const MyEllipse& head() const - { - return mHead; - } - inline const Vec2F* quadrangle() const - { - return mQuadrangle; - } - inline const QList<MyEllipse>& spots() const // reference to be faster + + inline const MyEllipse & head() const { return mHead; } + inline const Vec2F * quadrangle() const { return mQuadrangle; } + inline const QList<MyEllipse> &spots() const // reference to be faster { return mSpots; } - inline const QColor& color() const - { - return mCol; - } + inline const QColor &color() const { return mCol; } - inline bool hasHead() const - { - return mHasHead; - } - inline bool hasQuadrangle() const - { - return mHasQuadrangle; - } + inline bool hasHead() const { return mHasHead; } + inline bool hasQuadrangle() const { return mHasQuadrangle; } - bool isOverlappingHead(const MyEllipse& e) const; - bool isInsideHead(const Vec2F& p) const; + bool isOverlappingHead(const MyEllipse &e) const; + bool isInsideHead(const Vec2F &p) const; // returns spot number in spots list when inside, otherwise returns -1 - int isOverlappingSpots(const MyEllipse& e) const; - int isInsideSpots(const Vec2F& p) const; + int isOverlappingSpots(const MyEllipse &e) const; + int isInsideSpots(const Vec2F &p) const; void modifyHead(const MyEllipse &head); @@ -101,13 +86,12 @@ public: class MarkerCasernList : public QList<MarkerCasern> { public: - bool mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool blackInside); + bool mayAddEllipse(const cv::Mat &img, const MyEllipse &e, bool blackInside); bool mayAddQuadrangle(const Vec2F v[4]); // organize every marker and delete marker without head void organize(const cv::Mat &img, bool autoWB); - //draw ... Qt void draw(cv::Mat &img) const; void toCrossList(QList<TrackPoint> *crossList, bool ignoreWithoutMarker) const; diff --git a/include/markerHermes.h b/include/markerHermes.h index aba58823b7fa64473d9e128b1f8d866bdb9f45cb..2e1231e029e42269b179cbcae9f98dc3824a38d0 100644 --- a/include/markerHermes.h +++ b/include/markerHermes.h @@ -21,46 +21,40 @@ #ifndef MARKERHERMES_H #define MARKERHERMES_H -#include <QList> -#include <QColor> - #include "ellipse.h" +#include <QColor> +#include <QList> + class TrackPoint; class MarkerHermes { private: - MyEllipse mHead; - bool mHasHead; + MyEllipse mHead; + bool mHasHead; QList<MyEllipse> mSpots; - QList<int> mSpotCount; - int mCenterIndex; // index in mSpots list from black marker -1 or 0 + QList<int> mSpotCount; + int mCenterIndex; // index in mSpots list from black marker -1 or 0 public: MarkerHermes(MyEllipse head); MarkerHermes(); ~MarkerHermes(); - - inline const MyEllipse& head() const - { - return mHead; - } - inline const QList<MyEllipse>& spots() const // reference to be faster + + inline const MyEllipse & head() const { return mHead; } + inline const QList<MyEllipse> &spots() const // reference to be faster { return mSpots; } - inline bool hasHead() const - { - return mHasHead; - } + inline bool hasHead() const { return mHasHead; } - bool isOverlappingHead(const MyEllipse& e) const; - bool isInsideHead(const Vec2F& p) const; + bool isOverlappingHead(const MyEllipse &e) const; + bool isInsideHead(const Vec2F &p) const; // returns spot number in spots list when inside, otherwise returns -1 - int isOverlappingSpots(const MyEllipse& e) const; - int isInsideSpots(const Vec2F& p) const; + int isOverlappingSpots(const MyEllipse &e) const; + int isInsideSpots(const Vec2F &p) const; void modifyHead(const MyEllipse &head); @@ -80,7 +74,7 @@ public: class MarkerHermesList : public QList<MarkerHermes> { public: - bool mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool blackInside); + bool mayAddEllipse(const cv::Mat &img, const MyEllipse &e, bool blackInside); // organize every marker and delete marker without head void organize(const cv::Mat &img, bool autoWB); diff --git a/include/markerJapan.h b/include/markerJapan.h index 7518ca9a324830ea7b0df0e9dbf4bc893df1fe9a..945bfb3b477c2919636e8a224003580b68a4fb4c 100644 --- a/include/markerJapan.h +++ b/include/markerJapan.h @@ -21,67 +21,52 @@ #ifndef MARKERJAPAN_H #define MARKERJAPAN_H -#include <QList> -#include <QColor> - #include "ellipse.h" +#include <QColor> +#include <QList> + class TrackPoint; class MarkerJapan { private: - MyEllipse mHead; - bool mHasHead; - Vec2F mQuadrangle[4]; - bool mHasQuadrangle; + MyEllipse mHead; + bool mHasHead; + Vec2F mQuadrangle[4]; + bool mHasQuadrangle; QList<MyEllipse> mSpots; - QList<int> mSpotCount; - QColor mCol; - int mCenterIndex; // index in mSpots list from cross marker - int mColorIndex; // index in mSpots list from color marker - int mOtherIndex; // index in mSpots list from round marker + QList<int> mSpotCount; + QColor mCol; + int mCenterIndex; // index in mSpots list from cross marker + int mColorIndex; // index in mSpots list from color marker + int mOtherIndex; // index in mSpots list from round marker public: MarkerJapan(MyEllipse head); MarkerJapan(); ~MarkerJapan(); - - inline const MyEllipse& head() const - { - return mHead; - } - inline const Vec2F* quadrangle() const - { - return mQuadrangle; - } - inline const QList<MyEllipse>& spots() const // reference to be faster + + inline const MyEllipse & head() const { return mHead; } + inline const Vec2F * quadrangle() const { return mQuadrangle; } + inline const QList<MyEllipse> &spots() const // reference to be faster { return mSpots; } - inline const QColor& color() const - { - return mCol; - } + inline const QColor &color() const { return mCol; } inline bool hasSpots() const { return mSpots.size() > 1; // mindestens 2 spots werden benoetigt, damit ein gueltiger Marker! } - inline bool hasHead() const - { - return mHasHead; - } - inline bool hasQuadrangle() const - { - return mHasQuadrangle; - } + inline bool hasHead() const { return mHasHead; } + inline bool hasQuadrangle() const { return mHasQuadrangle; } - bool isOverlappingHead(const MyEllipse& e) const; - bool isInsideHead(const Vec2F& p) const; + bool isOverlappingHead(const MyEllipse &e) const; + bool isInsideHead(const Vec2F &p) const; // returns spot number in spots list when inside, otherwise returns -1 - int isOverlappingSpots(const MyEllipse& e) const; - int isInsideSpots(const Vec2F& p) const; + int isOverlappingSpots(const MyEllipse &e) const; + int isInsideSpots(const Vec2F &p) const; void modifyHead(const MyEllipse &head, float headSize); @@ -93,32 +78,27 @@ public: void organize(const cv::Mat &img, bool autoWB); - Vec2F getCenter() const; + Vec2F getCenter() const; MyEllipse getCenterSpot() const; MyEllipse getColorSpot() const; void draw(cv::Mat &img) const; }; -//---------------------------------------------------------------------------- class MarkerJapanList : public QList<MarkerJapan> { private: float mHeadSize; + public: - MarkerJapanList(float headSize) - : mHeadSize(headSize) - { - } - bool mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool blackInside); + MarkerJapanList(float headSize) : mHeadSize(headSize) {} + bool mayAddEllipse(const cv::Mat &img, const MyEllipse &e, bool blackInside); bool mayAddQuadrangle(const Vec2F v[4]); // organize every marker and delete marker without head void organize(const cv::Mat &img, bool autoWB); - //draw ... Qt - void draw(cv::Mat &img) const; void toCrossList(QList<TrackPoint> *crossList, bool ignoreWithoutMarker) const; diff --git a/include/moCapController.h b/include/moCapController.h index e9a83d1712024a56782ec4f0d60029febf2975a0..356e514c3c653df477eed86211c72a77e4c4b822 100644 --- a/include/moCapController.h +++ b/include/moCapController.h @@ -20,27 +20,27 @@ #ifndef MOCAPCONTROLLER_H #define MOCAPCONTROLLER_H -#include <QObject> +#include "extrCalibration.h" +#include "moCapPersonMetadata.h" + #include <QColor> #include <QLine> +#include <QObject> #include <vector> -#include "extrCalibration.h" -#include "moCapPersonMetadata.h" - struct SkeletonLine; class QDomElement; struct SegmentRenderData { public: - QLine mLine; + QLine mLine; QColor mColor; - int mThickness; - bool mDirected; + int mThickness; + bool mDirected; }; -bool operator==(const SegmentRenderData& lhs, const SegmentRenderData& rhs); +bool operator==(const SegmentRenderData &lhs, const SegmentRenderData &rhs); /** * @brief The MoCapController class controls the visualisation of MoCap data. @@ -53,17 +53,21 @@ class MoCapController : public QObject { Q_OBJECT public: - MoCapController(MoCapStorage& storage, ExtrCalibration& extrCalib): mStorage(storage), mExtrCalib(extrCalib) {}; + MoCapController(MoCapStorage &storage, ExtrCalibration &extrCalib) : mStorage(storage), mExtrCalib(extrCalib){}; - void transformPersonSkeleton(const MoCapPerson& person, double framerate, int currentFrame, std::vector<SegmentRenderData>& renderData) const; - std::vector<SegmentRenderData> getRenderData(int currentFrame, double framerate) const; - bool getShowMoCap() const { return mShowMoCap; }; - void setShowMoCap(bool visibility); - void setColor(const QColor &color); - void setThickness(int thickness); - void notifyAllObserver(); + void transformPersonSkeleton( + const MoCapPerson & person, + double framerate, + int currentFrame, + std::vector<SegmentRenderData> &renderData) const; + std::vector<SegmentRenderData> getRenderData(int currentFrame, double framerate) const; + bool getShowMoCap() const { return mShowMoCap; }; + void setShowMoCap(bool visibility); + void setColor(const QColor &color); + void setThickness(int thickness); + void notifyAllObserver(); std::vector<MoCapPersonMetadata> getAllMoCapPersonMetadata() const; - void readMoCapFiles(const std::vector<MoCapPersonMetadata> &newMetadata); + void readMoCapFiles(const std::vector<MoCapPersonMetadata> &newMetadata); void setXml(QDomElement &elem); void getXml(const QDomElement &elem); @@ -74,14 +78,15 @@ signals: void thicknessChanged(int thickness); private: - static std::vector<SkeletonLine> interpolate(const std::vector<SkeletonLine>& prePairs, const std::vector<SkeletonLine>& postPairs, double weight); + static std::vector<SkeletonLine> + interpolate(const std::vector<SkeletonLine> &prePairs, const std::vector<SkeletonLine> &postPairs, double weight); - MoCapStorage& mStorage; - bool mShowMoCap = false; - QColor mColor = QColor(255, 255, 55); - int mThickness = 2; - ExtrCalibration& mExtrCalib; + MoCapStorage & mStorage; + bool mShowMoCap = false; + QColor mColor = QColor(255, 255, 55); + int mThickness = 2; + ExtrCalibration &mExtrCalib; }; #endif // MOCAPCONTROLLER_H diff --git a/include/moCapItem.h b/include/moCapItem.h index 9947ef26f1a08f2a6379a7fe07bb6aeed514d261..151a16db45ad870123af52c9c6201c5fdb66e79f 100644 --- a/include/moCapItem.h +++ b/include/moCapItem.h @@ -38,15 +38,20 @@ struct SegmentRenderData; class MoCapItem : public QGraphicsItem { public: - MoCapItem(QWidget &wParent, Animation &animation, MoCapController &moCapController, QGraphicsItem *parent = nullptr); + MoCapItem( + QWidget & wParent, + Animation & animation, + MoCapController &moCapController, + QGraphicsItem * parent = nullptr); QRectF boundingRect() const override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + private: - Petrack &mMainWindow; - Animation &mAnimation; + Petrack & mMainWindow; + Animation & mAnimation; MoCapController &mController; - static void drawLine(QPainter *painter, SegmentRenderData &renderData) ; - static void drawArrowHead(QPainter *painter, SegmentRenderData &renderData) ; + static void drawLine(QPainter *painter, SegmentRenderData &renderData); + static void drawArrowHead(QPainter *painter, SegmentRenderData &renderData); }; #endif // MOCAPITEM_H diff --git a/include/moCapPerson.h b/include/moCapPerson.h index 4f7406cd20ed58e1c78de7473911076f8862f839..0158743e2e688158a2e463e1a330d7b708f47126 100644 --- a/include/moCapPerson.h +++ b/include/moCapPerson.h @@ -20,10 +20,10 @@ #ifndef MOCAPPERSON_H #define MOCAPPERSON_H -#include <vector> -#include "skeletonTree.h" #include "moCapPersonMetadata.h" +#include "skeletonTree.h" +#include <vector> class QDomElement; @@ -39,20 +39,16 @@ class QDomElement; class MoCapPerson { public: - double getSampleIndex(double time) const; - inline bool hasSample(size_t index) const{ - return index < mSkeletons.size(); - }; - inline const SkeletonTree& getSample(size_t sample) const{ - return mSkeletons.at(sample); - } + double getSampleIndex(double time) const; + inline bool hasSample(size_t index) const { return index < mSkeletons.size(); }; + inline const SkeletonTree &getSample(size_t sample) const { return mSkeletons.at(sample); } - void setSamplerate(double samplerate); - void setTimeOffset(double timeOffset); - void setMetadata(const MoCapPersonMetadata& metadata); - void addSkeleton(const SkeletonTree& skeleton); - const SkeletonTree& getSkeleton(size_t samples) const; - const std::string& getFilename() const; + void setSamplerate(double samplerate); + void setTimeOffset(double timeOffset); + void setMetadata(const MoCapPersonMetadata &metadata); + void addSkeleton(const SkeletonTree &skeleton); + const SkeletonTree & getSkeleton(size_t samples) const; + const std::string & getFilename() const; const MoCapPersonMetadata &getMetadata() const; @@ -60,22 +56,19 @@ public: private: std::vector<SkeletonTree> mSkeletons; - MoCapPersonMetadata mMetadata; + MoCapPersonMetadata mMetadata; }; class MoCapStorage { private: std::vector<MoCapPerson> mPersons; + public: - void addPerson(const MoCapPerson &person); - void addPerson(MoCapPerson&& person); - std::vector<MoCapPerson>& getPersons(){ - return mPersons; - } - const std::vector<MoCapPerson>& getPersons() const{ - return mPersons; - } + void addPerson(const MoCapPerson &person); + void addPerson(MoCapPerson &&person); + std::vector<MoCapPerson> & getPersons() { return mPersons; } + const std::vector<MoCapPerson> &getPersons() const { return mPersons; } }; #endif // MOCAPPERSON_H diff --git a/include/moCapPersonMetadata.h b/include/moCapPersonMetadata.h index e09c581bf7913de048fb948b0c9f8b09ce9ecfd4..0f49230ad4b0dea28b840bf8ed26e2f409511078 100644 --- a/include/moCapPersonMetadata.h +++ b/include/moCapPersonMetadata.h @@ -22,12 +22,14 @@ #include "IO.h" -enum MoCapSystem{ +enum MoCapSystem +{ XSensC3D = 0, END ///< Used for checks before casting an int to MoCapSystem, must always stay at the end! }; + /** This map maps different MoCapSystems to an appropriate file extension. It is used for validating a given filepath. - * in the OpenMoCapDialog and MoCapPersonMetadata and should be expanded with every new MoCapSystem.*/ + * in the OpenMoCapDialog and MoCapPersonMetadata and should be expanded with every new MoCapSystem.*/ const std::map<MoCapSystem, std::string> moCapFileExtensions = {{MoCapSystem::XSensC3D, "c3d"}}; @@ -38,30 +40,31 @@ const std::map<MoCapSystem, std::string> moCapFileExtensions = {{MoCapSystem::XS * MoCap-Recording. This class identifies a single recording and * includes all data needed by PeTrack to (re)load a MoCap-Recording. */ -class MoCapPersonMetadata{ +class MoCapPersonMetadata +{ public: - MoCapPersonMetadata() = default; - MoCapPersonMetadata(const MoCapPersonMetadata&) = default; - MoCapPersonMetadata(MoCapPersonMetadata&&) = default; - MoCapPersonMetadata& operator=(const MoCapPersonMetadata&) = default; - MoCapPersonMetadata& operator=(MoCapPersonMetadata&&) = default; - ~MoCapPersonMetadata() = default; + MoCapPersonMetadata() = default; + MoCapPersonMetadata(const MoCapPersonMetadata &) = default; + MoCapPersonMetadata(MoCapPersonMetadata &&) = default; + MoCapPersonMetadata &operator=(const MoCapPersonMetadata &) = default; + MoCapPersonMetadata &operator=(MoCapPersonMetadata &&) = default; + ~MoCapPersonMetadata() = default; MoCapPersonMetadata(std::string filepath, MoCapSystem system, double samplerate, double offset); - void setFilepath(const std::string &filepath, MoCapSystem system); - void setSamplerate(double samplerate); - void setOffset(double offset); - void setMetadata(const std::string &filepath, MoCapSystem, double samplerate, double offset); - MoCapSystem getSystem() const; - double getSamplerate() const; - double getOffset() const; + void setFilepath(const std::string &filepath, MoCapSystem system); + void setSamplerate(double samplerate); + void setOffset(double offset); + void setMetadata(const std::string &filepath, MoCapSystem, double samplerate, double offset); + MoCapSystem getSystem() const; + double getSamplerate() const; + double getOffset() const; const std::string &getFilepath() const; private: - std::string mFilepath = ""; - MoCapSystem mSystem = XSensC3D; - double mSamplerate = 60; - double mOffset = 0; ///< time offset from MoCap to video in seconds + std::string mFilepath = ""; + MoCapSystem mSystem = XSensC3D; + double mSamplerate = 60; + double mOffset = 0; ///< time offset from MoCap to video in seconds }; bool operator==(const MoCapPersonMetadata &lhs, const MoCapPersonMetadata &rhs); diff --git a/include/moCapSelectionWidget.h b/include/moCapSelectionWidget.h index 837af10a038f7d946736816779a67643f8517e58..2bb92cde5868f5fc7afa93d7a2ee150eb05eda58 100644 --- a/include/moCapSelectionWidget.h +++ b/include/moCapSelectionWidget.h @@ -1,13 +1,15 @@ #ifndef MOCAPSELECTIONWIDGET_H #define MOCAPSELECTIONWIDGET_H -#include <QWidget> - #include "moCapPersonMetadata.h" -namespace Ui { - class MoCapSelectionWidget; +#include <QWidget> + +namespace Ui +{ +class MoCapSelectionWidget; } + class OpenMoCapDialog; class MoCapSelectionWidget : public QWidget @@ -15,24 +17,26 @@ class MoCapSelectionWidget : public QWidget Q_OBJECT public: - explicit MoCapSelectionWidget(QWidget *parent, const QMap<QString, MoCapSystem>& moCapSystems); - explicit MoCapSelectionWidget(QWidget *parent, const QMap<QString, MoCapSystem>& moCapSystems, const MoCapPersonMetadata& metadata); - MoCapSelectionWidget(const MoCapSelectionWidget&) = delete; - MoCapSelectionWidget(MoCapSelectionWidget&&) = delete; - MoCapSelectionWidget& operator=(const MoCapSelectionWidget&) = delete; - MoCapSelectionWidget& operator=(MoCapSelectionWidget&&) = delete; + explicit MoCapSelectionWidget(QWidget *parent, const QMap<QString, MoCapSystem> &moCapSystems); + explicit MoCapSelectionWidget( + QWidget * parent, + const QMap<QString, MoCapSystem> &moCapSystems, + const MoCapPersonMetadata & metadata); + MoCapSelectionWidget(const MoCapSelectionWidget &) = delete; + MoCapSelectionWidget(MoCapSelectionWidget &&) = delete; + MoCapSelectionWidget &operator=(const MoCapSelectionWidget &) = delete; + MoCapSelectionWidget &operator=(MoCapSelectionWidget &&) = delete; ~MoCapSelectionWidget() override; - void setFileName(); + void setFileName(); MoCapPersonMetadata getMetadata() const; bool isFilledOut() const; private: - Ui::MoCapSelectionWidget *mUi; - const QMap<QString, MoCapSystem>& mMoCapSystems; - bool mFilledOut = false; - + Ui::MoCapSelectionWidget * mUi; + const QMap<QString, MoCapSystem> &mMoCapSystems; + bool mFilledOut = false; }; #endif // MOCAPSELECTIONWIDGET_H diff --git a/include/multiColorMarkerItem.h b/include/multiColorMarkerItem.h index 31055aad3d25aa28cc688aa4d8cc31607e469df7..e0655d68176f60e7a7f191b6c2fd5fb78b370cca 100644 --- a/include/multiColorMarkerItem.h +++ b/include/multiColorMarkerItem.h @@ -21,10 +21,10 @@ #ifndef MULTICOLORMARKERITEM_H #define MULTICOLORMARKERITEM_H -#include <QGraphicsItem> - #include "vector.h" +#include <QGraphicsItem> + class Petrack; class Control; class Tracker; @@ -33,20 +33,17 @@ class MultiColorMarkerItem : public QGraphicsItem { private: Petrack *mMainWindow; - QImage *mImage; - cv::Mat mMask; - Vec2F mUlc; // upper left corner to draw + QImage * mImage; + cv::Mat mMask; + Vec2F mUlc; // upper left corner to draw public: - MultiColorMarkerItem(QWidget *wParent, QGraphicsItem * parent = nullptr); - QRectF boundingRect() const; - void setRect(Vec2F& v); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - cv::Mat getMask() - { - return mMask; - } - void setMask(cv::Mat &mask); + MultiColorMarkerItem(QWidget *wParent, QGraphicsItem *parent = nullptr); + QRectF boundingRect() const; + void setRect(Vec2F &v); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + cv::Mat getMask() { return mMask; } + void setMask(cv::Mat &mask); cv::Mat createMask(int w, int h); }; diff --git a/include/multiColorMarkerWidget.h b/include/multiColorMarkerWidget.h index d9506eb64b9fea82d71e3afbe692d9c264173262..d5383bf48010165a12c2bf711cca986674bfe174 100644 --- a/include/multiColorMarkerWidget.h +++ b/include/multiColorMarkerWidget.h @@ -21,16 +21,16 @@ #ifndef MULTICOLORMARKERWIDGET_H #define MULTICOLORMARKERWIDGET_H -#include <QtWidgets> -#include "ui_multiColorMarker.h" - -#include "petrack.h" -#include "multiColorMarkerItem.h" #include "codeMarkerWidget.h" -#include "imageItem.h" #include "control.h" +#include "imageItem.h" +#include "multiColorMarkerItem.h" +#include "petrack.h" +#include "ui_multiColorMarker.h" -class MultiColorMarkerWidget: public QWidget, public Ui::MultiColorMarker +#include <QtWidgets> + +class MultiColorMarkerWidget : public QWidget, public Ui::MultiColorMarker { Q_OBJECT @@ -47,12 +47,12 @@ private slots: void on_useDot_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens mMainWindow->updateImage(); } void on_dotSize_valueChanged(double /*d*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens mMainWindow->updateImage(); } void on_useCodeMarker_stateChanged(int /* i */) @@ -60,33 +60,30 @@ private slots: mMainWindow->setRecognitionChanged(true); mMainWindow->updateImage(); } - void on_CodeMarkerParameter_clicked() - { - mMainWindow->getCodeMarkerWidget()->show(); - } + void on_CodeMarkerParameter_clicked() { mMainWindow->getCodeMarkerWidget()->show(); } void on_ignoreWithoutDot_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens mMainWindow->updateImage(); } void on_useColor_stateChanged(int /*i*/) // eigentlich nichts noetig, da nur beim Tracing aktiv { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens mMainWindow->updateImage(); } void on_restrictPosition_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens mMainWindow->updateImage(); } void on_autoCorrect_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens mMainWindow->updateImage(); } void on_autoCorrectOnlyExport_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens mMainWindow->updateImage(); } @@ -96,71 +93,70 @@ private slots: mMainWindow->getMultiColorMarkerItem()->setVisible(i); mMainWindow->getScene()->update(); } - void on_maskMask_stateChanged(int /*i*/) - { - mMainWindow->getScene()->update(); - } - void on_opacity_valueChanged(int /*i*/) - { - mMainWindow->getScene()->update(); - } + void on_maskMask_stateChanged(int /*i*/) { mMainWindow->getScene()->update(); } + void on_opacity_valueChanged(int /*i*/) { mMainWindow->getScene()->update(); } // functions which force a new recognition void on_useOpen_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void on_useClose_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void on_closeRadius_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void on_openRadius_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void on_minArea_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void on_maxArea_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void on_useHeadSize_stateChanged(int i) { - if (i) + if(i) { - if (mMainWindow->getImageItem() && mMainWindow->getImage() && mMainWindow->getControlWidget()) + if(mMainWindow->getImageItem() && mMainWindow->getImage() && mMainWindow->getControlWidget()) { - QPointF cmPerPixel1 = mMainWindow->getImageItem()->getCmPerPixel(0, 0, mMainWindow->getControlWidget()->mapDefaultHeight->value()); - QPointF cmPerPixel2 = mMainWindow->getImageItem()->getCmPerPixel(mMainWindow->getImage()->width()-1, mMainWindow->getImage()->height()-1, mMainWindow->getControlWidget()->mapDefaultHeight->value()); - double cmPerPixelAvg = (cmPerPixel1.x()+cmPerPixel1.y()+cmPerPixel2.x()+cmPerPixel2.y())/4.; - if (cmPerPixelAvg > 0) + QPointF cmPerPixel1 = mMainWindow->getImageItem()->getCmPerPixel( + 0, 0, mMainWindow->getControlWidget()->mapDefaultHeight->value()); + QPointF cmPerPixel2 = mMainWindow->getImageItem()->getCmPerPixel( + mMainWindow->getImage()->width() - 1, + mMainWindow->getImage()->height() - 1, + mMainWindow->getControlWidget()->mapDefaultHeight->value()); + double cmPerPixelAvg = (cmPerPixel1.x() + cmPerPixel1.y() + cmPerPixel2.x() + cmPerPixel2.y()) / 4.; + if(cmPerPixelAvg > 0) { - double area = PI*0.25 * HEAD_SIZE/cmPerPixelAvg * 14./cmPerPixelAvg; // 14. Kopfbreite // Elipse: A=Pi*a*b (a,b Halbachsen) + double area = PI * 0.25 * HEAD_SIZE / cmPerPixelAvg * 14. / + cmPerPixelAvg; // 14. Kopfbreite // Elipse: A=Pi*a*b (a,b Halbachsen) mOldMinArea = minArea->value(); mOldMaxArea = maxArea->value(); - minArea->setValue(area*0.75); - maxArea->setValue(area*2.5); + minArea->setValue(area * 0.75); + maxArea->setValue(area * 2.5); } } minArea->setDisabled(true); @@ -174,14 +170,14 @@ private slots: maxArea->setValue(mOldMaxArea); } - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens mMainWindow->updateImage(); } void on_maxRatio_valueChanged(double /*d*/) { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } diff --git a/include/openMoCapDialog.h b/include/openMoCapDialog.h index 707d4157450764440a7e38a821baf47fb4f2a082..ca47ae3a24c802fac63d2fc7f094f6422228c262 100644 --- a/include/openMoCapDialog.h +++ b/include/openMoCapDialog.h @@ -20,15 +20,16 @@ #ifndef OPENMOCAPDIALOG_H #define OPENMOCAPDIALOG_H -#include <QDialog> -#include <QMap> - #include "IO.h" #include "moCapController.h" #include "moCapPersonMetadata.h" -namespace Ui { - class OpenMoCapDialog; +#include <QDialog> +#include <QMap> + +namespace Ui +{ +class OpenMoCapDialog; } /** @@ -45,11 +46,11 @@ class OpenMoCapDialog : public QDialog public: explicit OpenMoCapDialog(QWidget *parent, MoCapController &controller); - OpenMoCapDialog() = delete; - OpenMoCapDialog(const OpenMoCapDialog&) = delete; - OpenMoCapDialog(OpenMoCapDialog&&) = delete; - OpenMoCapDialog& operator=(const OpenMoCapDialog&) = delete; - OpenMoCapDialog& operator=(OpenMoCapDialog&&) = delete; + OpenMoCapDialog() = delete; + OpenMoCapDialog(const OpenMoCapDialog &) = delete; + OpenMoCapDialog(OpenMoCapDialog &&) = delete; + OpenMoCapDialog &operator=(const OpenMoCapDialog &) = delete; + OpenMoCapDialog &operator=(OpenMoCapDialog &&) = delete; ~OpenMoCapDialog() override; void clickedOk(); @@ -58,10 +59,10 @@ private slots: void on_btnAddSelection_clicked(); private: - Ui::OpenMoCapDialog *mUi; + Ui::OpenMoCapDialog * mUi; QMap<QString, MoCapSystem> mMoCapSystems; - MoCapController &mController; - QWidget *mParent; + MoCapController & mController; + QWidget * mParent; }; #endif // OPENMOCAPDIALOG_H diff --git a/include/pMessageBox.h b/include/pMessageBox.h index 3d4e0f738e977e9afd8056ca70303535f7a320ef..1fab7b6b5d15600fdbecc599b5c0386b587f585c 100644 --- a/include/pMessageBox.h +++ b/include/pMessageBox.h @@ -29,9 +29,9 @@ class QLabel; // need to define these macros to get the file/line/function of caller // Should be replaced with std::source_location once C++20 is used #define PInformation(...) PMessageBox::information(__FILE__, __func__, __LINE__, __VA_ARGS__) -#define PWarning(...) PMessageBox::warning(__FILE__, __func__, __LINE__, __VA_ARGS__) -#define PCritical(...) PMessageBox::critical(__FILE__, __func__, __LINE__, __VA_ARGS__) -#define PQuestion(...) PMessageBox::question(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define PWarning(...) PMessageBox::warning(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define PCritical(...) PMessageBox::critical(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define PQuestion(...) PMessageBox::question(__FILE__, __func__, __LINE__, __VA_ARGS__) /** @@ -46,15 +46,54 @@ class PMessageBox final : public QDialog Q_OBJECT public: - using StandardButton = QDialogButtonBox::StandardButton; + using StandardButton = QDialogButtonBox::StandardButton; using StandardButtons = QDialogButtonBox::StandardButtons; - PMessageBox(QWidget *parent, const QString& title, const QString& msg, const QIcon& icon, const QString& informativeText = QString(), StandardButtons buttons = StandardButton::Ok, StandardButton defaultButton = StandardButton::NoButton); + PMessageBox( + QWidget * parent, + const QString & title, + const QString & msg, + const QIcon & icon, + const QString & informativeText = QString(), + StandardButtons buttons = StandardButton::Ok, + StandardButton defaultButton = StandardButton::NoButton); - static int information(const char*file, const char*func, int line, QWidget *parent, const QString& title, const QString& text, StandardButtons buttons = StandardButton::Ok, StandardButton defaultButton = StandardButton::NoButton); - static int warning(const char*file, const char*func, int line, QWidget *parent, const QString& title, const QString& text, StandardButtons buttons = StandardButton::Ok, StandardButton defaultButton = StandardButton::NoButton); - static int critical(const char*file, const char*func, int line, QWidget *parent, const QString& title, const QString& text, StandardButtons buttons = StandardButton::Ok, StandardButton defaultButton = StandardButton::NoButton); - [[nodiscard]] static int question(const char*file, const char*func, int line, QWidget *parent, const QString& title, const QString& text, StandardButtons buttons = (StandardButton::Yes | StandardButton::No), StandardButton defaultButton = StandardButton::NoButton); + static int information( + const char * file, + const char * func, + int line, + QWidget * parent, + const QString & title, + const QString & text, + StandardButtons buttons = StandardButton::Ok, + StandardButton defaultButton = StandardButton::NoButton); + static int warning( + const char * file, + const char * func, + int line, + QWidget * parent, + const QString & title, + const QString & text, + StandardButtons buttons = StandardButton::Ok, + StandardButton defaultButton = StandardButton::NoButton); + static int critical( + const char * file, + const char * func, + int line, + QWidget * parent, + const QString & title, + const QString & text, + StandardButtons buttons = StandardButton::Ok, + StandardButton defaultButton = StandardButton::NoButton); + [[nodiscard]] static int question( + const char * file, + const char * func, + int line, + QWidget * parent, + const QString & title, + const QString & text, + StandardButtons buttons = (StandardButton::Yes | StandardButton::No), + StandardButton defaultButton = StandardButton::NoButton); private: static void setMinimumWidth(QLabel *textLabel); diff --git a/include/person.h b/include/person.h index 30c5c81d908a94aa3a2b134134011a9d5a561c8f..3371b52e73f772df4643f1711e882cebb58c7bc3 100644 --- a/include/person.h +++ b/include/person.h @@ -21,73 +21,62 @@ #ifndef PERSON_H #define PERSON_H -#include <QList> - +#include "backgroundFilter.h" #include "ellipse.h" #include "stereoContext.h" -#include "backgroundFilter.h" #include "tracker.h" -inline constexpr int STEP_SIZE = 5; //10 // Hoehenschritte der Isolinien in cm +#include <QList> + +inline constexpr int STEP_SIZE = 5; // 10 // Hoehenschritte der Isolinien in cm inline constexpr int DISP_GAP_SIZE_TO_FILL = 15; // 15 pixel innerhalb einer Zeile werden linear in disp interpoliert -class Person: public QList<MyEllipse> // List is approximated isoline +class Person : public QList<MyEllipse> // List is approximated isoline { private: float mDistTopEllipse; // entfernung zur camera; Schrittweite ist STEP_SIZE zu entnehmen - bool mActLevel; // zeigt an, ob fuer aktuellen Level eine Ellipse gefunden wurde + bool mActLevel; // zeigt an, ob fuer aktuellen Level eine Ellipse gefunden wurde public: - Person(const MyEllipse &e) - : mDistTopEllipse(FLT_MAX), mActLevel(false) - { - append(e); - } - Person(const MyEllipse &e, float d) - : mDistTopEllipse(d), mActLevel(false) - { - append(e); - } - inline void setActLevel(bool b) - { - mActLevel = b; - } - inline bool getActLevel() const - { - return mActLevel; - } - inline void setDistTopEllipse(float h) - { - mDistTopEllipse = h; - } - inline float getDistTopEllipse() const - { - return mDistTopEllipse; - } + Person(const MyEllipse &e) : mDistTopEllipse(FLT_MAX), mActLevel(false) { append(e); } + Person(const MyEllipse &e, float d) : mDistTopEllipse(d), mActLevel(false) { append(e); } + inline void setActLevel(bool b) { mActLevel = b; } + inline bool getActLevel() const { return mActLevel; } + inline void setDistTopEllipse(float h) { mDistTopEllipse = h; } + inline float getDistTopEllipse() const { return mDistTopEllipse; } const MyEllipse *getHeadEllipse() const // muss pointer sein, da sonst nullptr nicht moeglich { - if (size() > (10/STEP_SIZE)) // war 1 // - return &at(10/STEP_SIZE); + if(size() > (10 / STEP_SIZE)) // war 1 // + return &at(10 / STEP_SIZE); return nullptr; } }; -class PersonList: public QList<Person> +class PersonList : public QList<Person> { private: pet::StereoContext *mSc; + public: PersonList(); - void searchEllipses(pet::StereoContext *sc, QRect &roi, BackgroundFilter* bgFilter); + void searchEllipses(pet::StereoContext *sc, QRect &roi, BackgroundFilter *bgFilter); // el liste aller ellipsen eines thresholds der hoehe // der thrershold durchlaeuft hoehenfeld von kopf bis fuss - void insertEllipses(const QList<MyEllipse> &el, float distFromCam); // nicht mehr: el wird angepasst, so dass nur noch eingefuegte ellipsen drin + void insertEllipses( + const QList<MyEllipse> &el, + float distFromCam); // nicht mehr: el wird angepasst, so dass nur noch eingefuegte ellipsen drin void optimize(); // bestimmt kopfposition in markerlosen Ueberkopfaufnahmen aus Hoehenbild - void calcPersonPos(const cv::Mat &img, QRect &roi, QList<TrackPoint> &persList, pet::StereoContext *sc, BackgroundFilter *bgFilter, bool markerLess=true); + void calcPersonPos( + const cv::Mat & img, + QRect & roi, + QList<TrackPoint> & persList, + pet::StereoContext *sc, + BackgroundFilter * bgFilter, + bool markerLess = true); }; diff --git a/include/petrack.h b/include/petrack.h index 4344bb1b36f399cc6af38b0d8651f05fbdc40345..0e9f6bf907ed51611b33ac429d3c655f07352982 100644 --- a/include/petrack.h +++ b/include/petrack.h @@ -21,28 +21,26 @@ #ifndef PETRACK_H #define PETRACK_H -#include <QMainWindow> #include <QDomDocument> #include <QKeyEvent> +#include <QMainWindow> #include <QMouseEvent> - #include <opencv2/opencv.hpp> #ifdef STEREO -#include "stereoContext.h" #include "calibStereoFilter.h" +#include "stereoContext.h" #endif -#include "brightContrastFilter.h" -#include "borderFilter.h" -#include "swapFilter.h" -#include "backgroundFilter.h" #include "autoCalib.h" +#include "backgroundFilter.h" +#include "borderFilter.h" +#include "brightContrastFilter.h" #include "coordItem.h" #include "extrCalibration.h" -#include "moCapPerson.h" #include "moCapController.h" - +#include "moCapPerson.h" #include "recognition.h" +#include "swapFilter.h" class CalibFilter; class Animation; @@ -51,7 +49,12 @@ class RecognitionRoiItem; class GridItem; #ifdef STEREO_DISABLED -enum Camera {cameraLeft, cameraRight, cameraUnset}; +enum Camera +{ + cameraLeft, + cameraRight, + cameraUnset +}; #endif // durchschnittliche Kopflaenge in cm (Kopf 21x14) @@ -131,7 +134,7 @@ public slots: void saveXml(QDomDocument &doc); bool saveSameProject(); bool saveProject(QString fileName = ""); - void writeXmlElement(QXmlStreamWriter& xmlStream, QDomElement element); + void writeXmlElement(QXmlStreamWriter &xmlStream, QDomElement element); void openSequence(QString fileName = ""); void openCameraLiveStream(int camID = -1); void openMoCapFile(); @@ -139,9 +142,9 @@ public slots: void saveView(QString dest = ""); void saveImage(QString dest = ""); void setStatusPosReal(); - void addManualTrackPointOnlyVisible(const QPointF& pos); + void addManualTrackPointOnlyVisible(const QPointF &pos); void splitTrackPerson(QPointF pos); - int addOrMoveManualTrackPoint(const QPointF& pos); + int addOrMoveManualTrackPoint(const QPointF &pos); void editTrackPersonComment(QPointF pos); void setTrackPersonHeight(QPointF pos); void resetTrackPersonHeight(QPointF pos); @@ -149,292 +152,135 @@ public slots: void deleteTrackPointAll(int direction); void deleteTrackPointROI(); void deleteTrackPointInsideROI(); -// void showContextMenu(QPointF pos); + // void showContextMenu(QPointF pos); void updateSourceInOutFrames(); void skipToFrameWheel(int delta); public: - void updateControlWidget(); - void dragEnterEvent(QDragEnterEvent *event); - void dropEvent(QDropEvent *event); - void updateSceneRect(); - double getStatusPosRealHeight(); - void setStatusStereo(float x, float y, float z); - void setStatusTime(); - void setStatusFPS(); - void setShowFPS(double fps); - void updateShowFPS(bool skipped = false); - void setStatusPosReal(const QPointF &pos); - void setStatusPos(const QPoint &pos); - void setStatusColor(const QRgb &col); - void setStatusColor(); - void setMousePosOnImage(QPointF pos); - void updateControlImage(cv::Mat &img); - int calculateRealTracker(); - void exportTracker(QString dest = ""); - void importTracker(QString dest = ""); - void testTracker(); - void trackAll(); - void playAll(); - int winSize(QPointF *pos=nullptr, int pers=-1, int frame=-1, int level=-1); - void updateImage(bool imageChanged = false); - void updateImage(const cv::Mat &img); - void updateSequence(); + void updateControlWidget(); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + void updateSceneRect(); + double getStatusPosRealHeight(); + void setStatusStereo(float x, float y, float z); + void setStatusTime(); + void setStatusFPS(); + void setShowFPS(double fps); + void updateShowFPS(bool skipped = false); + void setStatusPosReal(const QPointF &pos); + void setStatusPos(const QPoint &pos); + void setStatusColor(const QRgb &col); + void setStatusColor(); + void setMousePosOnImage(QPointF pos); + void updateControlImage(cv::Mat &img); + int calculateRealTracker(); + void exportTracker(QString dest = ""); + void importTracker(QString dest = ""); + void testTracker(); + void trackAll(); + void playAll(); + int winSize(QPointF *pos = nullptr, int pers = -1, int frame = -1, int level = -1); + void updateImage(bool imageChanged = false); + void updateImage(const cv::Mat &img); + void updateSequence(); QSet<int> getPedestrianUserSelection(); QSet<int> getPedestriansToTrack(); - double getCmPerPixel() const; - void setHeadSize(double hS=-1); - double getHeadSize(QPointF *pos=nullptr, int pers=-1, int frame=-1); + double getCmPerPixel() const; + void setHeadSize(double hS = -1); + double getHeadSize(QPointF *pos = nullptr, int pers = -1, int frame = -1); //------------------------------ // inline function - bool isLoading() const - { - return mLoading; - } - void setLoading(bool b) - { - mLoading = b; - } + bool isLoading() const { return mLoading; } + void setLoading(bool b) { mLoading = b; } + + inline pet::StereoContext *getStereoContext() { return mStereoContext; } + inline QString getProFileName() { return mProFileName; } - inline pet::StereoContext* getStereoContext() - { - return mStereoContext; - } - inline QString getProFileName() - { - return mProFileName; - } private: - inline void setProFileName(const QString& fileName) + inline void setProFileName(const QString &fileName) { // NOTE: Use only the global variant in future? // global one in helper.h because it is needed to use getFileList and shouldn't depend on Petrack - proFileName = fileName; + proFileName = fileName; mProFileName = fileName; } -public: - inline QString getTrackFileName() - { - return mTrcFileName; - } - inline void setTrackFileName(const QString &fn) - { - mTrcFileName = fn; - } - inline QString getHeightFileName() - { - return mHeightFileName; - } - inline void setHeightFileName(const QString &fn) - { - mHeightFileName = fn; - } - inline QString getMarkerIDFileName() - { - return mMarkerIDFileName; - } - inline void setMarkerIDFileName(const QString &fn) - { - mMarkerIDFileName = fn; - } - - inline Control* getControlWidget() - { - return mControlWidget; - } - inline reco::Recognizer& getRecognizer() - { - return mReco; - } - inline StereoWidget* getStereoWidget() - { - return mStereoWidget; - } - inline ColorRangeWidget* getColorRangeWidget() - { - return mColorRangeWidget; - } - inline ColorMarkerWidget* getColorMarkerWidget() - { - return mColorMarkerWidget; - } - inline CodeMarkerWidget* getCodeMarkerWidget() - { - return mCodeMarkerWidget; - } - inline MultiColorMarkerWidget* getMultiColorMarkerWidget() - { - return mMultiColorMarkerWidget; - } - inline GraphicsView* getView() - { - return mView; - } - inline QGraphicsScene* getScene() - { - return mScene; - } - inline QImage* getImage() - { - return mImage; - } - inline cv::Mat getImg() - { - return mImg; - } - inline cv::Mat getImageFiltered() - { - return mImgFiltered; - } - inline Tracker* getTracker() - { - return mTracker; - } - inline TrackerReal* getTrackerReal() - { - return mTrackerReal; - } - inline ImageItem* getImageItem() - { - return mImageItem; - } - inline StereoItem* getStereoItem() - { - return mStereoItem; - } - inline ColorMarkerItem* getColorMarkerItem() - { - return mColorMarkerItem; - } - inline CodeMarkerItem* getCodeMarkerItem() - { - return mCodeMarkerItem; - } - inline MultiColorMarkerItem* getMultiColorMarkerItem() - { - return mMultiColorMarkerItem; - } - inline BackgroundItem* getBackgroundItem() - { - return mBackgroundItem; - } - inline MoCapItem* getMoCapItem() - { - return mMoCapItem; - } - inline RecognitionRoiItem* getRecoRoiItem() - { - return mRecognitionRoiItem; - } - inline TrackingRoiItem* getTrackRoiItem() - { - return mTrackingRoiItem; - } - inline TrackerItem* getTrackerItem() - { - return mTrackerItem; - } - inline Animation* getAnimation() - { - return mAnimation; - } - inline Player* getPlayer() - { - return mPlayerWidget; - } +public: + inline QString getTrackFileName() { return mTrcFileName; } + inline void setTrackFileName(const QString &fn) { mTrcFileName = fn; } + inline QString getHeightFileName() { return mHeightFileName; } + inline void setHeightFileName(const QString &fn) { mHeightFileName = fn; } + inline QString getMarkerIDFileName() { return mMarkerIDFileName; } + inline void setMarkerIDFileName(const QString &fn) { mMarkerIDFileName = fn; } + + inline Control * getControlWidget() { return mControlWidget; } + inline reco::Recognizer & getRecognizer() { return mReco; } + inline StereoWidget * getStereoWidget() { return mStereoWidget; } + inline ColorRangeWidget * getColorRangeWidget() { return mColorRangeWidget; } + inline ColorMarkerWidget * getColorMarkerWidget() { return mColorMarkerWidget; } + inline CodeMarkerWidget * getCodeMarkerWidget() { return mCodeMarkerWidget; } + inline MultiColorMarkerWidget *getMultiColorMarkerWidget() { return mMultiColorMarkerWidget; } + inline GraphicsView * getView() { return mView; } + inline QGraphicsScene * getScene() { return mScene; } + inline QImage * getImage() { return mImage; } + inline cv::Mat getImg() { return mImg; } + inline cv::Mat getImageFiltered() { return mImgFiltered; } + inline Tracker * getTracker() { return mTracker; } + inline TrackerReal * getTrackerReal() { return mTrackerReal; } + inline ImageItem * getImageItem() { return mImageItem; } + inline StereoItem * getStereoItem() { return mStereoItem; } + inline ColorMarkerItem * getColorMarkerItem() { return mColorMarkerItem; } + inline CodeMarkerItem * getCodeMarkerItem() { return mCodeMarkerItem; } + inline MultiColorMarkerItem * getMultiColorMarkerItem() { return mMultiColorMarkerItem; } + inline BackgroundItem * getBackgroundItem() { return mBackgroundItem; } + inline MoCapItem * getMoCapItem() { return mMoCapItem; } + inline RecognitionRoiItem * getRecoRoiItem() { return mRecognitionRoiItem; } + inline TrackingRoiItem * getTrackRoiItem() { return mTrackingRoiItem; } + + inline TrackerItem *getTrackerItem() { return mTrackerItem; } + inline Animation * getAnimation() { return mAnimation; } + inline Player * getPlayer() { return mPlayerWidget; } inline void updateCoord() { - if (mCoordItem) + if(mCoordItem) mCoordItem->updateData(); } - inline QPointF getMousePosOnImage() - { - return mMousePosOnImage; - } + inline QPointF getMousePosOnImage() { return mMousePosOnImage; } - inline void setRecognitionChanged(bool b) - { - mRecognitionChanged = b; - } - inline bool recognitionChanged() const - { - return mRecognitionChanged; - } + inline void setRecognitionChanged(bool b) { mRecognitionChanged = b; } + inline bool recognitionChanged() const { return mRecognitionChanged; } - inline void setTrackChanged(bool b) - { - mTrackChanged = b; - } - inline bool trackChanged() const - { - return mTrackChanged; - } - inline QAction* getHideControlActor() - { - return mHideControlsAct; - } + inline void setTrackChanged(bool b) { mTrackChanged = b; } + inline bool trackChanged() const { return mTrackChanged; } + inline QAction *getHideControlActor() { return mHideControlsAct; } // Attention: not type save, be care that animation is not stereo - inline CalibFilter* getCalibFilter() - { - return (CalibFilter*) mCalibFilter; - } + inline CalibFilter *getCalibFilter() { return (CalibFilter *) mCalibFilter; } #ifdef STEREO // Attention: not type save, be care that animation is stereo - inline CalibStereoFilter* getCalibStereoFilter() - { - return (CalibStereoFilter*) mCalibFilter; - } + inline CalibStereoFilter *getCalibStereoFilter() { return (CalibStereoFilter *) mCalibFilter; } #endif - inline BrightContrastFilter* getBrightContrastFilter() - { - return &mBrightContrastFilter; - } - inline BorderFilter* getBorderFilter() - { - return &mBorderFilter; - } - inline SwapFilter* getSwapFilter() - { - return &mSwapFilter; - } - inline BackgroundFilter* getBackgroundFilter() - { - return &mBackgroundFilter; - } + inline BrightContrastFilter *getBrightContrastFilter() { return &mBrightContrastFilter; } + inline BorderFilter * getBorderFilter() { return &mBorderFilter; } + inline SwapFilter * getSwapFilter() { return &mSwapFilter; } + inline BackgroundFilter * getBackgroundFilter() { return &mBackgroundFilter; } inline int getImageBorderSize() { - if (getBorderFilter()->getEnabled()) + if(getBorderFilter()->getEnabled()) return (int) getBorderFilter()->getBorderSize()->getValue(); else return 0; } - inline void setImageBorderSize(int sz) - { - getBorderFilter()->getBorderSize()->setValue(sz); - } + inline void setImageBorderSize(int sz) { getBorderFilter()->getBorderSize()->setValue(sz); } - inline AutoCalib* getAutoCalib() - { - return &mAutoCalib; - } - inline ExtrCalibration* getExtrCalibration() - { - return &mExtrCalibration; - } - inline double getStatusFPS() const - { - return mShowFPS; - } - inline MoCapController& getMoCapController() - { - return mMoCapController; - } + inline AutoCalib * getAutoCalib() { return &mAutoCalib; } + inline ExtrCalibration *getExtrCalibration() { return &mExtrCalibration; } + inline double getStatusFPS() const { return mShowFPS; } + inline MoCapController &getMoCapController() { return mMoCapController; } void updateWindowTitle(); @@ -443,7 +289,7 @@ public: * @brief Sets the information about the compiled PeTrack version. * @param petrackVersion current PeTrack version */ - void setPeTrackVersion(const std::string& petrackVersion); + void setPeTrackVersion(const std::string &petrackVersion); /** * @brief Sets the information about the compiled git commit hash, commit date, @@ -453,9 +299,9 @@ public: * @param gitCommitBranch commit branch of current version */ void setGitInformation( - const std::string& gitCommitID, - const std::string& gitCommitDate, - const std::string& gitCommitBranch); + const std::string &gitCommitID, + const std::string &gitCommitDate, + const std::string &gitCommitBranch); /** * @brief Sets the information about the used compiler and time stamp @@ -463,9 +309,10 @@ public: * @param compilerID name of the used compiler * @param compilerVersion version of the used compiler */ - void setCompileInformation(const std::string &compileTimeStamp, - const std::string &compilerID, - const std::string &compilerVersion); + void setCompileInformation( + const std::string &compileTimeStamp, + const std::string &compilerID, + const std::string &compilerVersion); private: void createActions(); @@ -478,68 +325,68 @@ private: bool maybeSave(); - void keyPressEvent(QKeyEvent * event); + void keyPressEvent(QKeyEvent *event); void mousePressEvent(QMouseEvent *event); //------------------------------ QHBoxLayout *mCentralLayout; - QFrame *mCentralWidget; - Control *mControlWidget; - QSplitter *mSplitter; - StereoWidget *mStereoWidget; - ColorRangeWidget *mColorRangeWidget; - ColorMarkerWidget *mColorMarkerWidget; - CodeMarkerWidget *mCodeMarkerWidget; + QFrame * mCentralWidget; + Control * mControlWidget; + QSplitter * mSplitter; + StereoWidget * mStereoWidget; + ColorRangeWidget * mColorRangeWidget; + ColorMarkerWidget * mColorMarkerWidget; + CodeMarkerWidget * mCodeMarkerWidget; MultiColorMarkerWidget *mMultiColorMarkerWidget; - QAction *mOpenSeqAct; - QAction *mOpenCameraAct; - QAction *mOpenMoCapAct; - QAction *mSaveSeqVidAct; - QAction *mSaveSeqVidViewAct; - QAction *mSaveSeqImgAct; - QAction *mSaveSeqViewAct; - QAction *mOpenPrAct; - QAction *mSaveAct; - QAction *mSavePrAct; - QAction *mSaveImageAct; - QAction *mSaveViewAct; - QAction *mPrintAct; - QAction *mResetSettingsAct; - QAction *mExitAct; - QAction *mFontAct; - QAction *mHideControlsAct; - QAction *mAntialiasAct; - QAction *mCropZoomViewAct; - QAction *mOpenGLAct; - QAction *mResetAct; - QAction *mFitViewAct; - QAction *mFitROIAct; - QAction *mCameraLeftViewAct; - QAction *mCameraRightViewAct; - QAction *mLimitPlaybackSpeed; - QAction *mFixPlaybackSpeed; - QAction *mSetToRealtime; - QAction *mSetTo0p75; - QAction *mSetTo0p50; - QAction *mSetTo0p25; - QAction *mSetTo1p25; - QAction *mSetTo1p50; - QAction *mSetTo1p75; - QAction *mSetTo2p00; - QAction *mPlayerLooping; - QAction *mDelPastAct; - QAction *mDelFutureAct; - QAction *mDelAllRoiAct; - QAction *mDelPartRoiAct; - QAction *mCommandAct; - QAction *mKeyAct; - QAction *mAboutAct; - QAction *mOnlineHelpAct; + QAction * mOpenSeqAct; + QAction * mOpenCameraAct; + QAction * mOpenMoCapAct; + QAction * mSaveSeqVidAct; + QAction * mSaveSeqVidViewAct; + QAction * mSaveSeqImgAct; + QAction * mSaveSeqViewAct; + QAction * mOpenPrAct; + QAction * mSaveAct; + QAction * mSavePrAct; + QAction * mSaveImageAct; + QAction * mSaveViewAct; + QAction * mPrintAct; + QAction * mResetSettingsAct; + QAction * mExitAct; + QAction * mFontAct; + QAction * mHideControlsAct; + QAction * mAntialiasAct; + QAction * mCropZoomViewAct; + QAction * mOpenGLAct; + QAction * mResetAct; + QAction * mFitViewAct; + QAction * mFitROIAct; + QAction * mCameraLeftViewAct; + QAction * mCameraRightViewAct; + QAction * mLimitPlaybackSpeed; + QAction * mFixPlaybackSpeed; + QAction * mSetToRealtime; + QAction * mSetTo0p75; + QAction * mSetTo0p50; + QAction * mSetTo0p25; + QAction * mSetTo1p25; + QAction * mSetTo1p50; + QAction * mSetTo1p75; + QAction * mSetTo2p00; + QAction * mPlayerLooping; + QAction * mDelPastAct; + QAction * mDelFutureAct; + QAction * mDelAllRoiAct; + QAction * mDelPartRoiAct; + QAction * mCommandAct; + QAction * mKeyAct; + QAction * mAboutAct; + QAction * mOnlineHelpAct; QActionGroup *mCameraGroupView; - QMenu *mPlaybackSpeedMenu; + QMenu * mPlaybackSpeedMenu; QMenu *mFileMenu; QMenu *mViewMenu; @@ -553,47 +400,47 @@ private: QString mHeightFileName; QString mMarkerIDFileName; - cv::Mat mImg; - cv::Mat mImgFiltered; - QImage *mImage; - Animation *mAnimation; + cv::Mat mImg; + cv::Mat mImgFiltered; + QImage * mImage; + Animation * mAnimation; pet::StereoContext *mStereoContext; - Player *mPlayerWidget; - - ViewWidget *mViewWidget; - GraphicsView *mView; - QGraphicsScene *mScene; - ImageItem *mImageItem; - LogoItem *mLogoItem; - CoordItem *mCoordItem; - GridItem *mGridItem; - RecognitionRoiItem *mRecognitionRoiItem; - TrackingRoiItem *mTrackingRoiItem; - TrackerItem *mTrackerItem; - StereoItem *mStereoItem; - ColorMarkerItem *mColorMarkerItem; - CodeMarkerItem *mCodeMarkerItem; + Player * mPlayerWidget; + + ViewWidget * mViewWidget; + GraphicsView * mView; + QGraphicsScene * mScene; + ImageItem * mImageItem; + LogoItem * mLogoItem; + CoordItem * mCoordItem; + GridItem * mGridItem; + RecognitionRoiItem * mRecognitionRoiItem; + TrackingRoiItem * mTrackingRoiItem; + TrackerItem * mTrackerItem; + StereoItem * mStereoItem; + ColorMarkerItem * mColorMarkerItem; + CodeMarkerItem * mCodeMarkerItem; MultiColorMarkerItem *mMultiColorMarkerItem; - BackgroundItem *mBackgroundItem; - MoCapItem *mMoCapItem; + BackgroundItem * mBackgroundItem; + MoCapItem * mMoCapItem; QDoubleSpinBox *mStatusPosRealHeight; - QLabel *mStatusLabelStereo; - QLabel *mStatusLabelTime; - QLabel *mStatusLabelFPS; - QLabel *mStatusLabelPosReal; - QLabel *mStatusLabelPos; - QLabel *mStatusLabelColor; + QLabel * mStatusLabelStereo; + QLabel * mStatusLabelTime; + QLabel * mStatusLabelFPS; + QLabel * mStatusLabelPosReal; + QLabel * mStatusLabelPos; + QLabel * mStatusLabelColor; QPointF mMousePosOnImage; - Filter *mCalibFilter; + Filter * mCalibFilter; BrightContrastFilter mBrightContrastFilter; - BorderFilter mBorderFilter; - SwapFilter mSwapFilter; - BackgroundFilter mBackgroundFilter; + BorderFilter mBorderFilter; + SwapFilter mSwapFilter; + BackgroundFilter mBackgroundFilter; - AutoCalib mAutoCalib; + AutoCalib mAutoCalib; ExtrCalibration mExtrCalibration; bool mRecognitionChanged; @@ -601,10 +448,10 @@ private: reco::Recognizer mReco; - Tracker *mTracker; + Tracker * mTracker; TrackerReal *mTrackerReal; - double mHeadSize; - double mCmPerPixel; + double mHeadSize; + double mCmPerPixel; QDomDocument mDefaultSettings; @@ -614,17 +461,17 @@ private: bool mAutoTrackOptimizeColor; bool mLoading; - MoCapStorage mStorage; - MoCapController mMoCapController {mStorage, mExtrCalibration}; + MoCapStorage mStorage; + MoCapController mMoCapController{mStorage, mExtrCalibration}; - QString mPetrackVersion{"Unknown"}; ///< Version of PeTrack used to compile - QString mGitCommitID{"Unknown"}; ///< Commit hash used to compile - QString mGitCommitDate{"Unknown"}; ///< Commit date used to compile + QString mPetrackVersion{"Unknown"}; ///< Version of PeTrack used to compile + QString mGitCommitID{"Unknown"}; ///< Commit hash used to compile + QString mGitCommitDate{"Unknown"}; ///< Commit date used to compile QString mGitCommitBranch{"Unknown"}; ///< Branch used to compile - QString mCompileDate{"Unknown"}; ///< Compile date - QString mCompilerID{"Unknown"}; ///< Used compiler + QString mCompileDate{"Unknown"}; ///< Compile date + QString mCompilerID{"Unknown"}; ///< Used compiler QString mCompilerVersion{"Unknown"}; ///< Used compiler version std::vector<std::string> mAuthors; diff --git a/include/player.h b/include/player.h index 004857f922363b3f212091fe3f79363cd25d0a6e..421163ba69320b14df352cbf8a16e84bd38375f3 100644 --- a/include/player.h +++ b/include/player.h @@ -21,8 +21,8 @@ #ifndef PLAYER_H #define PLAYER_H -#include <QWidget> #include <QTemporaryFile> +#include <QWidget> #ifdef AVI #include "aviFile.h" @@ -43,7 +43,8 @@ class QDoubleValidator; class Animation; class Petrack; -enum class PlayerState{ +enum class PlayerState +{ FORWARD, BACKWARD, PAUSE @@ -77,17 +78,17 @@ public slots: bool skipToFrame(int f); bool skipToFrame(); void update(); - void setFPS(double fps=-1.); + void setFPS(double fps = -1.); void togglePlayerSpeedLimited(); void setPlayerSpeedLimited(bool fixed); bool getPlayerSpeedLimited() const; void setPlayerSpeedFixed(bool fixed); void setLooping(bool looping); - void setFrameInNum(int in=-1.); - void setFrameOutNum(int out=-1.); - int getFrameInNum(); - int getFrameOutNum(); - int getPos(); + void setFrameInNum(int in = -1.); + void setFrameOutNum(int out = -1.); + int getFrameInNum(); + int getFrameOutNum(); + int getPos(); void play(PlayerState state); @@ -98,13 +99,13 @@ private: bool backward(); void playVideo(); - Animation *mAnimation; + Animation * mAnimation; QTemporaryFile mTmpFile; - PlayerState mState = PlayerState::PAUSE; - bool mPlayerSpeedLimited; - bool mPlayerSpeedFixed = false; - bool mLooping = false; - bool mRec; + PlayerState mState = PlayerState::PAUSE; + bool mPlayerSpeedLimited; + bool mPlayerSpeedFixed = false; + bool mLooping = false; + bool mRec; #ifdef AVI @@ -112,22 +113,22 @@ private: #else AviFileWriter mAviFile; #endif - - //GUI - QToolButton *mFrameForwardButton, *mFrameBackwardButton, *mPlayForwardButton, *mPlayBackwardButton, *mPauseButton; - QToolButton *mRecButton; - cv::Mat mImg; - QHBoxLayout *mPlayerLayout; - Petrack *mMainWindow; - QSlider *mSlider; - QLineEdit *mFrameNum; - QLineEdit *mFrameInNum; - QLineEdit *mFrameOutNum; - QLineEdit *mFpsNum; - QLabel *mAtLabel; - QLabel *mSourceInLabel; - QLabel *mSourceOutLabel; - QLabel *mFpsLabel; + + // GUI + QToolButton * mFrameForwardButton, *mFrameBackwardButton, *mPlayForwardButton, *mPlayBackwardButton, *mPauseButton; + QToolButton * mRecButton; + cv::Mat mImg; + QHBoxLayout * mPlayerLayout; + Petrack * mMainWindow; + QSlider * mSlider; + QLineEdit * mFrameNum; + QLineEdit * mFrameInNum; + QLineEdit * mFrameOutNum; + QLineEdit * mFpsNum; + QLabel * mAtLabel; + QLabel * mSourceInLabel; + QLabel * mSourceOutLabel; + QLabel * mFpsLabel; QIntValidator *mFrameNumValidator; QIntValidator *mFrameInNumValidator; QIntValidator *mFrameOutNumValidator; diff --git a/include/qtColorTriangle.h b/include/qtColorTriangle.h index 4189ec3d3d1a127996bf9352ad1d3175c8e542df..4661e9600f778e64976962f63a6153c21d0e6447 100644 --- a/include/qtColorTriangle.h +++ b/include/qtColorTriangle.h @@ -49,26 +49,25 @@ #ifndef QTCOLORTRIANGLE_H #define QTCOLORTRIANGLE_H #include <QtGui/QImage> - #include <QtWidgets> class QPointF; struct Vertex; #if defined(Q_WS_WIN) -# if !defined(QT_QTCOLORTRIANGLE_EXPORT) && !defined(QT_QTCOLORTRIANGLE_IMPORT) -# define QT_QTCOLORTRIANGLE_EXPORT -# elif defined(QT_QTCOLORTRIANGLE_IMPORT) -# if defined(QT_QTCOLORTRIANGLE_EXPORT) -# undef QT_QTCOLORTRIANGLE_EXPORT -# endif -# define QT_QTCOLORTRIANGLE_EXPORT __declspec(dllimport) -# elif defined(QT_QTCOLORTRIANGLE_EXPORT) -# undef QT_QTCOLORTRIANGLE_EXPORT -# define QT_QTCOLORTRIANGLE_EXPORT __declspec(dllexport) -# endif +#if !defined(QT_QTCOLORTRIANGLE_EXPORT) && !defined(QT_QTCOLORTRIANGLE_IMPORT) +#define QT_QTCOLORTRIANGLE_EXPORT +#elif defined(QT_QTCOLORTRIANGLE_IMPORT) +#if defined(QT_QTCOLORTRIANGLE_EXPORT) +#undef QT_QTCOLORTRIANGLE_EXPORT +#endif +#define QT_QTCOLORTRIANGLE_EXPORT __declspec(dllimport) +#elif defined(QT_QTCOLORTRIANGLE_EXPORT) +#undef QT_QTCOLORTRIANGLE_EXPORT +#define QT_QTCOLORTRIANGLE_EXPORT __declspec(dllexport) +#endif #else -# define QT_QTCOLORTRIANGLE_EXPORT +#define QT_QTCOLORTRIANGLE_EXPORT #endif class QT_QTCOLORTRIANGLE_EXPORT QtColorTriangle : public QWidget @@ -80,9 +79,9 @@ public: ~QtColorTriangle(); QSize sizeHint() const; - int heightForWidth(int w) const; + int heightForWidth(int w) const; - void polish(); + void polish(); QColor color() const; Q_SIGNALS: @@ -98,38 +97,37 @@ protected: void mouseReleaseEvent(QMouseEvent *); void keyPressEvent(QKeyEvent *e); void resizeEvent(QResizeEvent *); - void drawTrigon(QImage *p, const QPointF &a, const QPointF &b, - const QPointF &c, const QColor &color); + void drawTrigon(QImage *p, const QPointF &a, const QPointF &b, const QPointF &c, const QColor &color); private: - double radiusAt(const QPointF &pos, const QRect &rect) const; - double angleAt(const QPointF &pos, const QRect &rect) const; - QPointF movePointToTriangle(double x, double y, const Vertex &a, - const Vertex &b, const Vertex &c) const; + double radiusAt(const QPointF &pos, const QRect &rect) const; + double angleAt(const QPointF &pos, const QRect &rect) const; + QPointF movePointToTriangle(double x, double y, const Vertex &a, const Vertex &b, const Vertex &c) const; QPointF pointFromColor(const QColor &col) const; - QColor colorFromPoint(const QPointF &p) const; + QColor colorFromPoint(const QPointF &p) const; void genBackground(); - QImage bg; - double a, b, c; + QImage bg; + double a, b, c; QPointF pa, pb, pc, pd; QColor curColor; - int curHue; + int curHue; bool mustGenerateBackground; - int penWidth; - int ellipseSize; + int penWidth; + int ellipseSize; - int outerRadius; + int outerRadius; QPointF selectorPos; - enum SelectionMode { - Idle, - SelectingHue, - SelectingSatValue + enum SelectionMode + { + Idle, + SelectingHue, + SelectingSatValue } selMode; }; diff --git a/include/recognition.h b/include/recognition.h index 3a190d05f460b05814d3cc71e3b9395c52bea2d8..41a14b0fc20039bab680c497c8ac3f2fe9accf2b 100644 --- a/include/recognition.h +++ b/include/recognition.h @@ -21,12 +21,12 @@ #ifndef RECOGNITION_H #define RECOGNITION_H +#include "vector.h" + #include <QList> #include <QObject> #include <opencv2/aruco.hpp> -#include "vector.h" - class TrackPoint; class QRect; class BackgroundFilter; @@ -34,228 +34,270 @@ class Control; class ImageItem; class CodeMarkerItem; -namespace reco { - /** - * Different recognition methods used in PeTrack - * - * Note: be aware that changing the explicitly assigned integer values will break backwards compatibility! - */ - enum class RecognitionMethod +namespace reco +{ +/** + * Different recognition methods used in PeTrack + * + * Note: be aware that changing the explicitly assigned integer values will break backwards compatibility! + */ +enum class RecognitionMethod +{ + Casern = 0, + Hermes = 1, + Stereo = 2, + Color = 3, + Japan = 4, + MultiColor = 5, + Code = 6, +}; + +class ArucoCodeParams +{ + double minMarkerPerimeter = 5; + double maxMarkerPerimeter = 15; + double minCornerDistance = 0.05; + double minMarkerDistance = 0.05; + int adaptiveThreshWinSizeMin = 3; + int adaptiveThreshWinSizeMax = 27; + int adaptiveThreshWinSizeStep = 10; + int adaptiveThreshConstant = 7; + double polygonalApproxAccuracyRate = 0.03; + int minDistanceToBorder = 3; + bool doCornerRefinement = false; + int cornerRefinementWinSize = 5; + int cornerRefinementMaxIterations = 30; + double cornerRefinementMinAccuracy = 0.1; + int markerBorderBits = 1; + int perspectiveRemovePixelPerCell = 4; + double perspectiveRemoveIgnoredMarginPerCell = 0.13; + double maxErroneousBitsInBorderRate = 0.35; + double minOtsuStdDev = 5; + double errorCorrectionRate = 0.6; + +public: + friend inline constexpr bool operator==(const ArucoCodeParams &lhs, const ArucoCodeParams &rhs) noexcept { - Casern = 0, - Hermes = 1, - Stereo = 2, - Color = 3, - Japan = 4, - MultiColor = 5, - Code = 6, - }; - - class ArucoCodeParams { - double minMarkerPerimeter = 5; - double maxMarkerPerimeter = 15; - double minCornerDistance = 0.05; - double minMarkerDistance = 0.05; - int adaptiveThreshWinSizeMin = 3; - int adaptiveThreshWinSizeMax = 27; - int adaptiveThreshWinSizeStep = 10; - int adaptiveThreshConstant = 7; - double polygonalApproxAccuracyRate = 0.03; - int minDistanceToBorder = 3; - bool doCornerRefinement = false; - int cornerRefinementWinSize = 5; - int cornerRefinementMaxIterations = 30; - double cornerRefinementMinAccuracy = 0.1; - int markerBorderBits = 1; - int perspectiveRemovePixelPerCell = 4; - double perspectiveRemoveIgnoredMarginPerCell = 0.13; - double maxErroneousBitsInBorderRate = 0.35; - double minOtsuStdDev = 5; - double errorCorrectionRate = 0.6; - - public: - - friend inline constexpr bool operator==(const ArucoCodeParams & lhs, const ArucoCodeParams & rhs) noexcept - { - return (lhs.minMarkerPerimeter == rhs.minMarkerPerimeter) && ((lhs.maxMarkerPerimeter == rhs.maxMarkerPerimeter) && ((lhs.minCornerDistance == rhs.minCornerDistance) && ((lhs.minMarkerDistance == rhs.minMarkerDistance) && ((lhs.adaptiveThreshWinSizeMin == rhs.adaptiveThreshWinSizeMin) && ((lhs.adaptiveThreshWinSizeMax == rhs.adaptiveThreshWinSizeMax) && ((lhs.adaptiveThreshWinSizeStep == rhs.adaptiveThreshWinSizeStep) && ((lhs.adaptiveThreshConstant == rhs.adaptiveThreshConstant) && ((lhs.polygonalApproxAccuracyRate == rhs.polygonalApproxAccuracyRate) && ((lhs.minDistanceToBorder == rhs.minDistanceToBorder) && ((static_cast<int>(lhs.doCornerRefinement) == static_cast<int>(rhs.doCornerRefinement)) && ((lhs.cornerRefinementWinSize == rhs.cornerRefinementWinSize) && ((lhs.cornerRefinementMaxIterations == rhs.cornerRefinementMaxIterations) && ((lhs.cornerRefinementMinAccuracy == rhs.cornerRefinementMinAccuracy) && ((lhs.markerBorderBits == rhs.markerBorderBits) && ((lhs.perspectiveRemovePixelPerCell == rhs.perspectiveRemovePixelPerCell) && ((lhs.perspectiveRemoveIgnoredMarginPerCell == rhs.perspectiveRemoveIgnoredMarginPerCell) && ((lhs.maxErroneousBitsInBorderRate == rhs.maxErroneousBitsInBorderRate) && ((lhs.minOtsuStdDev == rhs.minOtsuStdDev) && (lhs.errorCorrectionRate == rhs.errorCorrectionRate))))))))))))))))))); - } - friend inline constexpr bool operator!=(const ArucoCodeParams& lhs, const ArucoCodeParams& rhs) + return (lhs.minMarkerPerimeter == rhs.minMarkerPerimeter) && + ((lhs.maxMarkerPerimeter == rhs.maxMarkerPerimeter) && + ((lhs.minCornerDistance == rhs.minCornerDistance) && + ((lhs.minMarkerDistance == rhs.minMarkerDistance) && + ((lhs.adaptiveThreshWinSizeMin == rhs.adaptiveThreshWinSizeMin) && + ((lhs.adaptiveThreshWinSizeMax == rhs.adaptiveThreshWinSizeMax) && + ((lhs.adaptiveThreshWinSizeStep == rhs.adaptiveThreshWinSizeStep) && + ((lhs.adaptiveThreshConstant == rhs.adaptiveThreshConstant) && + ((lhs.polygonalApproxAccuracyRate == rhs.polygonalApproxAccuracyRate) && + ((lhs.minDistanceToBorder == rhs.minDistanceToBorder) && + ((static_cast<int>(lhs.doCornerRefinement) == static_cast<int>(rhs.doCornerRefinement)) && + ((lhs.cornerRefinementWinSize == rhs.cornerRefinementWinSize) && + ((lhs.cornerRefinementMaxIterations == rhs.cornerRefinementMaxIterations) && + ((lhs.cornerRefinementMinAccuracy == rhs.cornerRefinementMinAccuracy) && + ((lhs.markerBorderBits == rhs.markerBorderBits) && + ((lhs.perspectiveRemovePixelPerCell == rhs.perspectiveRemovePixelPerCell) && + ((lhs.perspectiveRemoveIgnoredMarginPerCell == + rhs.perspectiveRemoveIgnoredMarginPerCell) && + ((lhs.maxErroneousBitsInBorderRate == rhs.maxErroneousBitsInBorderRate) && + ((lhs.minOtsuStdDev == rhs.minOtsuStdDev) && + (lhs.errorCorrectionRate == rhs.errorCorrectionRate))))))))))))))))))); + } + friend inline constexpr bool operator!=(const ArucoCodeParams &lhs, const ArucoCodeParams &rhs) + { + return !(lhs == rhs); + } + double getMinMarkerPerimeter() const; + void setMinMarkerPerimeter(double newMinMarkerPerimeter); + double getMaxMarkerPerimeter() const; + void setMaxMarkerPerimeter(double newMaxMarkerPerimeter); + double getMinCornerDistance() const; + void setMinCornerDistance(double newMinCornerDistance); + double getMinMarkerDistance() const; + void setMinMarkerDistance(double newMinMarkerDistance); + int getAdaptiveThreshWinSizeMin() const; + void setAdaptiveThreshWinSizeMin(int newAdaptiveThreshWinSizeMin); + int getAdaptiveThreshWinSizeMax() const; + void setAdaptiveThreshWinSizeMax(int newAdaptiveThreshWinSizeMax); + int getAdaptiveThreshWinSizeStep() const; + void setAdaptiveThreshWinSizeStep(int newAdaptiveThreshWinSizeStep); + int getAdaptiveThreshConstant() const; + void setAdaptiveThreshConstant(int newAdaptiveThreshConstant); + double getPolygonalApproxAccuracyRate() const; + void setPolygonalApproxAccuracyRate(double newPolygonalApproxAccuracyRate); + int getMinDistanceToBorder() const; + void setMinDistanceToBorder(int newMinDistanceToBorder); + bool getDoCornerRefinement() const; + void setDoCornerRefinement(bool newDoCornerRefinement); + int getCornerRefinementWinSize() const; + void setCornerRefinementWinSize(int newCornerRefinementWinSize); + int getCornerRefinementMaxIterations() const; + void setCornerRefinementMaxIterations(int newCornerRefinementMaxIterations); + double getCornerRefinementMinAccuracy() const; + void setCornerRefinementMinAccuracy(double newCornerRefinementMinAccuracy); + int getMarkerBorderBits() const; + void setMarkerBorderBits(int newMarkerBorderBits); + int getPerspectiveRemovePixelPerCell() const; + void setPerspectiveRemovePixelPerCell(int newPerspectiveRemovePixelPerCell); + double getPerspectiveRemoveIgnoredMarginPerCell() const; + void setPerspectiveRemoveIgnoredMarginPerCell(double newPerspectiveRemoveIgnoredMarginPerCell); + double getMaxErroneousBitsInBorderRate() const; + void setMaxErroneousBitsInBorderRate(double newMaxErroneousBitsInBorderRate); + double getMinOtsuStdDev() const; + void setMinOtsuStdDev(double newMinOtsuStdDev); + double getErrorCorrectionRate() const; + void setErrorCorrectionRate(double newErrorCorrectionRate); +}; + + +class CodeMarkerOptions : public QObject +{ + Q_OBJECT + +private: + CodeMarkerItem *codeMarkerItem; + int indexOfMarkerDict = 16; + + ArucoCodeParams detectorParams; + + Control *controlWidget; + Vec2F offsetCropRect2Roi = Vec2F{0, 0}; + +public: + // TODO: Remove getter and setter for pointers; + // cannot properly set these in constructor because of + // bidirectional dependecies + CodeMarkerItem *getCodeMarkerItem() const { return codeMarkerItem; } + Control * getControlWidget() const { return controlWidget; } + ArucoCodeParams getDetectorParams() const { return detectorParams; } + int getIndexOfMarkerDict() const { return indexOfMarkerDict; } + +public: + void setCodeMarkerItem(CodeMarkerItem *item) { codeMarkerItem = item; } + void setControlWidget(Control *control) { controlWidget = control; } + void setDetectorParams(ArucoCodeParams params); + void setIndexOfMarkerDict(int idx); + + const Vec2F &getOffsetCropRect2Roi() const; + void setOffsetCropRect2Roi(const Vec2F &newOffsetCropRect2Roi); + +signals: + void detectorParamsChanged(); + void indexOfMarkerDictChanged(); +}; + +class Recognizer : public QObject +{ + Q_OBJECT + +private: + // TODO add options for each marker type + CodeMarkerOptions mCodeMarkerOptions; + + // default multicolor marker (until 11/2016 hermes marker) + RecognitionMethod mRecoMethod = RecognitionMethod::MultiColor; + +public: + QList<TrackPoint> + getMarkerPos(cv::Mat &img, QRect &roi, Control *controlWidget, int borderSize, BackgroundFilter *bgFilter); + + RecognitionMethod getRecoMethod() const { return mRecoMethod; } + CodeMarkerOptions &getCodeMarkerOptions() { return mCodeMarkerOptions; } + +public slots: + void userChangedRecoMethod(RecognitionMethod method) + { + if(method != mRecoMethod) { - return !(lhs == rhs); + mRecoMethod = method; + emit recoMethodChanged(mRecoMethod); } - double getMinMarkerPerimeter() const; - void setMinMarkerPerimeter(double newMinMarkerPerimeter); - double getMaxMarkerPerimeter() const; - void setMaxMarkerPerimeter(double newMaxMarkerPerimeter); - double getMinCornerDistance() const; - void setMinCornerDistance(double newMinCornerDistance); - double getMinMarkerDistance() const; - void setMinMarkerDistance(double newMinMarkerDistance); - int getAdaptiveThreshWinSizeMin() const; - void setAdaptiveThreshWinSizeMin(int newAdaptiveThreshWinSizeMin); - int getAdaptiveThreshWinSizeMax() const; - void setAdaptiveThreshWinSizeMax(int newAdaptiveThreshWinSizeMax); - int getAdaptiveThreshWinSizeStep() const; - void setAdaptiveThreshWinSizeStep(int newAdaptiveThreshWinSizeStep); - int getAdaptiveThreshConstant() const; - void setAdaptiveThreshConstant(int newAdaptiveThreshConstant); - double getPolygonalApproxAccuracyRate() const; - void setPolygonalApproxAccuracyRate(double newPolygonalApproxAccuracyRate); - int getMinDistanceToBorder() const; - void setMinDistanceToBorder(int newMinDistanceToBorder); - bool getDoCornerRefinement() const; - void setDoCornerRefinement(bool newDoCornerRefinement); - int getCornerRefinementWinSize() const; - void setCornerRefinementWinSize(int newCornerRefinementWinSize); - int getCornerRefinementMaxIterations() const; - void setCornerRefinementMaxIterations(int newCornerRefinementMaxIterations); - double getCornerRefinementMinAccuracy() const; - void setCornerRefinementMinAccuracy(double newCornerRefinementMinAccuracy); - int getMarkerBorderBits() const; - void setMarkerBorderBits(int newMarkerBorderBits); - int getPerspectiveRemovePixelPerCell() const; - void setPerspectiveRemovePixelPerCell(int newPerspectiveRemovePixelPerCell); - double getPerspectiveRemoveIgnoredMarginPerCell() const; - void setPerspectiveRemoveIgnoredMarginPerCell(double newPerspectiveRemoveIgnoredMarginPerCell); - double getMaxErroneousBitsInBorderRate() const; - void setMaxErroneousBitsInBorderRate(double newMaxErroneousBitsInBorderRate); - double getMinOtsuStdDev() const; - void setMinOtsuStdDev(double newMinOtsuStdDev); - double getErrorCorrectionRate() const; - void setErrorCorrectionRate(double newErrorCorrectionRate); - }; - - - class CodeMarkerOptions : public QObject{ - Q_OBJECT - - private: - CodeMarkerItem *codeMarkerItem; - int indexOfMarkerDict = 16; - - ArucoCodeParams detectorParams; - - Control *controlWidget; - Vec2F offsetCropRect2Roi = Vec2F{0,0}; + } - public: - // TODO: Remove getter and setter for pointers; - // cannot properly set these in constructor because of - // bidirectional dependecies - CodeMarkerItem *getCodeMarkerItem() const {return codeMarkerItem;} - Control *getControlWidget() const {return controlWidget;} - ArucoCodeParams getDetectorParams() const {return detectorParams;} - int getIndexOfMarkerDict() const {return indexOfMarkerDict;} +signals: + void recoMethodChanged(RecognitionMethod method); +}; - public: - void setCodeMarkerItem(CodeMarkerItem *item) {codeMarkerItem = item;} - void setControlWidget(Control *control) {controlWidget = control;} - void setDetectorParams(ArucoCodeParams params); - void setIndexOfMarkerDict(int idx); +// berechnet pixelverschiebung aufgrund von schraegsicht bei einem farbmarker +// Maik Dissertation Seite 138 +// boxImageCentre ohne Border +Vec2F autoCorrectColorMarker(Vec2F &boxImageCentre, Control *controlWidget); - const Vec2F &getOffsetCropRect2Roi() const; - void setOffsetCropRect2Roi(const Vec2F &newOffsetCropRect2Roi); - signals: - void detectorParamsChanged(); - void indexOfMarkerDictChanged(); +namespace detail +{ + struct ColorBlob + { + cv::RotatedRect box; ///< bounding box + Vec2F imageCenter; ///< Center in whole image (instead of ROI) + QColor color; ///< color of detected blob + std::vector<cv::Point> contour; ///< detected contour + double maxExpansion; ///< length of longer side of bounding rect }; - class Recognizer : public QObject + struct ColorBlobDetectionParams { - Q_OBJECT - - private: - // TODO add options for each marker type - CodeMarkerOptions mCodeMarkerOptions; - - // default multicolor marker (until 11/2016 hermes marker) - RecognitionMethod mRecoMethod = RecognitionMethod::MultiColor; - public: - QList<TrackPoint> getMarkerPos(cv::Mat &img, QRect &roi, Control *controlWidget, int borderSize, BackgroundFilter *bgFilter); - - RecognitionMethod getRecoMethod() const {return mRecoMethod;} - CodeMarkerOptions& getCodeMarkerOptions() {return mCodeMarkerOptions;} + QColor fromColor; ///< from color of the colormap + QColor toColor; ///< to color of the colormap + bool invHue = false; ///< flag indicating if hue should be inverted (for red-ish colors) + bool useOpen = true; ///< should open-operation be used + bool useClose = true; ///< should close-operation be used + int radiusOpen = 5; ///< radius of open-kernel + int radiusClose = 5; ///< radius of close-kernel + int minArea = 1000; ///< min area of the contour + int maxArea = 5000; ///< max area of the contour + Vec2F offset; ///< offset of ROI to image + double maxRatio = 2; ///< maximum allowed ratio of sides for bounding rect + cv::Mat img; ///< img in which to detect the blobs + cv::Mat binary; ///< img for the binary mask + }; - public slots: - void userChangedRecoMethod(RecognitionMethod method) - { - if(method != mRecoMethod) - { - mRecoMethod = method; - emit recoMethodChanged(mRecoMethod); - } - } + struct BlackDotOptions + { + int borderSize = 0; ///< size of border from borderFilter + bool restrictPosition = + false; ///< should the position of the black dot be restricted (see restrictPositionBlackDot()) + bool ignoreWithoutMarker = true; ///< should markers without dot be ignored? + bool autoCorrect = false; ///< should perspective correction be performed + bool autoCorrectOnlyExport = + false; ///< should perspective correction only be performed when exporting trajectories + ImageItem *imageItem = nullptr; ///< used for getAngleToGround and such + QColor midHue; ///< middle hue of the color map + double dotSize = 5; ///< size of the black dot + Control * controlWidget = nullptr; ///< pointer to Control used for autoCorrect + }; - signals: - void recoMethodChanged(RecognitionMethod method); + struct ArucoOptions + { + Control *controlWidget = nullptr; ///< pointer to Control used for autoCorrect + bool ignoreWithoutMarker = true; ///< should a blob without valid arucoMarker be ignored + bool autoCorrect = false; ///< should perspective correction be performed + bool autoCorrectOnlyExport = + false; ///< should perspective correction only be performed when exporting trajectories + RecognitionMethod method = + RecognitionMethod::Code; ///< Used recognition method; could be called from findMulticolorMarker + CodeMarkerOptions &codeOpt; }; - // berechnet pixelverschiebung aufgrund von schraegsicht bei einem farbmarker - // Maik Dissertation Seite 138 - // boxImageCentre ohne Border - Vec2F autoCorrectColorMarker(Vec2F &boxImageCentre, Control *controlWidget); - - - namespace detail { - struct ColorBlob{ - cv::RotatedRect box; ///< bounding box - Vec2F imageCenter; ///< Center in whole image (instead of ROI) - QColor color; ///< color of detected blob - std::vector<cv::Point> contour; ///< detected contour - double maxExpansion; ///< length of longer side of bounding rect - }; - - struct ColorBlobDetectionParams{ - QColor fromColor; ///< from color of the colormap - QColor toColor; ///< to color of the colormap - bool invHue = false; ///< flag indicating if hue should be inverted (for red-ish colors) - bool useOpen = true; ///< should open-operation be used - bool useClose = true; ///< should close-operation be used - int radiusOpen = 5; ///< radius of open-kernel - int radiusClose = 5; ///< radius of close-kernel - int minArea = 1000; ///< min area of the contour - int maxArea = 5000; ///< max area of the contour - Vec2F offset; ///< offset of ROI to image - double maxRatio = 2; ///< maximum allowed ratio of sides for bounding rect - cv::Mat img; ///< img in which to detect the blobs - cv::Mat binary; ///< img for the binary mask - }; - - struct BlackDotOptions - { - int borderSize = 0; ///< size of border from borderFilter - bool restrictPosition = - false; ///< should the position of the black dot be restricted (see restrictPositionBlackDot()) - bool ignoreWithoutMarker = true; ///< should markers without dot be ignored? - bool autoCorrect = false; ///< should perspective correction be performed - bool autoCorrectOnlyExport = false; ///< should perspective correction only be performed when exporting trajectories - ImageItem *imageItem = nullptr; ///< used for getAngleToGround and such - QColor midHue; ///< middle hue of the color map - double dotSize = 5; ///< size of the black dot - Control * controlWidget = nullptr; ///< pointer to Control used for autoCorrect - }; - - struct ArucoOptions - { - Control *controlWidget = nullptr; ///< pointer to Control used for autoCorrect - bool ignoreWithoutMarker = true; ///< should a blob without valid arucoMarker be ignored - bool autoCorrect = false; ///< should perspective correction be performed - bool autoCorrectOnlyExport = false; ///< should perspective correction only be performed when exporting trajectories - RecognitionMethod method = RecognitionMethod::Code; ///< Used recognition method; could be called from findMulticolorMarker - CodeMarkerOptions& codeOpt; - }; - - std::vector<ColorBlob> findColorBlob(const ColorBlobDetectionParams &options); - void restrictPositionBlackDot(ColorBlob& blob, ImageItem *imageItem, int bS, cv::Rect& cropRect); - cv::Mat customBgr2Gray(const cv::Mat& subImg, const QColor& midHue); - void refineWithBlackDot(std::vector<ColorBlob>& blobs, const cv::Mat& img, QList<TrackPoint>& crossList, const BlackDotOptions& options); - void refineWithAruco(std::vector<ColorBlob> &blobs, const cv::Mat& img, QList<TrackPoint> &crossList, ArucoOptions& options); - - void findCodeMarker(cv::Mat &img, QList<TrackPoint> &crossList, RecognitionMethod recoMethod, const CodeMarkerOptions &opt); - cv::Ptr<cv::aruco::Dictionary> getDictMip36h12(); - } -} + std::vector<ColorBlob> findColorBlob(const ColorBlobDetectionParams &options); + void restrictPositionBlackDot(ColorBlob &blob, ImageItem *imageItem, int bS, cv::Rect &cropRect); + cv::Mat customBgr2Gray(const cv::Mat &subImg, const QColor &midHue); + void refineWithBlackDot( + std::vector<ColorBlob> &blobs, + const cv::Mat & img, + QList<TrackPoint> & crossList, + const BlackDotOptions & options); + void refineWithAruco( + std::vector<ColorBlob> &blobs, + const cv::Mat & img, + QList<TrackPoint> & crossList, + ArucoOptions & options); + + void findCodeMarker( + cv::Mat & img, + QList<TrackPoint> & crossList, + RecognitionMethod recoMethod, + const CodeMarkerOptions &opt); + cv::Ptr<cv::aruco::Dictionary> getDictMip36h12(); +} // namespace detail +} // namespace reco Q_DECLARE_METATYPE(reco::RecognitionMethod) #endif diff --git a/include/recognitionRoiItem.h b/include/recognitionRoiItem.h index 40230532841da37608dec3732572a06a617f4702..9069c237bb79547f747ef54668f8270c95d8705b 100644 --- a/include/recognitionRoiItem.h +++ b/include/recognitionRoiItem.h @@ -30,20 +30,31 @@ class Control; class RecognitionRoiItem : public QGraphicsRectItem { inline static constexpr int DISTANCE_TO_BORDER = 5; - inline static constexpr int MIN_SIZE = 10; - enum pressLocation{inside, top, bottom, left, right, topLeft, topRight, bottomLeft, bottomRight}; + inline static constexpr int MIN_SIZE = 10; + enum pressLocation + { + inside, + top, + bottom, + left, + right, + topLeft, + topRight, + bottomLeft, + bottomRight + }; private: - Petrack *mMainWindow; - Control *mControlWidget; - QRect mPressRect; - QPointF mPressPos; + Petrack * mMainWindow; + Control * mControlWidget; + QRect mPressRect; + QPointF mPressPos; enum pressLocation mPressLocation; public: - RecognitionRoiItem(QWidget *wParent, QGraphicsItem * parent = nullptr); - void mousePressEvent(QGraphicsSceneMouseEvent * event); - void mouseReleaseEvent(QGraphicsSceneMouseEvent * event); + RecognitionRoiItem(QWidget *wParent, QGraphicsItem *parent = nullptr); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void hoverMoveEvent(QGraphicsSceneHoverEvent *event); void checkRect(); diff --git a/include/skeletonTree.h b/include/skeletonTree.h index 28d666f01eee5fbcf146aeb686ebdb7506219f8b..703c613b4516c9e9a9fc45518804eb80c01d43fa 100644 --- a/include/skeletonTree.h +++ b/include/skeletonTree.h @@ -19,15 +19,16 @@ */ #ifndef SKELETONTREE_H #define SKELETONTREE_H -#include <cstdint> -#include <string> -#include <stdexcept> +#include "vector.h" + #include <algorithm> +#include <cstdint> +#include <memory> #include <opencv2/core/matx.hpp> #include <opencv2/core/types.hpp> +#include <stdexcept> +#include <string> #include <vector> -#include <memory> -#include "vector.h" /** * @brief A node of the SkeletonTree class. @@ -39,19 +40,18 @@ * This class is used by @see SkeletonTree * **/ -class SkeletonNode{ - +class SkeletonNode +{ public: + SkeletonNode(const uint8_t &id, cv::Point3f point); - SkeletonNode(const uint8_t& id, cv::Point3f point); - - SkeletonNode(const SkeletonNode& rhs) = default; - SkeletonNode(SkeletonNode&& rhs) = default; + SkeletonNode(const SkeletonNode &rhs) = default; + SkeletonNode(SkeletonNode &&rhs) = default; ~SkeletonNode() = default; - SkeletonNode& operator=(const SkeletonNode& rhs) = default; - SkeletonNode& operator=(SkeletonNode&& rhs) = default; + SkeletonNode &operator=(const SkeletonNode &rhs) = default; + SkeletonNode &operator=(SkeletonNode &&rhs) = default; /** * @brief Gets the children as a vector. @@ -60,7 +60,7 @@ public: * * @return A reference to a vector containing the children. */ - inline std::vector<SkeletonNode>& getChildren() {return mChildren;} + inline std::vector<SkeletonNode> &getChildren() { return mChildren; } /** * @brief Gets the children as a vector. @@ -68,35 +68,33 @@ public: * * @return A const reference to a vector containing the children. */ - inline const std::vector<SkeletonNode>& getChildren() const {return mChildren;} + inline const std::vector<SkeletonNode> &getChildren() const { return mChildren; } /** - * @brief Gets a const reference to the child with the specified memory index. This method is bounds checked. - * This method gets the child by the specified memory index. Children are stored sequentially in memory. - * If the index is out of range a std::out_of_range is thrown. - * @param[in] index The index of the child to be retrieved. - * - * @return A const reference to the child at the memory location. - * @throw std::out_of_range - */ - const SkeletonNode &getChild(size_t index) const { - return mChildren.at(index); - } + * @brief Gets a const reference to the child with the specified memory index. This method is bounds checked. + * This method gets the child by the specified memory index. Children are stored sequentially in memory. + * If the index is out of range a std::out_of_range is thrown. + * @param[in] index The index of the child to be retrieved. + * + * @return A const reference to the child at the memory location. + * @throw std::out_of_range + */ + const SkeletonNode &getChild(size_t index) const { return mChildren.at(index); } - const SkeletonNode& getChildById(uint8_t id) const; + const SkeletonNode &getChildById(uint8_t id) const; /** * @brief Gets the id of the node. * @return The id of the node. */ - inline uint8_t getId() const {return mId;} + inline uint8_t getId() const { return mId; } /** * @brief Gets the number of children. * @return The number of children. */ - inline size_t getChildrenCount() const {return mChildren.size();} + inline size_t getChildrenCount() const { return mChildren.size(); } /** * @brief Makes a node a child. @@ -107,7 +105,8 @@ public: * * @throw std::bad_alloc */ - inline SkeletonNode& addChild(const SkeletonNode& node) { + inline SkeletonNode &addChild(const SkeletonNode &node) + { mChildren.push_back(node); return mChildren.back(); } @@ -116,13 +115,14 @@ public: * @brief Makes a node the child using move semantics. * Appends the node to the list of children. There are no checks for correctness or uniqueness. * This method is there to allow for move optimizations. - * @param[in] node The node to be parented. + * @param[in] node The node to be parented. * * @return The added node. * * @throw std::bad_alloc */ - inline SkeletonNode& addChild(SkeletonNode&& node) { + inline SkeletonNode &addChild(SkeletonNode &&node) + { mChildren.push_back(std::move(node)); return mChildren.back(); } @@ -132,21 +132,20 @@ public: * * @return The position of the node. */ - inline cv::Point3f getPos() const {return mPoint;} + inline cv::Point3f getPos() const { return mPoint; } private: - uint8_t mId; /**< An identifier for the node. */ - cv::Point3f mPoint; /**< Position of the node. */ + uint8_t mId; /**< An identifier for the node. */ + cv::Point3f mPoint; /**< Position of the node. */ std::vector<SkeletonNode> mChildren; /**< A vector containing the child nodes of this node.*/ - - }; -struct SkeletonLine{ +struct SkeletonLine +{ cv::Point3f start; - uint8_t start_id; + uint8_t start_id; cv::Point3f end; - uint8_t end_id; + uint8_t end_id; }; /** @@ -161,21 +160,15 @@ struct SkeletonLine{ class SkeletonTree { - - static void recurseSkeleton(const SkeletonNode& node, std::vector<SkeletonLine>& lines); + static void recurseSkeleton(const SkeletonNode &node, std::vector<SkeletonLine> &lines); public: - /** * @brief Constructor for the Skeleton. * @param[in] root The root node for the Skeleton. * @param[in] dir The direction the head is facing. The vector will be normalized. */ - SkeletonTree(SkeletonNode root, const Vec3F& dir) - : mRoot(std::move(root)), mHeadDir(dir) - { - mHeadDir.normalize(); - } + SkeletonTree(SkeletonNode root, const Vec3F &dir) : mRoot(std::move(root)), mHeadDir(dir) { mHeadDir.normalize(); } /** * @brief Moving constructor for the Skeleton. @@ -185,11 +178,7 @@ public: * @param[in] root The root node as a r-value. * @param[in] dir The direction the head is facing in as a r-value */ - SkeletonTree(SkeletonNode&& root, Vec3F&& dir) - : mRoot(root), mHeadDir(dir) - { - mHeadDir.normalize(); - } + SkeletonTree(SkeletonNode &&root, Vec3F &&dir) : mRoot(root), mHeadDir(dir) { mHeadDir.normalize(); } std::vector<SkeletonLine> getLines() const; @@ -198,14 +187,14 @@ public: * * @return The root node of the skeleton as a reference. */ - inline SkeletonNode& getRoot() {return mRoot;} + inline SkeletonNode &getRoot() { return mRoot; } /** * @brief Gets the root node of the skeleton as a const reference. * * @return The root node of the skeleton as a const reference. */ - inline const SkeletonNode& getRoot() const {return mRoot;} + inline const SkeletonNode &getRoot() const { return mRoot; } /** * @brief Gets the direction of the head. @@ -213,16 +202,12 @@ public: * * @return The normalized direction of the head. */ - inline const Vec3F& getHeadDir() const { - return mHeadDir; - } + inline const Vec3F &getHeadDir() const { return mHeadDir; } private: - SkeletonNode mRoot; /**< Root node of the skeleton. */ - Vec3F mHeadDir; /**< Direction the head is facing to. This value is normalized. */ - + SkeletonNode mRoot; /**< Root node of the skeleton. */ + Vec3F mHeadDir; /**< Direction the head is facing to. This value is normalized. */ }; - #endif // SKELETONTREE_H diff --git a/include/skeletonTreeFactory.h b/include/skeletonTreeFactory.h index 29bdc263a7181160f4e7b816b8c131c8ebb4899f..d0fff5574a00e4827cde87780c8501de71393a2b 100644 --- a/include/skeletonTreeFactory.h +++ b/include/skeletonTreeFactory.h @@ -21,9 +21,10 @@ #ifndef SKELETONTREE_FACTORY_H #define SKELETONTREE_FACTORY_H -#include <opencv2/core/types.hpp> #include "skeletonTree.h" +#include <opencv2/core/types.hpp> + /** * @brief This struct defines all the points needed to construct a skeleton from a person. * @@ -33,7 +34,8 @@ * @see SkeletonTreeFactory * @see SkeletonTree **/ -struct XSenseStruct{ +struct XSenseStruct +{ cv::Point3f mRoot; /***< pSacrum used as sacrum and root. Id is 0. */ cv::Point3f mNeck; /**< pC7SpinalProcess used as atlas bone. Id is 1. */ @@ -46,14 +48,14 @@ struct XSenseStruct{ cv::Point3f mElbowR; /**< pRightOlecranon used as right elbow. Id is 8. */ cv::Point3f mElbowL; /**< pLeftOlecranon used as left elbow. Id is 4. */ - cv::Point3f mWristR; /**< pRightStyloid used as right wrist. Id is 9. */ - cv::Point3f mWristL; /**< pLeftStyloid used as left wrist. Id is 5. */ + cv::Point3f mWristR; /**< pRightStyloid used as right wrist. Id is 9. */ + cv::Point3f mWristL; /**< pLeftStyloid used as left wrist. Id is 5. */ cv::Point3f mHandR; /**< pRightTopOfHand used as the right hand. Id is 10. */ cv::Point3f mHandL; /**< pLeftTopOfHand used as the left hand. Id is 6.*/ - cv::Point3f mHipR; /**< pRightIschialTub used as the right hip. Id is 15. */ - cv::Point3f mHipL; /**< pLeftIschialTub used as the left hip. Id is 11. */ + cv::Point3f mHipR; /**< pRightIschialTub used as the right hip. Id is 15. */ + cv::Point3f mHipL; /**< pLeftIschialTub used as the left hip. Id is 11. */ cv::Point3f mKneeR; /**< pRightPatella used as the right knee. Id is 16. */ cv::Point3f mKneeL; /**< pLeftPatella used as the left knee. Id is 12. */ @@ -75,9 +77,10 @@ struct XSenseStruct{ * Using that struct as a parameter the generateTree can be overloaded. * @see SkeletonTree **/ -class SkeletonTreeFactory{ +class SkeletonTreeFactory +{ public: - static SkeletonTree generateTree(const XSenseStruct& points); + static SkeletonTree generateTree(const XSenseStruct &points); }; #endif diff --git a/include/stereoAviFile.h b/include/stereoAviFile.h index 74df05550bf074972a1f49a712b7714fb14581f9..42c57a63922caa932e3db252c58f67d1ac49cbc7 100644 --- a/include/stereoAviFile.h +++ b/include/stereoAviFile.h @@ -28,7 +28,6 @@ //============================================================================= - //============================================================================= // Project Includes //============================================================================= @@ -37,7 +36,12 @@ //#include <highgui.h> #include "opencv2/opencv.hpp" -enum Camera {cameraLeft, cameraRight, cameraUnset}; +enum Camera +{ + cameraLeft, + cameraRight, + cameraUnset +}; /** * A simple wrapper for the .AVI file interface. @@ -47,93 +51,90 @@ enum Camera {cameraLeft, cameraRight, cameraUnset}; class StereoAviFile { public: - /** Default constructor. */ - StereoAviFile(); + /** Default constructor. */ + StereoAviFile(); - /** Default destructor. */ - virtual ~StereoAviFile(); + /** Default destructor. */ + virtual ~StereoAviFile(); - /** Open an .avi file for reading. */ - bool open(const char* pszFilename, IplImage* stereoImgLeft, IplImage* stereoImgRight); + /** Open an .avi file for reading. */ + bool open(const char *pszFilename, IplImage *stereoImgLeft, IplImage *stereoImgRight); -// /** -// * Read the next frame from the avi stream. File must have been opened for -// * reading. -// * -// * @return false if read error, or last frame, true on success. -// * @bug Need a better return value. -// */ -// bool readNextFrame(); + // /** + // * Read the next frame from the avi stream. File must have been opened for + // * reading. + // * + // * @return false if read error, or last frame, true on success. + // * @bug Need a better return value. + // */ + // bool readNextFrame(); - IplImage* getFrame(enum Camera camera); + IplImage *getFrame(enum Camera camera); - // return iplImage for using in openCV - IplImage* readFrame(int index); + // return iplImage for using in openCV + IplImage *readFrame(int index); - /** Close the .avi file. This is also done by the destructor. */ - bool close(); + /** Close the .avi file. This is also done by the destructor. */ + bool close(); -// /* -// * Converts the error to a string a posts a message. -// * -// * @param hrErr The resulting error. -// */ -// void errorToString( HRESULT hrErr ); + // /* + // * Converts the error to a string a posts a message. + // * + // * @param hrErr The resulting error. + // */ + // void errorToString( HRESULT hrErr ); - enum Camera getCamera(); + enum Camera getCamera(); - void setCamera(enum Camera); + void setCamera(enum Camera); - // from here up the var were protected before + // from here up the var were protected before - /** Height, in pixels, of each frame in the .avi. */ - int m_iRows; + /** Height, in pixels, of each frame in the .avi. */ + int m_iRows; - /** Width, in pixels, of each frame in the .avi. */ - int m_iCols; + /** Width, in pixels, of each frame in the .avi. */ + int m_iCols; - /** Bits per pixel of the .avi. */ - int m_iBPP; + /** Bits per pixel of the .avi. */ + int m_iBPP; protected: + enum Camera mCamera; - enum Camera mCamera; + /** Row increment, in bytes. */ + int m_iRowInc; - /** Row increment, in bytes. */ - int m_iRowInc; + /** Image size in bytes. */ + int m_iSize; - /** Image size in bytes. */ - int m_iSize; + /** Time index for current frame. */ + int m_iTimeIndex; - /** Time index for current frame. */ - int m_iTimeIndex; + /** Temporary image buffer. */ + unsigned char *m_pTempBuffer; - /** Temporary image buffer. */ - unsigned char* m_pTempBuffer; + // iplImage for use with openCV + // IplImage* mImage; + IplImage *mImageLeft; + IplImage *mImageRight; - // iplImage for use with openCV - //IplImage* mImage; - IplImage* mImageLeft; - IplImage* mImageRight; + // /** Temporary buffer for saving .bmps. */ + // unsigned char* m_pTempBMPBuffer; + // + // /** Our bitmapinfo structure */ + // BITMAPINFO* m_pBitmapInfo; -// /** Temporary buffer for saving .bmps. */ -// unsigned char* m_pTempBMPBuffer; -// -// /** Our bitmapinfo structure */ -// BITMAPINFO* m_pBitmapInfo; - -// /** avi file name */ -// char m_szAVIDestFile[ _MAX_PATH ]; + // /** avi file name */ + // char m_szAVIDestFile[ _MAX_PATH ]; private: + /** Read the opened AVI-File */ + // VideoCapture m_vcReader; + CvCapture *m_vcReader; - /** Read the opened AVI-File */ - //VideoCapture m_vcReader; - CvCapture* m_vcReader; - - /** Writes to the opened AVI-File */ - //VideoWriter m_vcWriter; - + /** Writes to the opened AVI-File */ + // VideoWriter m_vcWriter; }; #endif // STEREOAVIFILE_H diff --git a/include/stereoContext.h b/include/stereoContext.h index 3a5550f6d9370b56ed6072473a794809cc9fdc3b..83b99a3cabd937fa9a21cf569b0a9b53007248ed 100644 --- a/include/stereoContext.h +++ b/include/stereoContext.h @@ -28,29 +28,35 @@ #endif #ifdef STEREO -#include "opencv2/calib3d/calib3d_c.h" #include "opencv2/calib3d.hpp" +#include "opencv2/calib3d/calib3d_c.h" #include "pgrAviFile.h" #else #include "stereoAviFile.h" #endif -#include "opencv2/calib3d/calib3d_c.h" #include "opencv2/calib3d.hpp" +#include "opencv2/calib3d/calib3d_c.h" class Petrack; class Animation; class BackgroundFilter; /* Namespace to stop multiple definition problem of Class StereoContext in Petrack and Triclops-Library */ -namespace pet{ - -enum stereoStatus {clean=0, buildInput=1, preprocessed=2, rectified=4, genDisparity=8}; +namespace pet +{ +enum stereoStatus +{ + clean = 0, + buildInput = 1, + preprocessed = 2, + rectified = 4, + genDisparity = 8 +}; class StereoContext { public: - - StereoContext(Petrack* main); + StereoContext(Petrack *main); ~StereoContext(); @@ -61,16 +67,13 @@ public: void preprocess(); #ifndef STEREO_DISABLED - IplImage *getRectified(enum Camera camera=cameraRight); + IplImage *getRectified(enum Camera camera = cameraRight); IplImage *getDisparity(bool *dispNew = nullptr); #endif // von person.cpp benoetigt, um frame nummer zu erhalten - inline Animation *getAnimation() - { - return mAnimation; - } + inline Animation *getAnimation() { return mAnimation; } // --------------------------------------------------- @@ -81,9 +84,9 @@ public: void indicateNewValues(); - bool getXYZ(int row, int col, float* x, float* y, float* z); + bool getXYZ(int row, int col, float *x, float *y, float *z); - bool getMedianXYZaround(int col, int row, float* x, float* y, float* z); + bool getMedianXYZaround(int col, int row, float *x, float *y, float *z); float getZfromDisp(unsigned short int disp); @@ -91,78 +94,56 @@ public: // --------------------------------------------------- #ifdef STEREO - inline TriclopsContext getContext() - { - return mTriclopsContext; - } + inline TriclopsContext getContext() { return mTriclopsContext; } #endif - inline unsigned char getSurfaceValue() const - { - return mSurfaceValue; - } - inline unsigned char getBackForthValue() const - { - return mBackForthValue; - } + inline unsigned char getSurfaceValue() const { return mSurfaceValue; } + inline unsigned char getBackForthValue() const { return mBackForthValue; } - inline unsigned short int getMin() const - { - return mMin; - } - inline unsigned short int getMax() const - { - return mMax; - } + inline unsigned short int getMin() const { return mMin; } + inline unsigned short int getMax() const { return mMax; } - inline void addStatus(enum stereoStatus s) - { - mStatus |= s; - } + inline void addStatus(enum stereoStatus s) { mStatus |= s; } inline void setStatus(enum stereoStatus s) // set status up to this level { - mStatus = s*2-1; - } - inline void resetStatus() - { - mStatus = clean; + mStatus = s * 2 - 1; } + inline void resetStatus() { mStatus = clean; } - CvMat* getPointCloud(); + CvMat *getPointCloud(); bool exportPointCloud(QString dest = ""); protected: - - Animation *mAnimation; - Petrack *mMain; + Animation *mAnimation; + Petrack * mMain; #ifdef STEREO - TriclopsContext mTriclopsContext; - TriclopsInput mTriclopsInput; - TriclopsImage mTriRectLeft; - TriclopsImage mTriRectRight; - TriclopsImage16 mTriDisparity; + TriclopsContext mTriclopsContext; + TriclopsInput mTriclopsInput; + TriclopsImage mTriRectLeft; + TriclopsImage mTriRectRight; + TriclopsImage16 mTriDisparity; #endif - BackgroundFilter *mBackgroundFilterLeft; - BackgroundFilter *mBackgroundFilterRight; + BackgroundFilter *mBackgroundFilterLeft; + BackgroundFilter *mBackgroundFilterRight; #ifndef STEREO_DISABLED - IplImage mRectLeft; - IplImage mRectRight; - IplImage mDisparity; - CvStereoBMState *mBMState; + IplImage mRectLeft; + IplImage mRectRight; + IplImage mDisparity; + CvStereoBMState *mBMState; #endif - cv::Ptr<cv::StereoSGBM> mSgbm; - CvMat *mBMdisparity16; - CvMat *mPointCloud; - unsigned char mSurfaceValue; - unsigned char mBackForthValue; - unsigned short int mMin; - unsigned short int mMax; - short int mStatus; + cv::Ptr<cv::StereoSGBM> mSgbm; + CvMat * mBMdisparity16; + CvMat * mPointCloud; + unsigned char mSurfaceValue; + unsigned char mBackForthValue; + unsigned short int mMin; + unsigned short int mMax; + short int mStatus; }; -} +} // namespace pet #endif // #ifndef STEREOCONTEXT diff --git a/include/stereoItem.h b/include/stereoItem.h index 4c241b48cb3b96a10a6885bdaf10b81c07faf3ce..afec91ddc4e6aca34da4756913ac65bc79d16134 100644 --- a/include/stereoItem.h +++ b/include/stereoItem.h @@ -21,27 +21,27 @@ #ifndef STEREOITEM_H #define STEREOITEM_H -#include <QGraphicsItem> - #include "petrack.h" +#include <QGraphicsItem> + class StereoItem : public QGraphicsItem { private: Petrack *mMainWindow; - QImage *mImage; - bool mDispNew; // indicates that a new disparity has been generated after the last drawing + QImage * mImage; + bool mDispNew; // indicates that a new disparity has been generated after the last drawing public: - StereoItem(QWidget *wParent, QGraphicsItem * parent = nullptr); + StereoItem(QWidget *wParent, QGraphicsItem *parent = nullptr); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void hoverMoveEvent(QGraphicsSceneHoverEvent *event); #ifndef STEREO_DISABLED void updateData(IplImage *disp); #endif QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - void setDispNew(bool d = true); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void setDispNew(bool d = true); }; #endif diff --git a/include/stereoWidget.h b/include/stereoWidget.h index 86618485fc9fb4fa1d5df365e7ade0976e63a941..d65cf241dce250be3d36560cf9770fb5acae9c71 100644 --- a/include/stereoWidget.h +++ b/include/stereoWidget.h @@ -21,13 +21,13 @@ #ifndef STEREOWIDGET_H #define STEREOWIDGET_H -#include <QtWidgets> -#include "ui_stereo.h" - #include "petrack.h" #include "stereoItem.h" +#include "ui_stereo.h" + +#include <QtWidgets> -class StereoWidget: public QWidget, public Ui::Stereo +class StereoWidget : public QWidget, public Ui::Stereo { Q_OBJECT @@ -44,12 +44,12 @@ private slots: #ifndef STEREO_DISABLED void on_stereoUseForHeight_stateChanged(int i) { - if (stereoUseForHeightEver->isChecked() && stereoUseForHeight->isChecked()) + if(stereoUseForHeightEver->isChecked() && stereoUseForHeight->isChecked()) mMainWindow->updateImage(); } void on_stereoUseForHeightEver_stateChanged(int i) { - if (stereoUseForHeightEver->isChecked() && stereoUseForHeight->isChecked()) + if(stereoUseForHeightEver->isChecked() && stereoUseForHeight->isChecked()) mMainWindow->updateImage(); } @@ -60,12 +60,12 @@ private slots: } void on_stereoColor_currentIndexChanged(int i) { - if (mMainWindow && (mMainWindow->getScene())) + if(mMainWindow && (mMainWindow->getScene())) mMainWindow->getScene()->update(); } void on_stereoDispAlgo_currentIndexChanged(int i) { - if (mMainWindow && (mMainWindow->getScene()) && mMainWindow->getStereoContext()) + if(mMainWindow && (mMainWindow->getScene()) && mMainWindow->getStereoContext()) { mMainWindow->getStereoContext()->indicateNewValues(); mMainWindow->getScene()->update(); @@ -73,38 +73,35 @@ private slots: } void on_hideWrong_stateChanged(int i) { - if (mMainWindow && (mMainWindow->getScene()) && mMainWindow->getStereoContext()) + if(mMainWindow && (mMainWindow->getScene()) && mMainWindow->getStereoContext()) { mMainWindow->getStereoContext()->indicateNewValues(); mMainWindow->getScene()->update(); } - //mMainWindow->getScene()->update(); + // mMainWindow->getScene()->update(); } void on_stereoMaskSize_valueChanged(int i) { - if (i%2 == 0) + if(i % 2 == 0) { - stereoMaskSize->setValue(i-1); + stereoMaskSize->setValue(i - 1); return; } - if (mMainWindow->getStereoContext()) + if(mMainWindow->getStereoContext()) { mMainWindow->getStereoContext()->indicateNewValues(); mMainWindow->getScene()->update(); } } - void on_opacity_valueChanged(int i) - { - mMainWindow->getScene()->update(); - } + void on_opacity_valueChanged(int i) { mMainWindow->getScene()->update(); } void on_edgeMaskSize_valueChanged(int i) { - if (i%2 == 0) + if(i % 2 == 0) { - edgeMaskSize->setValue(i-1); + edgeMaskSize->setValue(i - 1); return; } - if (mMainWindow->getStereoContext()) + if(mMainWindow->getStereoContext()) { mMainWindow->getStereoContext()->preprocess(); mMainWindow->getStereoContext()->indicateNewValues(); @@ -115,7 +112,7 @@ private slots: // zuerst das ergebniss des zuletzt berechneten frames mit edge angezeigt wird!!!!!!!!! void on_useEdge_stateChanged(int i) { - if (mMainWindow->getStereoContext()) + if(mMainWindow->getStereoContext()) { mMainWindow->getStereoContext()->preprocess(); mMainWindow->getStereoContext()->indicateNewValues(); @@ -124,7 +121,7 @@ private slots: } void on_maxDisparity_valueChanged(int i) { - if (mMainWindow->getStereoContext()) + if(mMainWindow->getStereoContext()) { mMainWindow->getStereoContext()->indicateNewValues(); mMainWindow->getScene()->update(); @@ -132,17 +129,14 @@ private slots: } void on_minDisparity_valueChanged(int i) { - if (mMainWindow->getStereoContext()) + if(mMainWindow->getStereoContext()) { mMainWindow->getStereoContext()->indicateNewValues(); mMainWindow->getScene()->update(); } } - void on_stereoExport_clicked() - { - mMainWindow->getStereoContext()->exportPointCloud(); - } + void on_stereoExport_clicked() { mMainWindow->getStereoContext()->exportPointCloud(); } #endif private: diff --git a/include/swapFilter.h b/include/swapFilter.h index 22b5892f5659e40ccecbb06d02b321e26824caa0..1f57c332e962f25046d4459ccbdd6e12b79ca732 100644 --- a/include/swapFilter.h +++ b/include/swapFilter.h @@ -28,7 +28,7 @@ class SwapFilter : public Filter { private: Parameter mSwapHorizontally; // 0.0 false; 1.0 true - Parameter mSwapVertically; // 0.0 false; 1.0 true + Parameter mSwapVertically; // 0.0 false; 1.0 true public: SwapFilter(); diff --git a/include/tracker.h b/include/tracker.h index f93ffaa5e48a01a36e0b23409b203920bc579b8c..746b882f5dbfddba1c20e58b0edaa1547ec88bc3 100644 --- a/include/tracker.h +++ b/include/tracker.h @@ -21,14 +21,15 @@ #ifndef TRACKER_H #define TRACKER_H -#include <QList> +#include "petrack.h" +#include "vector.h" + #include <QColor> +#include <QList> #include <QTextStream> -#include "vector.h" -#include "petrack.h" - -// war 1.5, aber bei bildauslassungen kann es ungewollt zuschlagen (bei 3 ist ein ausgelassener frame mgl, bei 2 wieder ein problem) +// war 1.5, aber bei bildauslassungen kann es ungewollt zuschlagen (bei 3 ist ein ausgelassener frame mgl, bei 2 wieder +// ein problem) inline constexpr double EXTRAPOLATE_FACTOR = 3.; // maximale anzahl an gleichzeitig getrackten personen @@ -48,11 +49,12 @@ inline constexpr double MIN_HEIGHT = -100'000.; class TrackPoint : public Vec2F // Vec2F is pixel point in picture { private: - Vec2F mColPoint; // center of color marker - QColor mCol; // color of corresponding marker - int mQual; // quality 0 (worst) .. 100 (best) - int mMarkerID; // ID of detected Marker - Vec3F mSp; // measured 3d point with stereo // mZdistanceToCam; // distance in z direction to camera - measured with stereo + Vec2F mColPoint; // center of color marker + QColor mCol; // color of corresponding marker + int mQual; // quality 0 (worst) .. 100 (best) + int mMarkerID; // ID of detected Marker + Vec3F mSp; // measured 3d point with stereo // mZdistanceToCam; // distance in z direction to camera - measured with + // stereo public: TrackPoint(); @@ -62,82 +64,46 @@ public: TrackPoint(const Vec2F &p, int qual, const QColor &col); TrackPoint(const Vec2F &p, int qual, const Vec2F &colPoint, const QColor &col); - inline const Vec2F& colPoint() const - { - return mColPoint; - } - inline void setColPoint(Vec2F &cp) - { - mColPoint = cp; - } - inline const QColor& color() const - { - return mCol; - } - inline void setColor(QColor& col) - { - mCol = col; - } - inline void setColPoint(const Vec2F &colPoint) - { - mColPoint = colPoint; - } - inline void setCol(const QColor &col) - { - mCol = col; - } - inline int qual() const - { - return mQual; - } - inline void setQual(int qual) - { - mQual = qual; - } - inline int getMarkerID() const - { - return mMarkerID; - } - inline void setMarkerID(int markerID) - { - mMarkerID = markerID; - } - - inline const Vec3F& sp() const - { - return mSp; - } - inline void setSp(const Vec3F &sp) - { - mSp = sp; - } - inline void setSp(float x, float y, float z) + inline const Vec2F & colPoint() const { return mColPoint; } + inline void setColPoint(Vec2F &cp) { mColPoint = cp; } + inline const QColor &color() const { return mCol; } + inline void setColor(QColor &col) { mCol = col; } + inline void setColPoint(const Vec2F &colPoint) { mColPoint = colPoint; } + inline void setCol(const QColor &col) { mCol = col; } + inline int qual() const { return mQual; } + inline void setQual(int qual) { mQual = qual; } + inline int getMarkerID() const { return mMarkerID; } + inline void setMarkerID(int markerID) { mMarkerID = markerID; } + + inline const Vec3F &sp() const { return mSp; } + inline void setSp(const Vec3F &sp) { mSp = sp; } + inline void setSp(float x, float y, float z) { mSp.setX(x); mSp.setY(y); mSp.setZ(z); } - const TrackPoint& operator=(const Vec2F& v); - const TrackPoint& operator+=(const Vec2F& v); - const TrackPoint operator+(const Vec2F& v) const; + const TrackPoint &operator=(const Vec2F &v); + const TrackPoint &operator+=(const Vec2F &v); + const TrackPoint operator+(const Vec2F &v) const; }; -inline QTextStream& operator>>(QTextStream& s, TrackPoint& tp) +inline QTextStream &operator>>(QTextStream &s, TrackPoint &tp) { double d; - Vec2F p; - Vec3F sp; + Vec2F p; + Vec3F sp; QColor col; - int qual; - int markerID; + int qual; + int markerID; - s >> d; + s >> d; tp.setX(d); s >> d; tp.setY(d); - if (Petrack::trcVersion > 1) + if(Petrack::trcVersion > 1) { s >> d; sp.setX(d); @@ -147,40 +113,48 @@ inline QTextStream& operator>>(QTextStream& s, TrackPoint& tp) sp.setZ(d); tp.setSp(sp); } - s >> qual; + s >> qual; tp.setQual(qual); - s >> d; + s >> d; p.setX(d); - s >> d; + s >> d; p.setY(d); tp.setColPoint(p); - s >> col; + s >> col; tp.setColor(col); - if (Petrack::trcVersion > 2) + if(Petrack::trcVersion > 2) { s >> markerID; tp.setMarkerID(markerID); } return s; } -inline QTextStream& operator<<(QTextStream& s, const TrackPoint& tp) +inline QTextStream &operator<<(QTextStream &s, const TrackPoint &tp) { - if (Petrack::trcVersion > 2) - s << tp.x() << " " << tp.y() << " " << tp.sp().x() << " " << tp.sp().y() << " " << tp.sp().z() << " " << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color() << " " << tp.getMarkerID(); - else if (Petrack::trcVersion == 2) - s << tp.x() << " " << tp.y() << " " << tp.sp().x() << " " << tp.sp().y() << " " << tp.sp().z() << " " << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color(); + if(Petrack::trcVersion > 2) + s << tp.x() << " " << tp.y() << " " << tp.sp().x() << " " << tp.sp().y() << " " << tp.sp().z() << " " + << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color() << " " + << tp.getMarkerID(); + else if(Petrack::trcVersion == 2) + s << tp.x() << " " << tp.y() << " " << tp.sp().x() << " " << tp.sp().y() << " " << tp.sp().z() << " " + << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color(); else - s << tp.x() << " " << tp.y() << " " << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color(); + s << tp.x() << " " << tp.y() << " " << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " + << tp.color(); return s; } -inline std::ostream& operator<<(std::ostream& s, const TrackPoint& tp) +inline std::ostream &operator<<(std::ostream &s, const TrackPoint &tp) { - if (Petrack::trcVersion > 2) - s << tp.x() << " " << tp.y() << " " << tp.sp().x() << " " << tp.sp().y() << " " << tp.sp().z() << " " << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color() << " " << tp.getMarkerID(); - else if (Petrack::trcVersion > 1) - s << tp.x() << " " << tp.y() << " " << tp.sp().x() << " " << tp.sp().y() << " " << tp.sp().z() << " " << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color(); + if(Petrack::trcVersion > 2) + s << tp.x() << " " << tp.y() << " " << tp.sp().x() << " " << tp.sp().y() << " " << tp.sp().z() << " " + << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color() << " " + << tp.getMarkerID(); + else if(Petrack::trcVersion > 1) + s << tp.x() << " " << tp.y() << " " << tp.sp().x() << " " << tp.sp().y() << " " << tp.sp().z() << " " + << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color(); else - s << tp.x() << " " << tp.y() << " " << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " << tp.color(); + s << tp.x() << " " << tp.y() << " " << tp.qual() << " " << tp.colPoint().x() << " " << tp.colPoint().y() << " " + << tp.color(); return s; } @@ -191,18 +165,19 @@ inline std::ostream& operator<<(std::ostream& s, const TrackPoint& tp) class TrackPerson : public QList<TrackPoint> { private: - int mNr; // person number - int mMarkerID = -1; //markerID of Trackperson; -1 as positive values including 0 do exist as ArucoCodeNumbers-Values - double mHeight; // height of the person - int mHeightCount; // number of colors where mHeight is averaged - int mFirstFrame; // 0.. frame where the person was tracked the first time - int mLastFrame; // 0.. - //int qual; // quality - bool mNewReco; // true if person was just recognized - QColor mCol; // color of point - QString mComment; // comment for person - int mNrInBg; // number of successive frames in the background - int mColCount; // number of colors where mCol is average from + int mNr; // person number + int mMarkerID = -1; // markerID of Trackperson; -1 as positive values including 0 do exist as + // ArucoCodeNumbers-Values + double mHeight; // height of the person + int mHeightCount; // number of colors where mHeight is averaged + int mFirstFrame; // 0.. frame where the person was tracked the first time + int mLastFrame; // 0.. + // int qual; // quality + bool mNewReco; // true if person was just recognized + QColor mCol; // color of point + QString mComment; // comment for person + int mNrInBg; // number of successive frames in the background + int mColCount; // number of colors where mCol is average from public: TrackPerson(); @@ -212,134 +187,72 @@ public: bool insertAtFrame(int frame, const TrackPoint &p, int persNr, bool extrapolate); - inline int nrInBg() const - { - return mNrInBg; - } - inline void setNrInBg(int n) - { - mNrInBg = n; - } + inline int nrInBg() const { return mNrInBg; } + inline void setNrInBg(int n) { mNrInBg = n; } - inline double height() const - { - return mHeight; - } + inline double height() const { return mHeight; } // echte Personengroesse beim einlesen der trj datei - inline void setHeight(double h) - { - mHeight = h; - } + inline void setHeight(double h) { mHeight = h; } // beim setzen der Hoehe wird Mittelwert gebildet // z is z distance to camera // altitude is height of the camera over floor inline void setHeight(float z, float altitude) // , int frame { - mHeight = (mHeight*mHeightCount+(altitude-z))/(mHeightCount+1); + mHeight = (mHeight * mHeightCount + (altitude - z)) / (mHeightCount + 1); ++mHeightCount; } inline void resetHeight() { - mHeight = MIN_HEIGHT; + mHeight = MIN_HEIGHT; mHeightCount = 0; } - void recalcHeight(float altitude); + void recalcHeight(float altitude); double getNearestZ(int i, int *extrapolated); - inline int getMarkerID() const - { - return mMarkerID; - } - inline void setMarkerID(const int markerID) - { - mMarkerID = markerID; - } - inline const QColor& color() const - { - return mCol; - } - inline void setColor(const QColor& col) - { - mCol = col; - } - inline bool newReco() const - { - return mNewReco; - } - inline void setNewReco(bool b) - { - mNewReco = b; - } - inline int firstFrame() const - { - return mFirstFrame; - } - inline void setFirstFrame(int f) - { - mFirstFrame = f; - } - inline int lastFrame() const - { - return mLastFrame; - } - inline void setLastFrame(int f) - { - mLastFrame = f; - } - inline int nr() const - { - return mNr; - } - inline void setNr(int nr) - { - mNr = nr; - } - inline const QString comment() const - { - return mComment; - } + inline int getMarkerID() const { return mMarkerID; } + inline void setMarkerID(const int markerID) { mMarkerID = markerID; } + inline const QColor &color() const { return mCol; } + inline void setColor(const QColor &col) { mCol = col; } + inline bool newReco() const { return mNewReco; } + inline void setNewReco(bool b) { mNewReco = b; } + inline int firstFrame() const { return mFirstFrame; } + inline void setFirstFrame(int f) { mFirstFrame = f; } + inline int lastFrame() const { return mLastFrame; } + inline void setLastFrame(int f) { mLastFrame = f; } + inline int nr() const { return mNr; } + inline void setNr(int nr) { mNr = nr; } + inline const QString comment() const { return mComment; } /** * @brief Get the comment without line breaks * * Get the comment as a one line QString where all linebreak are replaced with '<br>' * @return comment without line breaks */ - inline QString serializeComment() const - { - return QString{mComment}.replace(QRegularExpression("\n"), "<br>"); - } - - inline void setComment(QString s) - { - mComment = s; - } - inline int colCount() const - { - return mColCount; - } - inline void setColCount(int c) - { - mColCount = c; - } - void addColor(const QColor &col); - void optimizeColor(); - bool trackPointExist(int frame) const; - const TrackPoint& trackPointAt(int frame) const; // & macht bei else probleme, sonst mit [] zugreifbar + inline QString serializeComment() const { return QString{mComment}.replace(QRegularExpression("\n"), "<br>"); } + + inline void setComment(QString s) { mComment = s; } + inline int colCount() const { return mColCount; } + inline void setColCount(int c) { mColCount = c; } + void addColor(const QColor &col); + void optimizeColor(); + bool trackPointExist(int frame) const; + const TrackPoint &trackPointAt(int frame) const; // & macht bei else probleme, sonst mit [] zugreifbar // gibt -1 zurueck, wenn frame oder naechster frame nicht existiert // entfernung ist absolut double distanceToNextFrame(int frame) const; - void syncTrackPersonMarkerID(int markerID); + void syncTrackPersonMarkerID(int markerID); }; -//mHeightCount wird nicht e3xportiert und auch nicht wieder eingelesen -> nach import auf 0 obwohl auf height ein wert steht, daher immer mheight auf -1 testen!!! +// mHeightCount wird nicht e3xportiert und auch nicht wieder eingelesen -> nach import auf 0 obwohl auf height ein wert +// steht, daher immer mheight auf -1 testen!!! // keine Konsistenzueberpruefung -inline QTextStream& operator>>(QTextStream& s, TrackPerson& tp) +inline QTextStream &operator>>(QTextStream &s, TrackPerson &tp) { - double d; - QColor col; - int n; + double d; + QColor col; + int n; TrackPoint p; - int markerID; + int markerID; s.skipWhiteSpace(); QString str = s.readLine(); @@ -358,13 +271,13 @@ inline QTextStream& operator>>(QTextStream& s, TrackPerson& tp) tp.setColCount(n); trjInfoLine >> col; tp.setColor(col); - if (Petrack::trcVersion > 3) + if(Petrack::trcVersion > 3) { trjInfoLine >> markerID; tp.setMarkerID(markerID); } - trjInfoLine >> n; // size of list - if (Petrack::trcVersion > 2) // Reading the comment line + trjInfoLine >> n; // size of list + if(Petrack::trcVersion > 2) // Reading the comment line { // Kommentarzeile lesen str = s.readLine(); @@ -372,7 +285,7 @@ inline QTextStream& operator>>(QTextStream& s, TrackPerson& tp) } - for (int i = 0; i < n; ++i) + for(int i = 0; i < n; ++i) { s >> p; tp.append(p); @@ -380,30 +293,32 @@ inline QTextStream& operator>>(QTextStream& s, TrackPerson& tp) return s; } -inline QTextStream& operator<<(QTextStream& s, const TrackPerson& tp) +inline QTextStream &operator<<(QTextStream &s, const TrackPerson &tp) { - s << tp.nr() << " " << tp.height() << " " << tp.firstFrame() << " " << tp.lastFrame() << " " << tp.colCount() << " " << tp.color(); - if (Petrack::trcVersion > 3) + s << tp.nr() << " " << tp.height() << " " << tp.firstFrame() << " " << tp.lastFrame() << " " << tp.colCount() << " " + << tp.color(); + if(Petrack::trcVersion > 3) { - s << " " <<tp.getMarkerID(); + s << " " << tp.getMarkerID(); } s << " " << tp.size(); s << Qt::endl << tp.serializeComment() << Qt::endl; - for (int i = 0; i < tp.size(); ++i) + for(int i = 0; i < tp.size(); ++i) s << tp.at(i) << Qt::endl; return s; } -inline std::ostream& operator<<(std::ostream& s, const TrackPerson& tp) +inline std::ostream &operator<<(std::ostream &s, const TrackPerson &tp) { - s << tp.nr() << " " << tp.height() << " " << tp.firstFrame() << " " << tp.lastFrame() << " " << tp.colCount() << " " << tp.color(); + s << tp.nr() << " " << tp.height() << " " << tp.firstFrame() << " " << tp.lastFrame() << " " << tp.colCount() << " " + << tp.color(); if(Petrack::trcVersion > 3) { - s << " " << tp.getMarkerID(); + s << " " << tp.getMarkerID(); } s << " " << tp.size(); s << std::endl << tp.serializeComment() << std::endl; - for (int i = 0; i < tp.size(); ++i) + for(int i = 0; i < tp.size(); ++i) s << tp.at(i) << std::endl; return s; } @@ -425,15 +340,15 @@ inline std::ostream& operator<<(std::ostream& s, const TrackPerson& tp) class Tracker : public QList<TrackPerson> { private: - Petrack *mMainWindow; - cv::Mat mGrey, mPrevGrey; - std::vector<cv::Mat> mPrevPyr, mCurrentPyr; + Petrack * mMainWindow; + cv::Mat mGrey, mPrevGrey; + std::vector<cv::Mat> mPrevPyr, mCurrentPyr; std::vector<cv::Point2f> mPrevFeaturePoints, mFeaturePoints; - std::vector<uchar> mStatus; - int mPrevFrame; - std::vector<int> mPrevFeaturePointsIdx; - std::vector<float> mTrackError; - cv::TermCriteria mTermCriteria; + std::vector<uchar> mStatus; + int mPrevFrame; + std::vector<int> mPrevFeaturePointsIdx; + std::vector<float> mTrackError; + cv::TermCriteria mTermCriteria; public: Tracker(QWidget *wParent); @@ -446,16 +361,16 @@ public: void resize(cv::Size size); void splitPerson(int pers, int frame); - bool splitPersonAt(const Vec2F& p, int frame, QSet<int> onlyVisible); + bool splitPersonAt(const Vec2F &p, int frame, QSet<int> onlyVisible); bool delPointOf(int pers, int direction, int frame); - bool delPoint(const Vec2F& p, int direction, int frame, QSet<int> onlyVisible); + bool delPoint(const Vec2F &p, int direction, int frame, QSet<int> onlyVisible); void delPointAll(int direction, int frame); void delPointROI(); void delPointInsideROI(); - bool editTrackPersonComment(const Vec2F& p, int frame, const QSet<int>& onlyVisible); - bool setTrackPersonHeight(const Vec2F& p, int frame, QSet<int> onlyVisible); - bool resetTrackPersonHeight(const Vec2F& p, int frame, QSet<int> onlyVisible); + bool editTrackPersonComment(const Vec2F &p, int frame, const QSet<int> &onlyVisible); + bool setTrackPersonHeight(const Vec2F &p, int frame, QSet<int> onlyVisible); + bool resetTrackPersonHeight(const Vec2F &p, int frame, QSet<int> onlyVisible); // used for calculation of 3D point for all points in frame // returns number of found points or -1 if no stereoContext available (also points without disp found are counted) @@ -464,7 +379,12 @@ public: // true, if new traj is inserted with point p and initial frame frame // p in pixel coord // pers wird gesetzt, wenn existierender trackpoint einer person verschoben wird - bool addPoint(TrackPoint &p, int frame, const QSet<int>& onlyVisible, reco::RecognitionMethod method, int *pers = nullptr); + bool addPoint( + TrackPoint & p, + int frame, + const QSet<int> & onlyVisible, + reco::RecognitionMethod method, + int * pers = nullptr); // hier sollte direkt die farbe mit uebergeben werden void addPoints(QList<TrackPoint> &pL, int frame, reco::RecognitionMethod method); @@ -479,19 +399,38 @@ public: int smallestFirstFrame(); int smallestLastFrame(); - size_t calcPrevFeaturePoints(int prevFrame, cv::Rect &rect, int frame, bool reTrack, int reQual, int borderSize, QSet<int> onlyVisible); + size_t calcPrevFeaturePoints( + int prevFrame, + cv::Rect &rect, + int frame, + bool reTrack, + int reQual, + int borderSize, + QSet<int> onlyVisible); int insertFeaturePoints(int frame, size_t count, cv::Mat &img, int borderSize, float errorScale); // frame ist frame fuer naechsten prev frame - int track(cv::Mat &img, cv::Rect &rect, int frame, bool reTrack, int reQual, int borderSize, reco::RecognitionMethod recoMethod, int level=3, QSet<int> onlyVisible = QSet<int>(), int errorScaleExponent=0); - - - void checkPlausibility(QList<int> &pers, QList<int> &frame, - bool testEqual = true, - bool testVelocity = true, - bool testInside = true, - bool testLength = true); + int track( + cv::Mat & img, + cv::Rect & rect, + int frame, + bool reTrack, + int reQual, + int borderSize, + reco::RecognitionMethod recoMethod, + int level = 3, + QSet<int> onlyVisible = QSet<int>(), + int errorScaleExponent = 0); + + + void checkPlausibility( + QList<int> &pers, + QList<int> &frame, + bool testEqual = true, + bool testVelocity = true, + bool testInside = true, + bool testLength = true); void optimizeColor(); // reset the height of all persons, but not the pos of the trackpoints @@ -511,12 +450,12 @@ public: void purge(int frame); private: - bool tryMergeTrajectories(const TrackPoint& v, size_t i, int frame); + bool tryMergeTrajectories(const TrackPoint &v, size_t i, int frame); void trackFeaturePointsLK(int level); void trackFeaturePointsLK(int level, bool adaptive); void refineViaColorPointLK(int level, float errorScale); - void useBackgroundFilter(QList<int>& trjToDel, BackgroundFilter *bgFilter); + void useBackgroundFilter(QList<int> &trjToDel, BackgroundFilter *bgFilter); void refineViaNearDarkPoint(); void preCalculateImagePyramids(int level); }; diff --git a/include/trackerItem.h b/include/trackerItem.h index 5f110166d5e6beb0726264e4b8c2bddad9a956ef..574e2fe294a1a07a470a1ea97a3f40eb210329e4 100644 --- a/include/trackerItem.h +++ b/include/trackerItem.h @@ -35,10 +35,10 @@ private: Tracker *mTracker; public: - TrackerItem(QWidget *wParent, Tracker *tracker, QGraphicsItem * parent = nullptr); - void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); + TrackerItem(QWidget *wParent, Tracker *tracker, QGraphicsItem *parent = nullptr); + void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); }; #endif diff --git a/include/trackerReal.h b/include/trackerReal.h index bba495c331d0e9d77e99f443d94536f6242a018e..39c2a3f1827112ee53517a77f2bab0f4a79befb1 100644 --- a/include/trackerReal.h +++ b/include/trackerReal.h @@ -21,56 +21,36 @@ #ifndef TRACKERREAL_H #define TRACKERREAL_H -#include <QList> - -#include "vector.h" -#include "tracker.h" -#include "imageItem.h" #include "colorPlot.h" +#include "imageItem.h" +#include "tracker.h" +#include "vector.h" + +#include <QList> // point in x/y in cm class TrackPointReal : public Vec3F { private: - int mFrameNum; // frame number in animation sequence possibly with missing frames + int mFrameNum; // frame number in animation sequence possibly with missing frames Vec2F mViewDir; float mAngleOfView; // angle of view of camera to point - int mMarkerID; + int mMarkerID; + public: TrackPointReal(const Vec3F &p, int frameNum); TrackPointReal(const Vec3F &p, int frameNum, const Vec2F &d); - inline int frameNum() const - { - return mFrameNum; - } - inline void setFrameNum(int frameNum) - { - mFrameNum = frameNum; - } - inline Vec2F viewDir() const - { - return mViewDir; - } - inline float angleOfView() const - { - return mAngleOfView; - } - inline void setAngleOfView(float a) - { - mAngleOfView = a; - } - inline int getMarkerID() const - { - return mMarkerID; - } - inline void setMarkerID(int markerID) - { - mMarkerID = markerID; - } + inline int frameNum() const { return mFrameNum; } + inline void setFrameNum(int frameNum) { mFrameNum = frameNum; } + inline Vec2F viewDir() const { return mViewDir; } + inline float angleOfView() const { return mAngleOfView; } + inline void setAngleOfView(float a) { mAngleOfView = a; } + inline int getMarkerID() const { return mMarkerID; } + inline void setMarkerID(int markerID) { mMarkerID = markerID; } }; -inline QTextStream& operator<<(QTextStream& s, const TrackPointReal& tp) +inline QTextStream &operator<<(QTextStream &s, const TrackPointReal &tp) { s << tp.x() << " " << tp.y(); // nur x, y wird ausgegeben, z wird nur bei Bedarf mit ausgegeben!!! return s; @@ -83,63 +63,39 @@ inline QTextStream& operator<<(QTextStream& s, const TrackPointReal& tp) class TrackPersonReal : public QList<TrackPointReal> { private: - double mHeight; // height of the person - int mFirstFrame; // 0.. frame where the person was tracked the first time - int mLastFrame; // 0.. - int mMarkerID = -1; //set to -1 as -1 does not naturally occur as a ArucoMarkerNumber-value + double mHeight; // height of the person + int mFirstFrame; // 0.. frame where the person was tracked the first time + int mLastFrame; // 0.. + int mMarkerID = -1; // set to -1 as -1 does not naturally occur as a ArucoMarkerNumber-value public: TrackPersonReal(); TrackPersonReal(int frame, const TrackPointReal &p); - inline double height() const - { - return mHeight; - } - inline void setHeight(double h) - { - mHeight = h; - } - inline int firstFrame() const - { - return mFirstFrame; - } - inline void setFirstFrame(int f) - { - mFirstFrame = f; - } - inline int lastFrame() const - { - return mLastFrame; - } - inline void setLastFrame(int f) - { - mLastFrame = f; - } - inline int getMarkerID() const - { - return mMarkerID; - } - inline void setMarkerID(int markerID) - { - mMarkerID = markerID; - } - bool trackPointExist(int frame) const; - const TrackPointReal& trackPointAt(int frame) const; // & macht bei else probleme, sonst mit [] zugreifbar + inline double height() const { return mHeight; } + inline void setHeight(double h) { mHeight = h; } + inline int firstFrame() const { return mFirstFrame; } + inline void setFirstFrame(int f) { mFirstFrame = f; } + inline int lastFrame() const { return mLastFrame; } + inline void setLastFrame(int f) { mLastFrame = f; } + inline int getMarkerID() const { return mMarkerID; } + inline void setMarkerID(int markerID) { mMarkerID = markerID; } + bool trackPointExist(int frame) const; + const TrackPointReal &trackPointAt(int frame) const; // & macht bei else probleme, sonst mit [] zugreifbar // gibt -1 zurueck, wenn frame oder naechster frame nicht existiert // entfernung ist absolut double distanceToNextFrame(int frame) const; - void init(int firstFrame, double height, int markerID); - void addEnd(const QPointF& pos, int frame); - void addEnd(const Vec3F& pos, int frame); - void addEnd(const QPointF& pos, int frame, const QPointF &dir); + void init(int firstFrame, double height, int markerID); + void addEnd(const QPointF &pos, int frame); + void addEnd(const Vec3F &pos, int frame); + void addEnd(const QPointF &pos, int frame, const QPointF &dir); }; -inline QTextStream& operator<<(QTextStream& s, const TrackPersonReal& tp) +inline QTextStream &operator<<(QTextStream &s, const TrackPersonReal &tp) { int firstFrame = tp.firstFrame(); - for (int i = 0; i < tp.size(); ++i) - s << firstFrame+i << tp.at(i) << tp.height() << Qt::endl; + for(int i = 0; i < tp.size(); ++i) + s << firstFrame + i << tp.at(i) << tp.height() << Qt::endl; return s; } @@ -157,26 +113,14 @@ inline QTextStream& operator<<(QTextStream& s, const TrackPersonReal& tp) class TrackerReal : public QList<TrackPersonReal> { private: - double mXMin, mXMax, mYMin, mYMax; + double mXMin, mXMax, mYMin, mYMax; Petrack *mMainWindow; public: - inline double xMin() const - { - return mXMin; - } - inline double xMax() const - { - return mXMax; - } - inline double yMin() const - { - return mYMin; - } - inline double yMax() const - { - return mYMax; - } + inline double xMin() const { return mXMin; } + inline double xMax() const { return mXMax; } + inline double yMin() const { return mYMin; } + inline double yMax() const { return mYMax; } TrackerReal(QWidget *wParent); @@ -189,20 +133,40 @@ public: // petrack...getImageBorderSize() // mControlWidget->getColorPlot() // petrack...mImageItem - int calculate(Tracker *tracker, ImageItem *imageItem, ColorPlot *colorPlot, int imageBorderSize = 0, bool missingFramesInserted = true, bool useTrackpoints = false, - bool alternateHeight = false, double altitude = 0, bool useCalibrationCenter = true, - bool exportElimTp = false, bool exportElimTrj = false, bool exportSmooth = true, - bool exportViewingDirection = false, bool exportAngleOfView = false, bool exportMarkerID = false, bool exportAutoCorrect = false); + int calculate( + Tracker * tracker, + ImageItem *imageItem, + ColorPlot *colorPlot, + int imageBorderSize = 0, + bool missingFramesInserted = true, + bool useTrackpoints = false, + bool alternateHeight = false, + double altitude = 0, + bool useCalibrationCenter = true, + bool exportElimTp = false, + bool exportElimTrj = false, + bool exportSmooth = true, + bool exportViewingDirection = false, + bool exportAngleOfView = false, + bool exportMarkerID = false, + bool exportAutoCorrect = false); void calcMinMax(); - int largestFirstFrame(); - int largestLastFrame(); - int smallestFirstFrame(); - int smallestLastFrame(); + int largestFirstFrame(); + int largestLastFrame(); + int smallestFirstFrame(); + int smallestLastFrame(); // alternateHeight true, wenn keine eindeutige personengroesse ausgegeben wird, sondern fuer jeden pounkt andere - void exportTxt(QTextStream &out, bool alternateHeight, bool useTrackpoints, bool exportViewingDirection, bool exportAngleOfView, bool exportUseM, bool exportMarkerID); - void exportDat(QTextStream &out, bool alternateHeight, bool useTrackpoints); // fuer gnuplot + void exportTxt( + QTextStream &out, + bool alternateHeight, + bool useTrackpoints, + bool exportViewingDirection, + bool exportAngleOfView, + bool exportUseM, + bool exportMarkerID); + void exportDat(QTextStream &out, bool alternateHeight, bool useTrackpoints); // fuer gnuplot void exportXml(QTextStream &outXml, bool alternateHeight, bool useTrackpoints); }; diff --git a/include/trackingRoiItem.h b/include/trackingRoiItem.h index 70206b14f506ac39152447ea34d19376a156a011..8d9d35ee0699503efe82ba4759b2a6b8c66644b3 100644 --- a/include/trackingRoiItem.h +++ b/include/trackingRoiItem.h @@ -28,23 +28,34 @@ class Control; class TrackingRoiItem : public QGraphicsRectItem { - inline static constexpr int DISTANCE_TO_BORDER = 5; - inline static constexpr int MIN_SIZE = 10; - - enum pressLocation{inside, top, bottom, left, right, topLeft, topRight, bottomLeft, bottomRight}; + inline static constexpr int DISTANCE_TO_BORDER = 5; + inline static constexpr int MIN_SIZE = 10; + + enum pressLocation + { + inside, + top, + bottom, + left, + right, + topLeft, + topRight, + bottomLeft, + bottomRight + }; private: - Petrack *mMainWindow; - Control *mControlWidget; - QRect mPressRect; - QPointF mPressPos; + Petrack * mMainWindow; + Control * mControlWidget; + QRect mPressRect; + QPointF mPressPos; enum pressLocation mPressLocation; public: - TrackingRoiItem(QWidget *wParent, QGraphicsItem * parent = nullptr); - void mousePressEvent(QGraphicsSceneMouseEvent * event); - void mouseReleaseEvent(QGraphicsSceneMouseEvent * event); - void mouseMoveEvent(QGraphicsSceneMouseEvent * event); + TrackingRoiItem(QWidget *wParent, QGraphicsItem *parent = nullptr); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void hoverMoveEvent(QGraphicsSceneHoverEvent *event); void checkRect(); }; diff --git a/include/vector.h b/include/vector.h index 3267eb46e1566bd4913acdebd40caa37c74f568d..958363ba7faafbf338bf38cdab5a9b8194786203 100644 --- a/include/vector.h +++ b/include/vector.h @@ -23,9 +23,9 @@ #include "helper.h" +#include <QMatrix4x4> #include <QVector3D> #include <opencv2/core/types_c.h> -#include <QMatrix4x4> struct CvPoint; struct CvPoint2D32f; @@ -40,9 +40,9 @@ inline void printQVector3D(const QVector3D &p) inline void printQMatrix4x4(const QMatrix4x4 &m) { - for (int i=0; i<4; ++i) - debout << (m.data())[i*4+0] << " " << (m.data())[i*4+1] << " " - << (m.data())[i*4+2] << " " << (m.data())[i*4+3] << std::endl; + for(int i = 0; i < 4; ++i) + debout << (m.data())[i * 4 + 0] << " " << (m.data())[i * 4 + 1] << " " << (m.data())[i * 4 + 2] << " " + << (m.data())[i * 4 + 3] << std::endl; } class Vec3F @@ -57,52 +57,52 @@ public: Vec3F(double x, double y, double z); ~Vec3F() = default; - Vec3F(const Vec3F& v) = default; - Vec3F(Vec3F&& v) = default; + Vec3F(const Vec3F &v) = default; + Vec3F(Vec3F &&v) = default; - Vec3F(const cv::Point3f& v); + Vec3F(const cv::Point3f &v); double x() const; double y() const; double z() const; - void setX(double x); - void setY(double y); - void setZ(double z); - void set(double x, double y, double z); + void setX(double x); + void setY(double y); + void setZ(double z); + void set(double x, double y, double z); - Vec3F& operator=(const Vec3F& v) = default; - Vec3F& operator=(Vec3F&& v) = default; + Vec3F &operator=(const Vec3F &v) = default; + Vec3F &operator=(Vec3F &&v) = default; - Vec3F& operator=(const cv::Point3f& v); + Vec3F &operator=(const cv::Point3f &v); - Vec3F operator+(const Vec3F& v) const; - Vec3F operator-(const Vec3F& v) const; - Vec3F& operator+=(const Vec3F& v); - Vec3F& operator-=(const Vec3F& v); - Vec3F operator-() const; + Vec3F operator+(const Vec3F &v) const; + Vec3F operator-(const Vec3F &v) const; + Vec3F &operator+=(const Vec3F &v); + Vec3F &operator-=(const Vec3F &v); + Vec3F operator-() const; Vec3F operator*(double n) const; // multiply with a scalar value Vec3F operator/(double n) const; // divide by a scalar value - double operator*(const Vec3F& v) const; // dot product + double operator*(const Vec3F &v) const; // dot product - bool operator==(const Vec3F& v) const; - bool operator!=(const Vec3F& v) const; + bool operator==(const Vec3F &v) const; + bool operator!=(const Vec3F &v) const; double length() const; - Vec3F unit() const; - void normalize(); + Vec3F unit() const; + void normalize(); - double distanceToPoint(const Vec3F& p) const; + double distanceToPoint(const Vec3F &p) const; }; -inline Vec3F operator*(double f, const Vec3F& v) +inline Vec3F operator*(double f, const Vec3F &v) { - return v*f; + return v * f; } -inline std::ostream& operator<< (std::ostream& s, const Vec3F& v) +inline std::ostream &operator<<(std::ostream &s, const Vec3F &v) { s << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")"; return s; @@ -113,46 +113,46 @@ inline std::ostream& operator<< (std::ostream& s, const Vec3F& v) class Vec2F { protected: - //private: dann waeren mX... nicht direkt aus abgeleitet klassen zugreifbar + // private: dann waeren mX... nicht direkt aus abgeleitet klassen zugreifbar double mX; double mY; public: Vec2F(); Vec2F(double x, double y); - Vec2F(const Vec2F& v) = default; - Vec2F(const QPointF& v); - Vec2F(const cv::Point2f& p); - Vec2F(const CvPoint* v); - Vec2F(const CvPoint2D32f* v); + Vec2F(const Vec2F &v) = default; + Vec2F(const QPointF &v); + Vec2F(const cv::Point2f &p); + Vec2F(const CvPoint *v); + Vec2F(const CvPoint2D32f *v); - CvPoint toCvPoint() const; + CvPoint toCvPoint() const; CvPoint2D32f toCvPoint2D32f() const; - QPoint toQPoint() const; - QPointF toQPointF() const; - cv::Point2f toPoint2f() const; + QPoint toQPoint() const; + QPointF toQPointF() const; + cv::Point2f toPoint2f() const; double x() const; double y() const; - void setX(double x); - void setY(double y); - void set(double x, double y); + void setX(double x); + void setY(double y); + void set(double x, double y); - Vec2F& operator=(const CvPoint *v); + Vec2F &operator=(const CvPoint *v); - Vec2F& operator+=(const Vec2F& v); - Vec2F operator+(const Vec2F& v) const; - Vec2F& operator-=(const Vec2F& v); - Vec2F operator-(const Vec2F& v) const; - Vec2F operator-() const; + Vec2F &operator+=(const Vec2F &v); + Vec2F operator+(const Vec2F &v) const; + Vec2F &operator-=(const Vec2F &v); + Vec2F operator-(const Vec2F &v) const; + Vec2F operator-() const; Vec2F operator*(double n) const; // multiply with a scalar value Vec2F operator/(double n) const; // divide by a scalar value - double operator*(const Vec2F& v) const; // dot product + double operator*(const Vec2F &v) const; // dot product - bool operator==(const Vec2F& v) const; - bool operator!=(const Vec2F& v) const; + bool operator==(const Vec2F &v) const; + bool operator!=(const Vec2F &v) const; double length() const; @@ -164,33 +164,33 @@ public: void normalize(); - double distanceToPoint(const Vec2F& p) const; + double distanceToPoint(const Vec2F &p) const; // return distance from vec to line between p1 and p2 - double distanceToLine(const Vec2F& p1, const Vec2F& p2) const; - double angleBetweenVec(const Vec2F& v) const; + double distanceToLine(const Vec2F &p1, const Vec2F &p2) const; + double angleBetweenVec(const Vec2F &v) const; static Vec2F fromAngle(double angle); }; -inline Vec2F operator*(double f, const Vec2F& v) +inline Vec2F operator*(double f, const Vec2F &v) { - return v*f; + return v * f; } -inline std::ostream& operator<< (std::ostream& s, const Vec2F& v) +inline std::ostream &operator<<(std::ostream &s, const Vec2F &v) { s << "(" << v.x() << ", " << v.y() << ")"; return s; } // only for combine programm, not for petrack -inline QTextStream& operator<< (QTextStream& s, const Vec2F& v) +inline QTextStream &operator<<(QTextStream &s, const Vec2F &v) { s << v.x() << " " << v.y(); // ohne (,) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! return s; } -inline std::istream& operator>> (std::istream& s, Vec2F& v) +inline std::istream &operator>>(std::istream &s, Vec2F &v) { double d; s >> d; @@ -199,7 +199,7 @@ inline std::istream& operator>> (std::istream& s, Vec2F& v) v.setY(d); return s; } -inline QTextStream& operator>> (QTextStream& s, Vec2F& v) +inline QTextStream &operator>>(QTextStream &s, Vec2F &v) { double d; s >> d; diff --git a/include/view.h b/include/view.h index 5b9c9b0c1e29e26e11163b265a8ff529e500faa7..6552210851ef28e181687d352a02a8ba308b07b8 100644 --- a/include/view.h +++ b/include/view.h @@ -23,8 +23,8 @@ #include <QFrame> #include <QGraphicsView> -#include <QSlider> #include <QKeyEvent> +#include <QSlider> class Petrack; class QLabel; @@ -33,8 +33,9 @@ class ViewWidget; class GraphicsView : public QGraphicsView { - Q_OBJECT // here: for emitting a signal (you need it also for connecting signals with slots) - // must stand in .h file so qmake generates makefile where moc uses header + // here: for emitting a signal (you need it also for connecting signals with slots) + // must stand in .h file so qmake generates makefile where moc uses header + Q_OBJECT private: ViewWidget *mViewWidget; @@ -77,22 +78,10 @@ public: void hideControls(bool hide); - inline int getZoomLevel() - { - return mZoomSlider->value(); - } - inline void setZoomLevel(int l) - { - mZoomSlider->setValue(l); - } - inline int getRotateLevel() - { - return mRotateSlider->value(); - } - inline void setRotateLevel(int l) - { - mRotateSlider->setValue(l); - } + inline int getZoomLevel() { return mZoomSlider->value(); } + inline void setZoomLevel(int l) { mZoomSlider->setValue(l); } + inline int getRotateLevel() { return mRotateSlider->value(); } + inline void setRotateLevel(int l) { mRotateSlider->setValue(l); } public slots: void zoomIn(int i = 1); @@ -106,11 +95,11 @@ private slots: void hideShowControls(); private: - Petrack *mMainWindow; + Petrack * mMainWindow; GraphicsView *mGraphicsView; - QToolButton *hideShowControlsButton; - QSlider *mZoomSlider; - QSlider *mRotateSlider; + QToolButton * hideShowControlsButton; + QSlider * mZoomSlider; + QSlider * mRotateSlider; }; #endif diff --git a/scripts/check-format-cpp.sh b/scripts/check-format-cpp.sh new file mode 100755 index 0000000000000000000000000000000000000000..58ed406ace38ec85ca753af8abcb7f616578374a --- /dev/null +++ b/scripts/check-format-cpp.sh @@ -0,0 +1,10 @@ +#! /bin/bash + +set -e + +origin=$(dirname "$(readlink -f "$0")") +files=$(find "$(readlink -f "${origin}"/../src)" -type f -regex "^.*\.\(hpp\|cpp\|h\|c\)$") +files+=$'\n'$(find "$(readlink -f "${origin}"/../include)" -type f -regex "^.*\.\(hpp\|cpp\|h\|c\)$") +files+=$'\n'$(find "$(readlink -f "${origin}"/../tests)" -type f -regex "^.*\.\(hpp\|cpp\|h\|c\)$") + +echo "${files}" | parallel clang-format-12 --dry-run -Werror diff --git a/scripts/format-cpp.sh b/scripts/format-cpp.sh new file mode 100755 index 0000000000000000000000000000000000000000..b1d9c8d0bd281374ae8ea0557c638b00d8d3145d --- /dev/null +++ b/scripts/format-cpp.sh @@ -0,0 +1,10 @@ +#! /bin/bash + +set -e + +origin=$(dirname "$(readlink -f "$0")") +files=$(find "$(readlink -f ${origin}/../src)" -type f -regex "^.*\.\(hpp\|cpp\|h\|c\)$") +files+=$'\n'$(find "$(readlink -f ${origin}/../include)" -type f -regex "^.*\.\(hpp\|cpp\|h\|c\)$") +files+=$'\n'$(find "$(readlink -f ${origin}/../tests)" -type f -regex "^.*\.\(hpp\|cpp\|h\|c\)$") + +echo "${files}" | parallel clang-format-12 -i diff --git a/src/IO.cpp b/src/IO.cpp index 3b9480d13743a554e93944578e068433c37a9df1..9cbd9756a5e1db215f73857d5eee4443e9528abf 100644 --- a/src/IO.cpp +++ b/src/IO.cpp @@ -18,6 +18,13 @@ * along with this program. If not, see <https://cdwww.gnu.org/licenses/>. */ +#include "IO.h" + +#include "moCapPerson.h" +#include "pMessageBox.h" +#include "skeletonTree.h" +#include "skeletonTreeFactory.h" + #include <QFile> #include <QJsonArray> #include <QJsonDocument> @@ -26,12 +33,6 @@ #include <QTextStream> #include <opencv2/opencv.hpp> -#include "IO.h" -#include "moCapPerson.h" -#include "pMessageBox.h" -#include "skeletonTree.h" -#include "skeletonTreeFactory.h" - /** * @brief Reads individual heights for markerIDs from file. * @@ -50,15 +51,15 @@ * @param heightFileName name of the file containing the height information * @return map of markerID to height if parsing was successful, error message otherwise */ -std::variant<std::unordered_map<int, float>, std::string> IO::readHeightFile(const QString& heightFileName) +std::variant<std::unordered_map<int, float>, std::string> IO::readHeightFile(const QString &heightFileName) { - if (!heightFileName.isEmpty()) + if(!heightFileName.isEmpty()) { // Import heights from txt-file - if (heightFileName.right(4) == ".txt") + if(heightFileName.right(4) == ".txt") { QFile heightFile(heightFileName); - if (!heightFile.open(QIODevice::ReadOnly | QIODevice::Text)) + if(!heightFile.open(QIODevice::ReadOnly | QIODevice::Text)) { return "Could not open " + heightFileName.toStdString(); } @@ -66,23 +67,23 @@ std::variant<std::unordered_map<int, float>, std::string> IO::readHeightFile(con std::unordered_map<int, float> markerHeights; QTextStream in(&heightFile); - bool readHeader = false; - float conversionFactorToCM = 1.0F; + bool readHeader = false; + float conversionFactorToCM = 1.0F; - while (!in.atEnd()) + while(!in.atEnd()) { QString line = in.readLine(); // Process header/comment line - if( line.startsWith("#",Qt::CaseInsensitive)) + if(line.startsWith("#", Qt::CaseInsensitive)) { - if (!readHeader) + if(!readHeader) { - const QString& headerline = line; - if (headerline.contains("z/cm")) + const QString &headerline = line; + if(headerline.contains("z/cm")) { conversionFactorToCM = 1.0F; } - else if (headerline.contains("z/m")) + else if(headerline.contains("z/m")) { conversionFactorToCM = 100.0F; } @@ -92,39 +93,39 @@ std::variant<std::unordered_map<int, float>, std::string> IO::readHeightFile(con } // read line with format: [id height] - if (auto splitLine = line.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts); splitLine.size() == 2) + if(auto splitLine = line.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts); splitLine.size() == 2) { bool markerConverted = true; - int markerID = splitLine[0].toInt(&markerConverted); - if (!markerConverted) + int markerID = splitLine[0].toInt(&markerConverted); + if(!markerConverted) { return "Marker needs to be an integer value, but is " + splitLine[0].toStdString(); } - bool heightConverted = true; - float height = splitLine[1].toFloat(&heightConverted) * conversionFactorToCM; + bool heightConverted = true; + float height = splitLine[1].toFloat(&heightConverted) * conversionFactorToCM; - if (!heightConverted || height <= 0) + if(!heightConverted || height <= 0) { return "Height needs to be a positive numerical value, but is " + splitLine[1].toStdString(); } - if (auto inserted = markerHeights.insert(std::make_pair(markerID, height)); !inserted.second) + if(auto inserted = markerHeights.insert(std::make_pair(markerID, height)); !inserted.second) { return "Duplicate entry for markerID = " + std::to_string(markerID) + "."; } } else { - return "Line should contain exactly 2 values: id height. But it contains " - + std::to_string(splitLine.size()) + " entries."; + return "Line should contain exactly 2 values: id height. But it contains " + + std::to_string(splitLine.size()) + " entries."; } } heightFile.close(); return markerHeights; } - return "Cannot load " + heightFileName.toStdString() - + " maybe because of wrong file extension. Needs to be .txt."; + return "Cannot load " + heightFileName.toStdString() + + " maybe because of wrong file extension. Needs to be .txt."; } return "No file provided."; } @@ -140,9 +141,9 @@ std::variant<std::unordered_map<int, float>, std::string> IO::readHeightFile(con */ void IO::readMoCapC3D(MoCapStorage &storage, const MoCapPersonMetadata &metadata) { - MoCapPerson person; - const std::string& filename = metadata.getFilepath(); - MoCapSystem fp = metadata.getSystem(); + MoCapPerson person; + const std::string &filename = metadata.getFilepath(); + MoCapSystem fp = metadata.getSystem(); person.setMetadata(metadata); ezc3d::c3d c3d; @@ -150,9 +151,8 @@ void IO::readMoCapC3D(MoCapStorage &storage, const MoCapPersonMetadata &metadata { c3d = ezc3d::c3d{filename}; } - catch(const std::invalid_argument& e) + catch(const std::invalid_argument &e) { - std::stringstream ss; ss << "Error while reading C3D File " << filename << ": " << e.what() << '\n'; PCritical(nullptr, "Error: Cannot load C3D File", ss.str().c_str()); @@ -163,30 +163,35 @@ void IO::readMoCapC3D(MoCapStorage &storage, const MoCapPersonMetadata &metadata person.setTimeOffset(person.getMetadata().getOffset() - firstFrame / person.getMetadata().getSamplerate()); // getImagePoint takes points in cm -> cm as target unit - const std::string unit = c3d.parameters().group("POINT").parameter("UNITS").valuesAsString()[0]; - double conversionFactor = 1e-1; // default, since XSens uses this + const std::string unit = c3d.parameters().group("POINT").parameter("UNITS").valuesAsString()[0]; + double conversionFactor = 1e-1; // default, since XSens uses this if(unit == "mm") { conversionFactor = 1e-1; - }else if(unit == "cm") + } + else if(unit == "cm") { conversionFactor = 1.0; - }else if(unit == "m") + } + else if(unit == "m") { conversionFactor = 100.0; } - const auto c3dToPoint3f = [conversionFactor](const ezc3d::DataNS::Points3dNS::Point& point){ - return cv::Point3f{static_cast<float>(point.x()), - static_cast<float>(point.y()), - static_cast<float>(point.z())} * conversionFactor; + const auto c3dToPoint3f = [conversionFactor](const ezc3d::DataNS::Points3dNS::Point &point) + { + return cv::Point3f{ + static_cast<float>(point.x()), static_cast<float>(point.y()), static_cast<float>(point.z())} * + conversionFactor; }; - switch (fp) { + switch(fp) + { case XSensC3D: readSkeletonC3D_XSENS(c3d, person, c3dToPoint3f); break; - case END: break; // So clang doesn't say it isn't handled + case END: + break; // So clang doesn't say it isn't handled } storage.addPerson(person); @@ -203,10 +208,9 @@ void IO::readMoCapC3D(MoCapStorage &storage, const MoCapPersonMetadata &metadata * @param c3dToPoint3f[in] function which converts a c3d point to a cv::Point3f in cm */ void IO::readSkeletonC3D_XSENS( - const ezc3d::c3d &c3d, - MoCapPerson &person, - const std::function<cv::Point3f(const ezc3d::DataNS::Points3dNS::Point&)>& c3dToPoint3f - ) + const ezc3d::c3d & c3d, + MoCapPerson & person, + const std::function<cv::Point3f(const ezc3d::DataNS::Points3dNS::Point &)> &c3dToPoint3f) { /* * Points from XSens @@ -230,13 +234,13 @@ void IO::readSkeletonC3D_XSENS( * left heel: 59 * right toe: 58 * left toe: 64 - */ + */ - const auto& frames = c3d.data().frames(); + const auto &frames = c3d.data().frames(); - for(const auto& frame : frames) + for(const auto &frame : frames) { - const auto& points = frame.points().points(); + const auto & points = frame.points().points(); XSenseStruct skeletonStruct; skeletonStruct.mHipR = c3dToPoint3f(points[5]); skeletonStruct.mHipL = c3dToPoint3f(points[6]); @@ -284,13 +288,13 @@ void IO::readSkeletonC3D_XSENS( */ std::variant<std::unordered_map<int, int>, std::string> IO::readMarkerIDFile(const QString &markerFileName) { - if (!markerFileName.isEmpty()) + if(!markerFileName.isEmpty()) { // Import heights from txt-file - if (markerFileName.right(4) == ".txt") + if(markerFileName.right(4) == ".txt") { QFile markerFile(markerFileName); - if (!markerFile.open(QIODevice::ReadOnly | QIODevice::Text)) + if(!markerFile.open(QIODevice::ReadOnly | QIODevice::Text)) { return "Could not open " + markerFileName.toStdString(); } @@ -299,50 +303,50 @@ std::variant<std::unordered_map<int, int>, std::string> IO::readMarkerIDFile(con QTextStream in(&markerFile); - while (!in.atEnd()) + while(!in.atEnd()) { QString line = in.readLine(); // Skip header/comment line - if( line.startsWith("#",Qt::CaseInsensitive)) + if(line.startsWith("#", Qt::CaseInsensitive)) { continue; } // read line with format: [personID markerID] - if (auto splitLine = line.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts); splitLine.size() == 2) + if(auto splitLine = line.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts); splitLine.size() == 2) { bool personIDConverted = true; - int personID = splitLine[0].toInt(&personIDConverted); - if (!personIDConverted) + int personID = splitLine[0].toInt(&personIDConverted); + if(!personIDConverted) { return "PersonID needs to be an integer value, but is " + splitLine[0].toStdString(); } bool markerIDConverted = true; - int markerID = splitLine[1].toInt(&markerIDConverted); + int markerID = splitLine[1].toInt(&markerIDConverted); - if (!markerIDConverted ) + if(!markerIDConverted) { return "MarkerID needs to be an integer value, but is " + splitLine[1].toStdString(); } - if (auto inserted = markerIDs.insert(std::make_pair(personID, markerID)); !inserted.second) + if(auto inserted = markerIDs.insert(std::make_pair(personID, markerID)); !inserted.second) { return "Duplicate entry for personID = " + std::to_string(personID) + "."; } } else { - return "Line should contain exactly 2 values: personID markerID. But it contains " - + std::to_string(splitLine.size()) + " entries."; + return "Line should contain exactly 2 values: personID markerID. But it contains " + + std::to_string(splitLine.size()) + " entries."; } } markerFile.close(); return markerIDs; } - return "Cannot load " + markerFileName.toStdString() - + " maybe because of wrong file extension. Needs to be .txt."; + return "Cannot load " + markerFileName.toStdString() + + " maybe because of wrong file extension. Needs to be .txt."; } return "No file provided."; } @@ -354,21 +358,21 @@ std::variant<std::unordered_map<int, int>, std::string> IO::readMarkerIDFile(con * @param authorsFile zenodo metadata file containing the author information * @return list of authors */ -std::vector<std::string> IO::readAuthors(const QString & authorsFile) +std::vector<std::string> IO::readAuthors(const QString &authorsFile) { QFile file(authorsFile); file.open(QIODevice::ReadOnly); QJsonParseError parseError{}; - QJsonDocument jsonDocument = QJsonDocument::fromJson(file.readAll(), &parseError); + QJsonDocument jsonDocument = QJsonDocument::fromJson(file.readAll(), &parseError); std::vector<std::string> authors; - if (parseError.error == QJsonParseError::NoError) + if(parseError.error == QJsonParseError::NoError) { - QJsonObject root = jsonDocument.object(); - auto creators = root["creators"].toArray(); - for (auto author : creators) + QJsonObject root = jsonDocument.object(); + auto creators = root["creators"].toArray(); + for(auto author : creators) { QJsonObject node = author.toObject(); authors.push_back(node["name"].toString().toStdString()); @@ -381,4 +385,3 @@ std::vector<std::string> IO::readAuthors(const QString & authorsFile) return authors; } - diff --git a/src/aboutDialog.cpp b/src/aboutDialog.cpp index f63323dd2f61b527993bede9270da29676705153..438d5b18e72f5b0e0ed2b3f9388a33d5ee068a9b 100644 --- a/src/aboutDialog.cpp +++ b/src/aboutDialog.cpp @@ -23,17 +23,18 @@ #include "ui_about.h" -AboutDialog::AboutDialog(QWidget *parent, - const QString& version, - const QString & commitHash, - const QString& commitDate, - const QString & commitBranch, - const QString & compiler, - const QString & compilerVersion, - const QString & compileDate, - const std::vector<std::string> & authors) - : QDialog(parent), mUi(new Ui::About) { - +AboutDialog::AboutDialog( + QWidget * parent, + const QString & version, + const QString & commitHash, + const QString & commitDate, + const QString & commitBranch, + const QString & compiler, + const QString & compilerVersion, + const QString & compileDate, + const std::vector<std::string> &authors) : + QDialog(parent), mUi(new Ui::About) +{ mUi->setupUi(this); // perform additional setup here ... @@ -45,9 +46,10 @@ AboutDialog::AboutDialog(QWidget *parent, mUi->lblCompilerVersionValue->setText(compilerVersion); mUi->lblCompileDateValue->setText(compileDate); - for (std::size_t i = 0; i < authors.size(); ++i) { - int row = i/2ul; - int col = i%2ul; + for(std::size_t i = 0; i < authors.size(); ++i) + { + int row = i / 2ul; + int col = i % 2ul; auto *label = new QLabel(); label->setText(QString::fromStdString(authors[i])); mUi->lytAuthors->addWidget(label, row, col, 1, 1); diff --git a/src/analysePlot.cpp b/src/analysePlot.cpp index 739dab855cda96dceb9ebad1ed619149f4aecdcc..2853db3d13973b1b14d4c36e7ececa4489d4f7b8 100644 --- a/src/analysePlot.cpp +++ b/src/analysePlot.cpp @@ -18,30 +18,27 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QPainter> -#include <QMouseEvent> +#include "analysePlot.h" + +#include "animation.h" +#include "control.h" +#include "petrack.h" +#include <QMouseEvent> +#include <QPainter> +#include <qwt_compat.h> +#include <qwt_plot_grid.h> #include <qwt_plot_layout.h> #include <qwt_plot_zoomer.h> -#include <qwt_symbol.h> #include <qwt_scale_engine.h> -#include <qwt_plot_grid.h> -#include <qwt_compat.h> - -#include "analysePlot.h" -#include "control.h" -#include "petrack.h" -#include "animation.h" +#include <qwt_symbol.h> //----------------------------------------------------------------- -class AnalyseZoomer: public QwtPlotZoomer +class AnalyseZoomer : public QwtPlotZoomer { public: - AnalyseZoomer(int xAxis, int yAxis, QWidget *canvas) - : QwtPlotZoomer(xAxis, yAxis, canvas) + AnalyseZoomer(int xAxis, int yAxis, QWidget *canvas) : QwtPlotZoomer(xAxis, yAxis, canvas) { - - // RightButton: zoom out by 1 // Ctrl+RightButton: zoom out to full size @@ -50,34 +47,40 @@ public: setMousePattern(QwtEventPattern::MouseSelect3, Qt::RightButton); setRubberBand(QwtPicker::RectRubberBand); - setTrackerMode(QwtPicker::AlwaysOn); //ActiveOnly (only when the selection is active), AlwaysOff + setTrackerMode(QwtPicker::AlwaysOn); // ActiveOnly (only when the selection is active), AlwaysOff } void widgetMouseMoveEvent(QMouseEvent *e) override { static int lastX = -1; static int lastY = -1; - int dx = e->x()-lastX; - int dy = e->y()-lastY; + int dx = e->x() - lastX; + int dy = e->y() - lastY; lastX = e->x(); lastY = e->y(); - //if (e->button() == Qt::MidButton) fkt bei move nicht - if (e->buttons() == Qt::MiddleButton) + // if (e->button() == Qt::MidButton) fkt bei move nicht + if(e->buttons() == Qt::MiddleButton) { plot()->setAutoReplot(false); - for (int axis = 0; axis < QwtPlot::axisCnt; axis++) + for(int axis = 0; axis < QwtPlot::axisCnt; axis++) { - if (axis == QwtPlot::xBottom || axis == QwtPlot::yLeft) + if(axis == QwtPlot::xBottom || axis == QwtPlot::yLeft) { const QwtScaleMap map = plot()->canvasMap(axis); - const int i1 = map.transform(plot()->axisScaleDiv(axis).lowerBound()); // war in alter qwt version: axisScaleDiv(axis)->lBound() - const int i2 = map.transform(plot()->axisScaleDiv(axis).upperBound()); // war in alter qwt version: axisScaleDiv(axis)->hBound() + const int i1 = + map.transform(plot() + ->axisScaleDiv(axis) + .lowerBound()); // war in alter qwt version: axisScaleDiv(axis)->lBound() + const int i2 = + map.transform(plot() + ->axisScaleDiv(axis) + .upperBound()); // war in alter qwt version: axisScaleDiv(axis)->hBound() double d1, d2; - if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) + if(axis == QwtPlot::xBottom || axis == QwtPlot::xTop) { d1 = map.invTransform(i1 - dx); d2 = map.invTransform(i2 - dx); @@ -88,22 +91,21 @@ public: d2 = map.invTransform(i2 - dy); } - if ((axis == QwtPlot::xBottom) && (d2 > zoomBase().width())) + if((axis == QwtPlot::xBottom) && (d2 > zoomBase().width())) { - d1 = d1-(d2-zoomBase().width()); + d1 = d1 - (d2 - zoomBase().width()); d2 = zoomBase().width(); - } - else if ((axis == QwtPlot::yLeft) && (d2 > zoomBase().height())) + } + else if((axis == QwtPlot::yLeft) && (d2 > zoomBase().height())) { - d1 = d1-(d2-zoomBase().height()); + d1 = d1 - (d2 - zoomBase().height()); d2 = zoomBase().height(); - } + } plot()->setAxisScale(axis, d1, d2); } } plot()->setAutoReplot(true); plot()->replot(); - } QwtPlotZoomer::widgetMouseMoveEvent(e); } @@ -124,16 +126,17 @@ TrackerRealPlotItem::TrackerRealPlotItem() mTrackerReal = nullptr; } -void TrackerRealPlotItem::draw(QPainter* p, const QwtScaleMap& mapX, const QwtScaleMap& mapY, const QRectF& /*re*/) const +void TrackerRealPlotItem::draw(QPainter *p, const QwtScaleMap &mapX, const QwtScaleMap &mapY, const QRectF & /*re*/) + const { Control *controlWidget = ((AnalysePlot *) plot())->getControlWidget(); - if (mTrackerReal && (mTrackerReal->size() > 0) && controlWidget != nullptr) + if(mTrackerReal && (mTrackerReal->size() > 0) && controlWidget != nullptr) { - QRectF rect; - double sx = (mapX.p2() - mapX.p1())/(mapX.s2() - mapX.s1()); - double sy = (mapY.p2() - mapY.p1())/(mapY.s2() - mapY.s1()); - double circleSize = ((AnalysePlot *) plot())->symbolSize(); - int i, j; + QRectF rect; + double sx = (mapX.p2() - mapX.p1()) / (mapX.s2() - mapX.s1()); + double sy = (mapY.p2() - mapY.p1()) / (mapY.s2() - mapY.s1()); + double circleSize = ((AnalysePlot *) plot())->symbolSize(); + int i, j; QPointF point, lastPoint; p->save(); @@ -143,38 +146,38 @@ void TrackerRealPlotItem::draw(QPainter* p, const QwtScaleMap& mapX, const QwtSc p->setPen(Qt::red); - rect.setWidth(circleSize/sx); - rect.setHeight(circleSize/sy); - sx = circleSize/(2.*sx); - sy = circleSize/(2.*sy); + rect.setWidth(circleSize / sx); + rect.setHeight(circleSize / sy); + sx = circleSize / (2. * sx); + sy = circleSize / (2. * sy); - bool anaConsiderX = controlWidget->anaConsiderX->isChecked(); - bool anaConsiderY = controlWidget->anaConsiderY->isChecked(); + bool anaConsiderX = controlWidget->anaConsiderX->isChecked(); + bool anaConsiderY = controlWidget->anaConsiderY->isChecked(); bool anaConsiderAbs = controlWidget->anaConsiderAbs->isChecked(); bool anaConsiderRev = controlWidget->anaConsiderRev->isChecked(); // Beschriftung - static QFont f("Courier", 10, QFont::Normal); //Times Helvetica, Normal Bold - QwtText titleX("t [frame]", QwtText::RichText); //"x" TeXText - QwtText titleY; - if (anaConsiderX && anaConsiderY) + static QFont f("Courier", 10, QFont::Normal); // Times Helvetica, Normal Bold + QwtText titleX("t [frame]", QwtText::RichText); //"x" TeXText + QwtText titleY; + if(anaConsiderX && anaConsiderY) { titleY.setText("v [m/s]", QwtText::RichText); } - else if (anaConsiderX) + else if(anaConsiderX) { - if (anaConsiderAbs) + if(anaConsiderAbs) titleY.setText("v<sub>|x|</sub> [m/s]", QwtText::RichText); - else if (anaConsiderRev) + else if(anaConsiderRev) titleY.setText("v<sub>-x</sub> [m/s]", QwtText::RichText); else titleY.setText("v<sub>x</sub> [m/s]", QwtText::RichText); } else // == if (anaConsiderY) { - if (anaConsiderAbs) + if(anaConsiderAbs) titleY.setText("v<sub>|y|</sub> [m/s]", QwtText::RichText); - else if (anaConsiderRev) + else if(anaConsiderRev) titleY.setText("v<sub>-y</sub> [m/s]", QwtText::RichText); else titleY.setText("v<sub>y</sub> [m/s]", QwtText::RichText); @@ -182,74 +185,74 @@ void TrackerRealPlotItem::draw(QPainter* p, const QwtScaleMap& mapX, const QwtSc titleX.setFont(f); titleY.setFont(f); ((AnalysePlot *) plot())->setAxisTitle(QwtPlot::xBottom, titleX); //"x" - ((AnalysePlot *) plot())->setAxisTitle(QwtPlot::yLeft, titleY); //"y" + ((AnalysePlot *) plot())->setAxisTitle(QwtPlot::yLeft, titleY); //"y" - int step = controlWidget->anaStep->value(); //1 - int frame, animFrame, velVecActIdx = -1; - double vel; // geschwindigkeit - int largestLastFrame = mTrackerReal->largestLastFrame(); - QVector<int> velAnzVec(largestLastFrame, 0); + int step = controlWidget->anaStep->value(); // 1 + int frame, animFrame, velVecActIdx = -1; + double vel; // geschwindigkeit + int largestLastFrame = mTrackerReal->largestLastFrame(); + QVector<int> velAnzVec(largestLastFrame, 0); QVector<double> velVec(largestLastFrame, 0.); - int actFrame = ((AnalysePlot *) plot())->getActFrame(); - bool markAct = controlWidget->anaMarkAct->isChecked(); - double fps = controlWidget->getMainWindow()->getAnimation()->getFPS(); - if (fps < 0) - fps =DEFAULT_FPS; + int actFrame = ((AnalysePlot *) plot())->getActFrame(); + bool markAct = controlWidget->anaMarkAct->isChecked(); + double fps = controlWidget->getMainWindow()->getAnimation()->getFPS(); + if(fps < 0) + fps = DEFAULT_FPS; - if (!markAct) + if(!markAct) { p->setPen(Qt::green); p->setBrush(Qt::green); } - for (i = 0; i < mTrackerReal->size(); ++i) + for(i = 0; i < mTrackerReal->size(); ++i) { - for (j = 0; j < mTrackerReal->at(i).size()-step; ++j) // -step, damit geschwindigkeit ermittelt werden kann + for(j = 0; j < mTrackerReal->at(i).size() - step; ++j) // -step, damit geschwindigkeit ermittelt werden kann { - frame = mTrackerReal->at(i).firstFrame()+j; + frame = mTrackerReal->at(i).firstFrame() + j; animFrame = mTrackerReal->at(i).at(j).frameNum(); // ohne eingefuegte frames bei auslassungen - if (markAct) + if(markAct) { - if (animFrame == actFrame) + if(animFrame == actFrame) { p->setPen(Qt::red); p->setBrush(Qt::red); velVecActIdx = frame; } - else //if (frame == actFrame+1) + else // if (frame == actFrame+1) { p->setPen(Qt::green); p->setBrush(Qt::green); } } - if (anaConsiderX && anaConsiderY) + if(anaConsiderX && anaConsiderY) { - vel = (mTrackerReal->at(i).at(j+step).distanceToPoint(mTrackerReal->at(i).at(j))); + vel = (mTrackerReal->at(i).at(j + step).distanceToPoint(mTrackerReal->at(i).at(j))); } - else if (anaConsiderX) + else if(anaConsiderX) { - if (anaConsiderAbs) - vel = fabs((mTrackerReal->at(i).at(j+step).x()-mTrackerReal->at(i).at(j).x())); - else if (anaConsiderRev) - vel = (mTrackerReal->at(i).at(j).x()-mTrackerReal->at(i).at(j+step).x()); + if(anaConsiderAbs) + vel = fabs((mTrackerReal->at(i).at(j + step).x() - mTrackerReal->at(i).at(j).x())); + else if(anaConsiderRev) + vel = (mTrackerReal->at(i).at(j).x() - mTrackerReal->at(i).at(j + step).x()); else - vel = (mTrackerReal->at(i).at(j+step).x()-mTrackerReal->at(i).at(j).x()); + vel = (mTrackerReal->at(i).at(j + step).x() - mTrackerReal->at(i).at(j).x()); } else // == if (anaConsiderY) { - if (anaConsiderAbs) - vel = fabs((mTrackerReal->at(i).at(j+step).y()-mTrackerReal->at(i).at(j).y())); - else if (anaConsiderRev) - vel = (mTrackerReal->at(i).at(j).y()-mTrackerReal->at(i).at(j+step).y()); + if(anaConsiderAbs) + vel = fabs((mTrackerReal->at(i).at(j + step).y() - mTrackerReal->at(i).at(j).y())); + else if(anaConsiderRev) + vel = (mTrackerReal->at(i).at(j).y() - mTrackerReal->at(i).at(j + step).y()); else - vel = (mTrackerReal->at(i).at(j+step).y()-mTrackerReal->at(i).at(j).y()); + vel = (mTrackerReal->at(i).at(j + step).y() - mTrackerReal->at(i).at(j).y()); } - vel /=((100./fps)*step); // m/s, war: 100cm/25frames =4 => vel /=(4.*step); + vel /= ((100. / fps) * step); // m/s, war: 100cm/25frames =4 => vel /=(4.*step); point.setX(frame); point.setY(vel); - rect.moveLeft(point.x()-sx); - rect.moveTop(point.y()-sy); + rect.moveLeft(point.x() - sx); + rect.moveTop(point.y() - sy); p->drawEllipse(rect); // j - j+step, da gegen die x-achse gelaufen wird @@ -259,23 +262,23 @@ void TrackerRealPlotItem::draw(QPainter* p, const QwtScaleMap& mapX, const QwtSc } } - rect.setWidth(2*rect.width()); - rect.setHeight(2*rect.height()); + rect.setWidth(2 * rect.width()); + rect.setHeight(2 * rect.height()); p->setPen(Qt::blue); p->setBrush(Qt::blue); - for (i = 0; i < velAnzVec.size(); ++i) + for(i = 0; i < velAnzVec.size(); ++i) { - if (velAnzVec[i] != 0) + if(velAnzVec[i] != 0) { point.setX(i); - point.setY(velVec[i]/velAnzVec[i]); - if ((i != 0) && (velAnzVec[i-1] != 0)) // nicht ganz hundertprozentig + point.setY(velVec[i] / velAnzVec[i]); + if((i != 0) && (velAnzVec[i - 1] != 0)) // nicht ganz hundertprozentig p->drawLine(lastPoint, point); lastPoint = point; - if (markAct && (i == velVecActIdx)) + if(markAct && (i == velVecActIdx)) { - rect.moveLeft(point.x()-2*sx); - rect.moveTop(point.y()-2*sy); + rect.moveLeft(point.x() - 2 * sx); + rect.moveTop(point.y() - 2 * sy); p->drawEllipse(rect); } } @@ -298,90 +301,90 @@ void TrackerRealPlotItem::setTrackerReal(TrackerReal *trackerReal) //----------------------------------------------------------------------------------------- AnalysePlot::AnalysePlot(QWidget *parent) // default= NULL - : QwtPlot(parent) + : + QwtPlot(parent) { setAutoReplot(false); setCanvasBackground(QColor(QColor(220, 220, 255))); mControlWidget = nullptr; - mSymbolSize = 3.; - mActFrame = 0; + mSymbolSize = 3.; + mActFrame = 0; // default in controlWidget - ansonsten wird es in plotitem geaendert - QFont f("Courier", 10, QFont::Normal); //Times Helvetica, Normal Bold - QwtText titleX("t [frame]", QwtText::RichText); //"x" TeXText + QFont f("Courier", 10, QFont::Normal); // Times Helvetica, Normal Bold + QwtText titleX("t [frame]", QwtText::RichText); //"x" TeXText QwtText titleY("v<sub>y</sub> [m/s]", QwtText::RichText); //"y" titleX.setFont(f); titleY.setFont(f); setAxisTitle(xBottom, titleX); //"x" - setAxisTitle(yLeft, titleY); //"y" + setAxisTitle(yLeft, titleY); //"y" plotLayout()->setAlignCanvasToScales(true); - mZoomer = new AnalyseZoomer(xBottom, yLeft, canvas()); //QwtPlotZoomer + mZoomer = new AnalyseZoomer(xBottom, yLeft, canvas()); // QwtPlotZoomer mTrackerRealItem = new TrackerRealPlotItem(); mTrackerRealItem->setZ(1); mTrackerRealItem->attach(this); - // grid + // grid QwtPlotGrid *grid = new QwtPlotGrid; grid->enableXMin(true); grid->enableYMin(true); grid->setMajorPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); - grid->setMinorPen(QPen(QColor(170, 170, 170), 0 , Qt::DotLine)); + grid->setMinorPen(QPen(QColor(170, 170, 170), 0, Qt::DotLine)); grid->setZ(0); grid->attach(this); - } QPoint AnalysePlot::getPos(const QColor &col) const { QPoint p; - if (mControlWidget) + if(mControlWidget) { - int x = mControlWidget->recoColorX->currentIndex(); - int y = mControlWidget->recoColorY->currentIndex(); + int x = mControlWidget->recoColorX->currentIndex(); + int y = mControlWidget->recoColorY->currentIndex(); int ymax = (int) yMax(); - if (mControlWidget->recoColorModel->currentIndex() == 0) // HSV + if(mControlWidget->recoColorModel->currentIndex() == 0) // HSV { - if (x==0) // nicht setX und setY, weil das width und height anpasst + if(x == 0) // nicht setX und setY, weil das width und height anpasst p.setX(col.hue()); - else if (x==1) + else if(x == 1) p.setX(col.saturation()); else p.setX(col.value()); - if (y==0) - p.setY(ymax-col.hue()); - else if (y==1) - p.setY(ymax-col.saturation()); + if(y == 0) + p.setY(ymax - col.hue()); + else if(y == 1) + p.setY(ymax - col.saturation()); else - p.setY(ymax-col.value()); + p.setY(ymax - col.value()); } else // RGB { - if (x==0) + if(x == 0) p.setX(col.red()); - else if (x==1) + else if(x == 1) p.setX(col.green()); else p.setX(col.blue()); - if (y==0) - p.setY(ymax-col.red()); - else if (y==1) - p.setY(ymax-col.green()); + if(y == 0) + p.setY(ymax - col.red()); + else if(y == 1) + p.setY(ymax - col.green()); else - p.setY(ymax-col.blue()); + p.setY(ymax - col.blue()); } } return p; } -void AnalysePlot::setTrackerReal(TrackerReal* trackerReal) +void AnalysePlot::setTrackerReal(TrackerReal *trackerReal) { mTrackerReal = trackerReal; mTrackerRealItem->setTrackerReal(trackerReal); @@ -389,19 +392,20 @@ void AnalysePlot::setTrackerReal(TrackerReal* trackerReal) void AnalysePlot::setScale() { - if (mControlWidget) + if(mControlWidget) { - - int frameNum = mTrackerReal->largestLastFrame(); //mControlWidget->getMainWindow()->getAnimation()->getNumFrames(); - mXMin = mTrackerReal->smallestFirstFrame()-10; //0-spacerX; - mXMax = frameNum+10; //frameNum+spacerX; - mYMin = -0.2; //0-spacerY; - mYMax = 2.; //2+spacerY; + int frameNum = + mTrackerReal->largestLastFrame(); // mControlWidget->getMainWindow()->getAnimation()->getNumFrames(); + mXMin = mTrackerReal->smallestFirstFrame() - 10; // 0-spacerX; + mXMax = frameNum + 10; // frameNum+spacerX; + mYMin = -0.2; // 0-spacerY; + mYMax = 2.; // 2+spacerY; setAxisScale(QwtPlot::xBottom, mXMin, mXMax); setAxisScale(QwtPlot::yLeft, mYMin, mYMax); - replot(); // why, see: file:///C:/Programme/qwt-5.0.2/doc/html/class_qwt_plot_zoomer.html#7a1711597f441223efdb7d9931fe19b9 - mZoomer->setZoomBase(QwtDoubleRect(mXMin, mYMin, mXMax-mXMin, mYMax-mYMin)); + replot(); // why, see: + // file:///C:/Programme/qwt-5.0.2/doc/html/class_qwt_plot_zoomer.html#7a1711597f441223efdb7d9931fe19b9 + mZoomer->setZoomBase(QwtDoubleRect(mXMin, mYMin, mXMax - mXMin, mYMax - mYMin)); } } diff --git a/src/animation.cpp b/src/animation.cpp index e33a579f9008541c3e83e84da97dd4bc32b9ed8f..391cc9ff0e5eb360462f707c12c06596f7722ae6 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -27,29 +27,27 @@ Edited by: Ricardo Martin Brualla, 01.02.2007 This class will hold an animation in form of a video or a sequence of images. In case of a video, you can only get the next frame. If it is a sequence of images, you can select the frame you want to get. -Appart from that, there is a static function that converts IplImages to QImage, so +Appart from that, there is a static function that converts IplImages to QImage, so they can be represented in QT. */ #include "animation.h" -#include <QWidget> +#include "filter.h" +#include "helper.h" +#include "pMessageBox.h" +#include "petrack.h" + +#include <QDir> +#include <QFileInfo> +#include <QRegExp> #include <QSize> #include <QStringList> -#include <QRegExp> -#include <QFileInfo> -#include <QDir> #include <QTime> - -#include <sstream> +#include <QWidget> #include <iomanip> - #include <opencv2/opencv.hpp> - -#include "pMessageBox.h" -#include "filter.h" -#include "helper.h" -#include "petrack.h" +#include <sstream> /**********************************************************************/ /* Constructors & Destructors **/ @@ -57,19 +55,18 @@ they can be represented in QT. Animation::Animation(QWidget *wParent) { - mMainWindow = (class Petrack*) wParent; - mVideo = false; - mStereo = false; - mImgSeq = false; + mMainWindow = (class Petrack *) wParent; + mVideo = false; + mStereo = false; + mImgSeq = false; mCameraLiveStream = false; - mCurrentFrame = -1; - mMaxFrames = -1; - mSourceInFrame = -1; - mSourceOutFrame = -1; - mFps = -1; - mFirstSec = -1; - mFirstMicroSec = -1; - ////mCapture = NULL; + mCurrentFrame = -1; + mMaxFrames = -1; + mSourceInFrame = -1; + mSourceOutFrame = -1; + mFps = -1; + mFirstSec = -1; + mFirstMicroSec = -1; #ifndef STEREO_DISABLED mCaptureStereo = nullptr; #endif @@ -81,12 +78,12 @@ Animation::Animation(QWidget *wParent) Animation::~Animation() { - if (mImgSeq) + if(mImgSeq) freePhoto(); - if (mVideo || mCameraLiveStream) + if(mVideo || mCameraLiveStream) freeVideo(); - mSourceInFrame = -1; + mSourceInFrame = -1; mSourceOutFrame = -1; } @@ -97,32 +94,34 @@ Animation::~Animation() /// Returns the next frame of the animation cv::Mat Animation::getNextFrame() { - return getFrameAtIndex(mCurrentFrame+1); + return getFrameAtIndex(mCurrentFrame + 1); } /// Returns the previous frame of the animation cv::Mat Animation::getPreviousFrame() { - return getFrameAtIndex(mCurrentFrame-1); + return getFrameAtIndex(mCurrentFrame - 1); } /// Returns the frame at the index index cv::Mat Animation::getFrameAtIndex(int index) { - if (mCameraLiveStream) + if(mCameraLiveStream) return getFrameVideo(index); // geaendert: We make sure first the index is valid. // If not, it will be set the first or the last index - if (index<getSourceInFrameNum()){ + if(index < getSourceInFrameNum()) + { return cv::Mat(); } - if (index>getSourceOutFrameNum()){ + if(index > getSourceOutFrameNum()) + { return cv::Mat(); } // Call the own methods to get it done - if (mVideo) + if(mVideo) return getFrameVideo(index); - if (mImgSeq) + if(mImgSeq) return getFramePhoto(index); return cv::Mat(); } @@ -135,7 +134,7 @@ cv::Mat Animation::getFrameAtIndex(int index) */ cv::Mat Animation::getFrameAtPos(double position) { - return getFrameAtIndex((int) (getSourceInFrameNum()+(position*(getNumFrames()-1)))); + return getFrameAtIndex((int) (getSourceInFrameNum() + (position * (getNumFrames() - 1)))); } /// Returns the current frame @@ -157,18 +156,23 @@ cv::Mat Animation::getCurrentFrame() */ void Animation::skipFrame(int num) { - if(isImageSequence()){ + if(isImageSequence()) + { int lastFrameNum = getSourceOutFrameNum(); - if(mCurrentFrame + num > lastFrameNum){ + if(mCurrentFrame + num > lastFrameNum) + { mCurrentFrame = lastFrameNum; - }else{ + } + else + { mCurrentFrame += num; } for(int i = 0; i < num; ++i) { mMainWindow->updateShowFPS(true); } - }else if(mVideoCapture.isOpened()) + } + else if(mVideoCapture.isOpened()) { int lastFrameNum = getSourceOutFrameNum(); for(int i = 0; i < num && mCurrentFrame < lastFrameNum; ++i) @@ -189,70 +193,80 @@ void Animation::skipFrame(int num) bool Animation::openTimeFile(QString &timeFileName) { QFile file(timeFileName); - int fcycSec=-1, fcycCount=-1; // fuer erstes frame - int lframe=-1 , lcycSec=-1, lcycCount=-1; // fuer vorangegangenen frame - int frame=-1 , cycSec=-1, cycCount=-1, cycOffset=-1, sec=-1, microSec=-1, bufIndex=-1, bufSeqNum=-1, seqNum=-1; - int dum, add=0; - double fps, dif, difMin=1000., difMax=-1000.; - int minFrame=-1, maxFrame=-1; + int fcycSec = -1, fcycCount = -1; // fuer erstes frame + int lframe = -1, lcycSec = -1, lcycCount = -1; // fuer vorangegangenen frame + int frame = -1, cycSec = -1, cycCount = -1, cycOffset = -1, sec = -1, microSec = -1, bufIndex = -1, bufSeqNum = -1, + seqNum = -1; + int dum, add = 0; + double fps, dif, difMin = 1000., difMax = -1000.; + int minFrame = -1, maxFrame = -1; debout << "Found corresponding time file " << timeFileName << std::endl; - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - debout << " Error: Cannot open existing time file " << timeFileName << ":" << std::endl << " " << file.errorString() << std::endl; + debout << " Error: Cannot open existing time file " << timeFileName << ":" << std::endl + << " " << file.errorString() << std::endl; return false; } else { QTextStream in(&file); - QDateTime dt; + QDateTime dt; in >> dum; // einlesen des ersten Wertes eines Zeile, um leerzeilen trotz nicht-Dateiende zu erkennen! - while (!in.atEnd()) + while(!in.atEnd()) { frame = dum; in >> cycSec >> cycCount >> cycOffset >> sec >> microSec >> bufIndex >> bufSeqNum >> seqNum; - if (frame == 0) + if(frame == 0) { - fcycSec=cycSec; fcycCount=cycCount; + fcycSec = cycSec; + fcycCount = cycCount; dt.setTime_t(sec); debout << " Recording starts at " << dt.toString("dd.MM.yyyy hh:mm:ss."); std::cout << std::setw(6) << std::setfill('0') << microSec << std::endl; - mFirstSec = sec; + mFirstSec = sec; mFirstMicroSec = microSec; } else { // minimale maximale Zeitabstaende zwischen frames bestimmen - cyc... sind genauere zeiten vom bus - if (lcycSec > cycSec) // wrap around after 128s + if(lcycSec > cycSec) // wrap around after 128s { - dif = (cycSec-lcycSec+128)+(cycCount-lcycCount)/8000.; + dif = (cycSec - lcycSec + 128) + (cycCount - lcycCount) / 8000.; add += 128; } else - dif = (cycSec-lcycSec)+(cycCount-lcycCount)/8000.; - if (dif > difMax) + dif = (cycSec - lcycSec) + (cycCount - lcycCount) / 8000.; + if(dif > difMax) { - difMax = dif; + difMax = dif; maxFrame = lframe; } - if (dif < difMin) + if(dif < difMin) { - difMin = dif; + difMin = dif; minFrame = lframe; } } - lframe=frame; lcycSec=cycSec; lcycCount=cycCount; + lframe = frame; + lcycSec = cycSec; + lcycCount = cycCount; in >> dum; } dt.setTime_t(sec); - fps = frame/((cycSec-fcycSec+add)+(cycCount-fcycCount)/8000.); - debout << " Recording ends at " << dt.toString("dd.MM.yyyy hh:mm:ss."); // entspricht nicht der in statusbar angezeigten zeit des letzten frames, da in statusbar fps und frameanzahl herangezogen wird (genauer)!!! + fps = frame / ((cycSec - fcycSec + add) + (cycCount - fcycCount) / 8000.); + debout << " Recording ends at " + << dt.toString( + "dd.MM.yyyy hh:mm:ss."); // entspricht nicht der in statusbar angezeigten zeit des letzten frames, + // da in statusbar fps und frameanzahl herangezogen wird (genauer)!!! std::cout << std::setw(6) << std::setfill('0') << microSec << std::endl; - debout << " Fps with "<< frame+1 <<" frames: " << fps << " (min "<<1./difMax<<" at frame "<<maxFrame<<" to "<<maxFrame+1<<", max "<<1./difMin<<" at frame "<<minFrame<<" to "<<minFrame+1<<")" << std::endl; + debout << " Fps with " << frame + 1 << " frames: " << fps << " (min " << 1. / difMax << " at frame " + << maxFrame << " to " << maxFrame + 1 << ", max " << 1. / difMin << " at frame " << minFrame << " to " + << minFrame + 1 << ")" << std::endl; setFPS(fps); - mStereo = true; - mSourceOutFrame = frame; //mNumFrames = frame+1; + mStereo = true; + mSourceOutFrame = frame; // mNumFrames = frame+1; file.close(); return true; @@ -277,22 +291,22 @@ int Animation::getFirstFrameMicroSec() const */ QString Animation::getTimeString(int frame) { - if (frame == -1) + if(frame == -1) frame = getCurrentFrameNum(); - if (mFirstSec != -1) // stereo video from arena with 16 fps + if(mFirstSec != -1) // stereo video from arena with 16 fps { QDateTime dt; - int deziMilliSec = frame%16*625 + mFirstMicroSec/100; // 625 = 10000/16 - dt.setTime_t(mFirstSec + frame/16 + deziMilliSec/10000); - return (dt.toString("dd.MM.yyyy hh:mm:ss")+".%1").arg(deziMilliSec%10000, 4, 10, QChar('0')); + int deziMilliSec = frame % 16 * 625 + mFirstMicroSec / 100; // 625 = 10000/16 + dt.setTime_t(mFirstSec + frame / 16 + deziMilliSec / 10000); + return (dt.toString("dd.MM.yyyy hh:mm:ss") + ".%1").arg(deziMilliSec % 10000, 4, 10, QChar('0')); } else { - int sec = (int) (frame/mFps); - QTime t(0,0,0); + int sec = (int) (frame / mFps); + QTime t(0, 0, 0); t = t.addSecs(sec); - return (t.toString("hh:mm:ss")+".%1").arg(myRound(((frame/mFps)-sec)*10000), 4, 10, QChar('0')); + return (t.toString("hh:mm:ss") + ".%1").arg(myRound(((frame / mFps) - sec) * 10000), 4, 10, QChar('0')); } } @@ -303,78 +317,70 @@ QString Animation::getTimeString(int frame) */ bool Animation::openAnimation(QString fileName) { - QFileInfo fileInfo(fileName); // First of all : does the file exist? - if (fileInfo.exists()) + if(fileInfo.exists()) { - bool openRet = false; - QString timeFileName = fileName.left(fileName.lastIndexOf("cam")+4)+".time"; + bool openRet = false; + QString timeFileName = fileName.left(fileName.lastIndexOf("cam") + 4) + ".time"; QFileInfo fileTimeInfo(timeFileName); - if (fileTimeInfo.exists()) + if(fileTimeInfo.exists()) { mTimeFileLoaded = openTimeFile(timeFileName); } - // Modify it to open other video extensions! - //if ((fileName.right(4).toLower() == ".avi") || - // (fileName.right(4).toLower() == ".mov") || - // (fileName.right(4).toLower() == ".mts") || - // (fileName.right(5).toLower() == ".m2ts") || - // (fileName.right(4).toLower() == ".wmv") || - // (fileName.right(4).toLower() == ".mp4") ) - //{ // now all videos will be try to open with OpenCV openRet = openAnimationPhoto(fileName); - //} + // If it is not a video, then is a photo :-) - //else - if (openRet == false) // es konnte keine Bildsequenz geladen werden + if(openRet == false) // es konnte keine Bildsequenz geladen werden openRet = openAnimationVideo(fileName); - if (mTimeFileLoaded && !openRet) - debout << "Warning: New loaded time file do not correspond to untouched sequence, because new sequence was not loadable!" << std::endl; + if(mTimeFileLoaded && !openRet) + debout << "Warning: New loaded time file do not correspond to untouched sequence, because new sequence was " + "not loadable!" + << std::endl; mTimeFileLoaded = false; // reset for new open stereo video sequence return openRet; } - else + else return false; } /// Opens a camera livestream bool Animation::openCameraStream(int camID) { - if( !mVideoCapture.open(camID) ) - { - return false; - }else - { + if(!mVideoCapture.open(camID)) + { + return false; + } + else + { // Destroy anything that was before free(); // Set new video & photo labels - mStereo = false; - mVideo = true; - mImgSeq = false; + mStereo = false; + mVideo = true; + mImgSeq = false; mCameraLiveStream = true; mCurrentFrame = -1; // Get the information of the animation - if (!getCameraInfo()) - return false; - - } - return true; + if(!getCameraInfo()) + return false; + } + return true; } /// Returns the number of frames in the current animation int Animation::getNumFrames() { - if (mVideo || mImgSeq || mStereo) - return getSourceOutFrameNum()-getSourceInFrameNum()+1;//return mNumFrames; + if(mVideo || mImgSeq || mStereo) + return getSourceOutFrameNum() - getSourceInFrameNum() + 1; // return mNumFrames; return 0; } int Animation::getMaxFrames() const { - if (mVideo || mImgSeq) + if(mVideo || mImgSeq) return mMaxFrames; return 0; } @@ -418,10 +424,10 @@ int Animation::getSourceOutFrameNum() const /// Returns the filename of the current frame QString Animation::getCurrentFileName() { - if (mCameraLiveStream) + if(mCameraLiveStream) return QString("camera live stream"); - if (!mImgFilesList.isEmpty() && mImgSeq) + if(!mImgFilesList.isEmpty() && mImgSeq) { if(mCurrentFrame < getSourceInFrameNum() || mCurrentFrame > getSourceOutFrameNum()) return QFileInfo(mImgFilesList.at(getSourceInFrameNum())).fileName(); @@ -435,16 +441,16 @@ QString Animation::getCurrentFileName() /// Returns the FPS of the current animation double Animation::getFPS() { - if (mCameraLiveStream) + if(mCameraLiveStream) { - if (mVideoCapture.get(cv::CAP_PROP_FPS)) + if(mVideoCapture.get(cv::CAP_PROP_FPS)) setFPS(mVideoCapture.get(cv::CAP_PROP_FPS)); } - if (mVideo) + if(mVideo) return mFps; - else if (mImgSeq) + else if(mImgSeq) { - if (mFps == -1) + if(mFps == -1) return DEFAULT_FPS; // we assume images from pal video (germany) else return mFps; // if we found a corresponding .time file for the bumblebee xb3 @@ -467,7 +473,7 @@ void Animation::setFPS(double fps) /// Returns the size of the original frames (could made bigger after filtering) QSize Animation::getSize() { - if (mVideo || mImgSeq) + if(mVideo || mImgSeq) return mSize; else { @@ -480,12 +486,12 @@ QSize Animation::getSize() /// free's all the data in animation void Animation::free() { - if (mImgSeq) + if(mImgSeq) freePhoto(); - if (mVideo || mCameraLiveStream) + if(mVideo || mCameraLiveStream) freeVideo(); - mSourceInFrame = -1; + mSourceInFrame = -1; mSourceOutFrame = -1; } @@ -493,17 +499,17 @@ void Animation::reset() { free(); - mVideo = false; - mStereo = false; - mImgSeq = false; + mVideo = false; + mStereo = false; + mImgSeq = false; mCameraLiveStream = false; - mCurrentFrame = -1; - mMaxFrames = -1; - mSourceInFrame = -1; - mSourceOutFrame = -1; - mFps = -1; - mFirstSec = -1; - mFirstMicroSec = -1; + mCurrentFrame = -1; + mMaxFrames = -1; + mSourceInFrame = -1; + mSourceOutFrame = -1; + mFps = -1; + mFirstSec = -1; + mFirstMicroSec = -1; #ifndef STEREO_DISABLED mCaptureStereo = nullptr; #endif @@ -549,7 +555,7 @@ bool Animation::isCameraLiveStream() const #ifndef STEREO_DISABLED enum Camera Animation::getCamera() { - if (mCaptureStereo != nullptr) + if(mCaptureStereo != nullptr) return mCaptureStereo->getCamera(); else return cameraUnset; @@ -557,9 +563,10 @@ enum Camera Animation::getCamera() void Animation::setCamera(enum Camera c) { - if (mCaptureStereo != nullptr) + if(mCaptureStereo != nullptr) return mCaptureStereo->setCamera(c); - //else //keine Warnung, damit bei Projekt ohne direkt geladenem Video aber setzen von Stereo-Einstellungen keine Warnung ausgegeben wird + // else //keine Warnung, damit bei Projekt ohne direkt geladenem Video aber setzen von Stereo-Einstellungen keine + // Warnung ausgegeben wird // debout << "Warning: Setting camera is only allowed for loaded stereo videos!" << endl; } #endif @@ -572,56 +579,57 @@ bool Animation::openAnimationPhoto(QString fileName) // check, if cv can open one animation file cv::Mat tempMat; - tempMat = cv::imread(fileName.toStdString(),cv::IMREAD_UNCHANGED);//, IMREAD_UNCHANGED);//CV_LOAD_IMAGE_UNCHANGED); + tempMat = + cv::imread(fileName.toStdString(), cv::IMREAD_UNCHANGED); //, IMREAD_UNCHANGED);//CV_LOAD_IMAGE_UNCHANGED); // Check for invalid input - if(! tempMat.data ) + if(!tempMat.data) { return false; } - if( tempMat.channels() == 4 ){ + if(tempMat.channels() == 4) + { std::cout << "Warning: PNG-Alpha channel will be ignored." << std::endl; - tempMat = cv::imread(fileName.toStdString(),cv::IMREAD_COLOR); + tempMat = cv::imread(fileName.toStdString(), cv::IMREAD_COLOR); } - // Destroy anything that was before + // Destroy anything that was before free(); // Set new video & photo labels - mVideo = false; - mStereo = false; - mImgSeq = true; + mVideo = false; + mStereo = false; + mImgSeq = true; mCameraLiveStream = false; // Accessing to file information and directory information mFileInfo = QFileInfo(fileName); - QDir dir = mFileInfo.dir(); + QDir dir = mFileInfo.dir(); // Get all files in the same directory - QList<QFileInfo> fileList = dir.entryInfoList(QDir::Files,QDir::Name); + QList<QFileInfo> fileList = dir.entryInfoList(QDir::Files, QDir::Name); // series1_0002-left => split into series1_|0002|-left // regexp is greedy - from left to right try to get the most characters QRegExp regExp("(?:[0-9]*)([^0-9]*)$"); //(?: ) zum ignorieren QString front, back; - int frontLen, frontLenList; - if ((frontLen = regExp.indexIn(mFileInfo.completeBaseName())) > -1) + int frontLen, frontLenList; + if((frontLen = regExp.indexIn(mFileInfo.completeBaseName())) > -1) { front = mFileInfo.completeBaseName().left(frontLen); - back = regExp.cap(1); + back = regExp.cap(1); } else // does not match regExp at all return false; mFileBase = front + back; // completeBaseName to cut suffix and sequence number - // Create a new image files list + // Create a new image files list mImgFilesList.clear(); - for (int i = 0; i < fileList.size(); i++) + for(int i = 0; i < fileList.size(); i++) { - if ((frontLenList = regExp.indexIn(fileList.at(i).completeBaseName())) > -1) + if((frontLenList = regExp.indexIn(fileList.at(i).completeBaseName())) > -1) { // Is the file in the series? - if ((fileList.at(i).completeBaseName().left(frontLenList) == front) && - (regExp.cap(1) == back) && - (fileList.at(i).suffix() == mFileInfo.suffix())) + if((fileList.at(i).completeBaseName().left(frontLenList) == front) && (regExp.cap(1) == back) && + (fileList.at(i).suffix() == mFileInfo.suffix())) { mImgFilesList << fileList.at(i).filePath(); } @@ -629,7 +637,7 @@ bool Animation::openAnimationPhoto(QString fileName) } // Get the information of the animation - if (!getInfoPhoto()) + if(!getInfoPhoto()) return false; // Set the current frame to -1 (shows, that no frame is already loaded) mCurrentFrame = -1; @@ -644,36 +652,43 @@ bool Animation::openAnimationPhoto(QString fileName) */ cv::Mat Animation::getFramePhoto(int index) { - if ((index != mCurrentFrame) || mImage.empty()) + if((index != mCurrentFrame) || mImage.empty()) { // Check if the index is valid if(index < getSourceInFrameNum() || index > getSourceOutFrameNum()) return cv::Mat(); - mImage = cv::imread(mImgFilesList.at(index).toStdString(),cv::IMREAD_UNCHANGED);//CV_LOAD_IMAGE_UNCHANGED); + mImage = cv::imread(mImgFilesList.at(index).toStdString(), cv::IMREAD_UNCHANGED); // CV_LOAD_IMAGE_UNCHANGED); // Check for invalid input - if( mImage.empty() ) // Check for invalid input + if(mImage.empty()) // Check for invalid input { - debout << "Could not open or find the image" << std::endl ; + debout << "Could not open or find the image" << std::endl; return cv::Mat(); } - if( mImage.channels() == 4 ) + if(mImage.channels() == 4) { - mImage = imread(mImgFilesList.at(index).toStdString(),cv::IMREAD_COLOR); + mImage = imread(mImgFilesList.at(index).toStdString(), cv::IMREAD_COLOR); } // Check image size of each frame - if( (mSize.width() > 0 && mSize.height() > 0) && (mImage.cols != mSize.width() || mImage.rows != mSize.height()) ) + if((mSize.width() > 0 && mSize.height() > 0) && (mImage.cols != mSize.width() || mImage.rows != mSize.height())) { debout << "Could not load image: image size differs in image sequence" << std::endl; debout << "Please ensure to have images of the same size!" << std::endl; - PCritical(nullptr,"An error has occurred!", - QString("The size of the images in the selected image sequence does not agree." - "<br /><br />[0]: %1 (%2x%3 pixel)<br />[%4]: %5 (%6x%7 pixel)") - .arg(mImgFilesList.at(0)).arg(mSize.width()).arg(mSize.height()).arg(index) - .arg(mImgFilesList.at(index)).arg(mImage.cols).arg(mImage.rows)); + PCritical( + nullptr, + "An error has occurred!", + QString("The size of the images in the selected image sequence does not agree." + "<br /><br />[0]: %1 (%2x%3 pixel)<br />[%4]: %5 (%6x%7 pixel)") + .arg(mImgFilesList.at(0)) + .arg(mSize.width()) + .arg(mSize.height()) + .arg(index) + .arg(mImgFilesList.at(index)) + .arg(mImage.cols) + .arg(mImage.rows)); return cv::Mat(); } @@ -695,21 +710,22 @@ cv::Mat Animation::getFramePhoto(int index) */ bool Animation::getInfoPhoto() { - bool rc = false; + bool rc = false; cv::Mat tempImg; // Set the number of frames mMaxFrames = mImgFilesList.size(); setSourceInFrameNum(0); - setSourceOutFrameNum(mMaxFrames-1); + setSourceOutFrameNum(mMaxFrames - 1); // Set the size of the frames // For that we need to retrieve a frame! tempImg = getFramePhoto(getSourceInFrameNum()); - if (!tempImg.empty()) // if frame is loadable + if(!tempImg.empty()) // if frame is loadable { // 1 or 3 channel and 8 bit per pixel - if (!(((tempImg.channels() == 1) || (tempImg.channels() == 3)) && (tempImg.depth() == CV_8U))) + if(!(((tempImg.channels() == 1) || (tempImg.channels() == 3)) && (tempImg.depth() == CV_8U))) { - debout << "Error: Only 1 or 3 channels (you are using "<< tempImg.channels() <<") and 8 bpp (you are using "<< tempImg.depth() <<") are supported!" << std::endl; + debout << "Error: Only 1 or 3 channels (you are using " << tempImg.channels() + << ") and 8 bpp (you are using " << tempImg.depth() << ") are supported!" << std::endl; } else { @@ -725,7 +741,7 @@ bool Animation::getInfoPhoto() void Animation::freePhoto() { // Release the image pointer - if (!mImage.empty()) + if(!mImage.empty()) { mImage = cv::Mat(); } @@ -766,24 +782,27 @@ bool Animation::openAnimationStereoVideo(int fileNumber, IplImage *stereoImgLeft StereoAviFile *captureStereo = new StereoAviFile; #endif - if ((fileNumber < mStereoVideoFilesList.length()) && - (captureStereo->open(mStereoVideoFilesList[fileNumber].toStdString().c_str(), stereoImgLeft, stereoImgRight))) + if((fileNumber < mStereoVideoFilesList.length()) && + (captureStereo->open(mStereoVideoFilesList[fileNumber].toStdString().c_str(), stereoImgLeft, stereoImgRight))) { - // wird nun schon vorher abgefragt: vor mTimeFileLoaded war mFps == 16 because time file must be loaded before ; && (myRound(mFps) == 16) - if (!((captureStereo->m_iRows == 960) && (captureStereo->m_iCols == 1280) && (captureStereo->m_iBPP == 16))) + // wird nun schon vorher abgefragt: vor mTimeFileLoaded war mFps == 16 because time file must be loaded before ; + // && (myRound(mFps) == 16) + if(!((captureStereo->m_iRows == 960) && (captureStereo->m_iCols == 1280) && (captureStereo->m_iBPP == 16))) { - debout << "Error: Only stereo videos from Hermes experiments with 1280x960 pixel, 16 bits per pixel anf 16 frames per second are supported!" << endl; + debout << "Error: Only stereo videos from Hermes experiments with 1280x960 pixel, 16 bits per pixel anf 16 " + "frames per second are supported!" + << endl; delete captureStereo; return false; } - if (mCaptureStereo) + if(mCaptureStereo) { captureStereo->setCamera(mCaptureStereo->getCamera()); mCaptureStereo->close(); delete mCaptureStereo; } mCurrentStereoFileNumber = fileNumber; - mCaptureStereo = captureStereo; + mCaptureStereo = captureStereo; return true; } else @@ -795,22 +814,23 @@ bool Animation::openAnimationStereoVideo(int fileNumber, IplImage *stereoImgLeft bool Animation::openAnimationStereoVideo(int fileNumber, Mat &stereoImgLeft, Mat &stereoImgRight) { IplImage *tempStereoImgLeft, *tempStereoImgRight; - Size size; - size.width = stereoImgLeft.cols; + Size size; + size.width = stereoImgLeft.cols; size.height = stereoImgRight.rows; - tempStereoImgLeft = cvCreateImage(size, 8, 1); // new unsigned char[2*1280*960]; // only stereo from bumblebee xb3 supported! - tempStereoImgRight = cvCreateImage(size, 8, 1); // new unsigned char[2*1280*960]; // only stereo from bumblebee xb3 supported! -// tempStereoImgLeft.create(size,CV_8UC1); -// tempStereoImgRight.create(size,CV_8UC1); + tempStereoImgLeft = + cvCreateImage(size, 8, 1); // new unsigned char[2*1280*960]; // only stereo from bumblebee xb3 supported! + tempStereoImgRight = + cvCreateImage(size, 8, 1); // new unsigned char[2*1280*960]; // only stereo from bumblebee xb3 supported! + // tempStereoImgLeft.create(size,CV_8UC1); + // tempStereoImgRight.create(size,CV_8UC1); bool ret = openAnimationStereoVideo(fileNumber, tempStereoImgLeft, tempStereoImgRight); if(ret) { - mStereoImgLeft = cvarrToMat(tempStereoImgLeft); mStereoImgRight = cvarrToMat(tempStereoImgRight); - - }else + } + else { cvReleaseImage(&tempStereoImgLeft); cvReleaseImage(&tempStereoImgRight); @@ -825,56 +845,58 @@ bool Animation::openAnimationStereoVideo(int fileNumber, Mat &stereoImgLeft, Mat bool Animation::openAnimationStereoVideo(QString fileName) { bool ret = false; -// IplImage *tempStereoImgLeft, *tempStereoImgRight; -// Mat tempStereoImgLeft,tempStereoImgRight; + // IplImage *tempStereoImgLeft, *tempStereoImgRight; + // Mat tempStereoImgLeft,tempStereoImgRight; // Accessing to file information and directory information - QFileInfo fileInfo(fileName); - QDir dir = fileInfo.dir(); + QFileInfo fileInfo(fileName); + QDir dir = fileInfo.dir(); QStringList filters; - //QString firstFileName = (fileName.left(fileName.lastIndexOf("cam")+5) + "%1.avi").arg(fileNumber, 4, 10, QChar('0')); - filters << (fileInfo.fileName()).left((fileInfo.fileName()).lastIndexOf("cam")+5) + "????.avi"; //"*.cpp" << "*.cxx" << "*.cc"; - //dir.setNameFilters(filters); - QStringList tmpList = mStereoVideoFilesList; + // QString firstFileName = (fileName.left(fileName.lastIndexOf("cam")+5) + "%1.avi").arg(fileNumber, 4, 10, + // QChar('0')); + filters << (fileInfo.fileName()).left((fileInfo.fileName()).lastIndexOf("cam") + 5) + + "????.avi"; //"*.cpp" << "*.cxx" << "*.cc"; + // dir.setNameFilters(filters); + QStringList tmpList = mStereoVideoFilesList; mStereoVideoFilesList = dir.entryList(filters); - for (int i = 0; i < mStereoVideoFilesList.size(); i++) + for(int i = 0; i < mStereoVideoFilesList.size(); i++) mStereoVideoFilesList[i] = fileInfo.path() + "/" + mStereoVideoFilesList[i]; - //debout << "getNumFrames: " << getNumFrames() << " mStereoVideoFilesList.len: " << mStereoVideoFilesList.length() << endl; - if (((getNumFrames()-1/*mNumFrames-1*/) / 640) == (mStereoVideoFilesList.length()-1)) + // debout << "getNumFrames: " << getNumFrames() << " mStereoVideoFilesList.len: " << mStereoVideoFilesList.length() + // << endl; + if(((getNumFrames() - 1 /*mNumFrames-1*/) / 640) == (mStereoVideoFilesList.length() - 1)) { Size size; - size.width = 1280; + size.width = 1280; size.height = 960; - mStereoImgLeft.create(size,CV_8UC1); - mStereoImgRight.create(size,CV_8UC1); -// tempStereoImgLeft = cvCreateImage(size, 8, 1); // new unsigned char[2*1280*960]; // only stereo from bumblebee xb3 supported! -// tempStereoImgRight = cvCreateImage(size, 8, 1); // new unsigned char[2*1280*960]; // only stereo from bumblebee xb3 supported! -// tempStereoImgLeft.create(size,CV_8UC1); -// tempStereoImgRight.create(size,CV_8UC1); + mStereoImgLeft.create(size, CV_8UC1); + mStereoImgRight.create(size, CV_8UC1); + // tempStereoImgLeft = cvCreateImage(size, 8, 1); // new unsigned char[2*1280*960]; // only stereo from + // bumblebee xb3 supported! tempStereoImgRight = cvCreateImage(size, 8, 1); // new unsigned + // char[2*1280*960]; // only stereo from bumblebee xb3 supported! tempStereoImgLeft.create(size,CV_8UC1); + // tempStereoImgRight.create(size,CV_8UC1); ret = openAnimationStereoVideo(0, mStereoImgLeft, mStereoImgRight); } - //debout << " ret: " << ret << endl; - if (ret) + // debout << " ret: " << ret << endl; + if(ret) { -// if (mStereoImgLeft) -// { -// cvReleaseImage(&mStereoImgLeft); -// mStereoImgLeft = NULL; -// } -// if (mStereoImgRight) -// { -// cvReleaseImage(&mStereoImgRight); -// mStereoImgRight = NULL; -// } -// mStereoImgLeft = cvarrToMat(tempStereoImgLeft); -// mStereoImgRight = cvarrToMat(tempStereoImgRight); - + // if (mStereoImgLeft) + // { + // cvReleaseImage(&mStereoImgLeft); + // mStereoImgLeft = NULL; + // } + // if (mStereoImgRight) + // { + // cvReleaseImage(&mStereoImgRight); + // mStereoImgRight = NULL; + // } + // mStereoImgLeft = cvarrToMat(tempStereoImgLeft); + // mStereoImgRight = cvarrToMat(tempStereoImgRight); } else { mStereoVideoFilesList = tmpList; -// tempStereoImgLeft = NULL; -// tempStereoImgRight = NULL; + // tempStereoImgLeft = NULL; + // tempStereoImgRight = NULL; } return ret; @@ -885,7 +907,7 @@ bool Animation::openAnimationStereoVideo(QString fileName) /// Opens an animation from a video file bool Animation::openAnimationVideo(QString fileName) { - if( !mVideoCapture.open(fileName.toStdString().c_str()) ) + if(!mVideoCapture.open(fileName.toStdString().c_str())) return false; if(mVideoCapture.isOpened()) @@ -893,7 +915,7 @@ bool Animation::openAnimationVideo(QString fileName) int width = (int) mVideoCapture.get(cv::CAP_PROP_FRAME_WIDTH); int height = (int) mVideoCapture.get(cv::CAP_PROP_FRAME_HEIGHT); int fps = (int) mVideoCapture.get(cv::CAP_PROP_FPS); - if ((width == 1280) && (height == 960) && (fps == 16)) // dann gehe ich von einem stereo video der BBX3 aus!!! + if((width == 1280) && (height == 960) && (fps == 16)) // dann gehe ich von einem stereo video der BBX3 aus!!! { mVideoCapture.release(); mStereo = true; @@ -902,24 +924,24 @@ bool Animation::openAnimationVideo(QString fileName) // Check if it was created succesfully if(!mVideoCapture.isOpened()) { -#if STEREO && not STEREO_DISABLED +#if STEREO && not STEREO_DISABLED - // untersuchen, ob Stereodaten von Arena/Messe-Versuchen - if (mTimeFileLoaded && openAnimationStereoVideo(fileName)) + // untersuchen, ob Stereodaten von Arena/Messe-Versuchen + if(mTimeFileLoaded && openAnimationStereoVideo(fileName)) { // Destroy anything that was before - //free(); + // free(); // Set new video & photo labels - mVideo = true; - mImgSeq = false; + mVideo = true; + mImgSeq = false; mCameraLiveStream = false; - //mCurrentFrame = -1; + // mCurrentFrame = -1; // Get the information of the animation -// if (!getInfoVideo(fileName)) -// return false; + // if (!getInfoVideo(fileName)) + // return false; // Set the size in the QSize structure mSize.setHeight(mCaptureStereo->m_iRows); @@ -937,28 +959,28 @@ bool Animation::openAnimationVideo(QString fileName) else { #ifndef STEREO_DISABLED - if (mCaptureStereo) + if(mCaptureStereo) { mCaptureStereo->close(); delete mCaptureStereo; } #endif // Set new video & photo labels - mStereo = false; - mVideo = true; - mImgSeq = false; + mStereo = false; + mVideo = true; + mImgSeq = false; mCameraLiveStream = false; mCurrentFrame = -1; // Get the information of the animation - if (!getInfoVideo(fileName)) + if(!getInfoVideo(fileName)) return false; // Set the current frame to -1 (shows, that no frame is already loaded) } - mFileInfo = QFileInfo(fileName); - mFileBase = mFileInfo.completeBaseName(); - mFileSuffix = mFileInfo.suffix(); + mFileInfo = QFileInfo(fileName); + mFileBase = mFileInfo.completeBaseName(); + mFileSuffix = mFileInfo.suffix(); mCurrentFrame = -1; // Set the current frame to -1 (shows, that no frame is already loaded) return true; @@ -968,12 +990,11 @@ bool Animation::openAnimationVideo(QString fileName) /// Returns the frame at given index in the video cv::Mat Animation::getFrameVideo(int index) { - - if (mCameraLiveStream) + if(mCameraLiveStream) { - if (mVideoCapture.read(mImage/*tempMat*/) ) + if(mVideoCapture.read(mImage /*tempMat*/)) { - if (mImage.empty())//tempImg == NULL) + if(mImage.empty()) // tempImg == NULL) return cv::Mat(); mCurrentFrame++; @@ -981,46 +1002,48 @@ cv::Mat Animation::getFrameVideo(int index) return mImage; } - if ((index != mCurrentFrame) || mImage.empty()) + if((index != mCurrentFrame) || mImage.empty()) { // Check if we have a valid index - if (index < getSourceInFrameNum() || (index > getSourceOutFrameNum() && getSourceOutFrameNum() != -1) ) + if(index < getSourceInFrameNum() || (index > getSourceOutFrameNum() && getSourceOutFrameNum() != -1)) return cv::Mat(); - if (mVideo && !mStereo) + if(mVideo && !mStereo) { // Check if we have a valid capture device - if (!mVideoCapture.isOpened()) + if(!mVideoCapture.isOpened()) return cv::Mat(); // Now we need to see if it is necessary to seek for the frame or if we can use // directly the cvQueryFrame function // This is tested since the seek function takes a lot of time! - if (index == getSourceInFrameNum() || mCurrentFrame+1 != index) + if(index == getSourceInFrameNum() || mCurrentFrame + 1 != index) { - if( !mVideoCapture.set(cv::CAP_PROP_POS_FRAMES, index) ) + if(!mVideoCapture.set(cv::CAP_PROP_POS_FRAMES, index)) { debout << "Error: video file does not support skipping." << std::endl; return cv::Mat(); } } // Query the frame - if( mVideoCapture.read(mImage)) + if(mVideoCapture.read(mImage)) { - if (mImage.empty())//tempImg == NULL) + if(mImage.empty()) // tempImg == NULL) return cv::Mat(); - }else + } + else { - debout << "Warning: number of frames in the video seems to be incorrect. Frame[" << index << "] is not loadable! Set number of Frames to " << index << "." << std::endl; - mSourceOutFrame = index-1; + debout << "Warning: number of frames in the video seems to be incorrect. Frame[" << index + << "] is not loadable! Set number of Frames to " << index << "." << std::endl; + mSourceOutFrame = index - 1; setSourceOutFrameNum(mSourceOutFrame); return cv::Mat(); } } #ifndef STEREO_DISABLED - else if (mStereo && mCaptureStereo)// stereo video + else if(mStereo && mCaptureStereo) // stereo video { - if (index/640 != mCurrentStereoFileNumber) // 640 stereo frames in one file + if(index / 640 != mCurrentStereoFileNumber) // 640 stereo frames in one file { - openAnimationStereoVideo(index/640, mStereoImgLeft, mStereoImgRight); + openAnimationStereoVideo(index / 640, mStereoImgLeft, mStereoImgRight); } mImage = cvarrToMat(mCaptureStereo->readFrame(index - mCurrentStereoFileNumber * 640)); } @@ -1029,7 +1052,7 @@ cv::Mat Animation::getFrameVideo(int index) mCurrentFrame = index; } #ifndef STEREO_DISABLED - else if (mStereo && (index == mCurrentFrame)) // da mgl anderes Bild rechte/links angefordert wird + else if(mStereo && (index == mCurrentFrame)) // da mgl anderes Bild rechte/links angefordert wird mImage = cvarrToMat(mCaptureStereo->readFrame(index - mCurrentStereoFileNumber * 640)); #endif // Return the pointer to the IplImage :-) @@ -1044,15 +1067,16 @@ bool Animation::getInfoVideo(QString /*fileName*/) // We will grab the information from a frame of the animation setSourceInFrameNum(0); cv::Mat tempImg = getFrameVideo(getSourceInFrameNum()); - if (tempImg.empty()) + if(tempImg.empty()) { debout << "Error: No frame could be retrieved from the capture during getInfoVideo." << std::endl; return false; } // 1 or 3 channel and 8 bit per pixel - if (!(((tempImg.channels() == 1) || (tempImg.channels() == 3)) && (tempImg.depth() == CV_8U))) + if(!(((tempImg.channels() == 1) || (tempImg.channels() == 3)) && (tempImg.depth() == CV_8U))) { - debout << "Warning: Only 1 or 3 channels (you are using "<< tempImg.channels() <<") and 8 bpp (you are using "<< tempImg.depth() <<") are supported!" << std::endl; + debout << "Warning: Only 1 or 3 channels (you are using " << tempImg.channels() << ") and 8 bpp (you are using " + << tempImg.depth() << ") are supported!" << std::endl; } // Set the size in the QSize structure mSize.setHeight(tempImg.rows); @@ -1060,44 +1084,51 @@ bool Animation::getInfoVideo(QString /*fileName*/) // Release the temporary frame // We get the FPS number with the cvGetCaptureProperty function // Note that this doesn't work if no frame has already retrieved!! - if (mVideoCapture.get(cv::CAP_PROP_FPS)){ + if(mVideoCapture.get(cv::CAP_PROP_FPS)) + { setFPS(mVideoCapture.get(cv::CAP_PROP_FPS)); mOriginalFps = mVideoCapture.get(cv::CAP_PROP_FPS); } // detect the used video codec - int fourCC = static_cast<int>( mVideoCapture.get(cv::CAP_PROP_FOURCC) ); - char FOURCC[] = {(char)( fourCC & 0XFF) , - (char)((fourCC & 0XFF00) >> 8), - (char)((fourCC & 0XFF0000) >> 16), - (char)((fourCC & 0XFF000000) >> 24), - 0}; - mMaxFrames = (int) mVideoCapture.get(cv::CAP_PROP_FRAME_COUNT); //mNumFrame - mSourceOutFrame = mMaxFrames-1; + int fourCC = static_cast<int>(mVideoCapture.get(cv::CAP_PROP_FOURCC)); + char FOURCC[] = { + (char) (fourCC & 0XFF), + (char) ((fourCC & 0XFF00) >> 8), + (char) ((fourCC & 0XFF0000) >> 16), + (char) ((fourCC & 0XFF000000) >> 24), + 0}; + mMaxFrames = (int) mVideoCapture.get(cv::CAP_PROP_FRAME_COUNT); // mNumFrame + mSourceOutFrame = mMaxFrames - 1; // Set videocapture to the last frame if CV_CAP_PROP_POS_FRAMES is supported by used video codec - if( mVideoCapture.set(cv::CAP_PROP_POS_FRAMES, mMaxFrames)) + if(mVideoCapture.set(cv::CAP_PROP_POS_FRAMES, mMaxFrames)) { // Set videoCapture to the really correct last frame - mVideoCapture.set(cv::CAP_PROP_POS_FRAMES, mVideoCapture.get(cv::CAP_PROP_POS_FRAMES)-1); + mVideoCapture.set(cv::CAP_PROP_POS_FRAMES, mVideoCapture.get(cv::CAP_PROP_POS_FRAMES) - 1); // Check if mNumFrames agrees with last readable frame - if( mMaxFrames != (mVideoCapture.get(cv::CAP_PROP_POS_FRAMES)+1) ) + if(mMaxFrames != (mVideoCapture.get(cv::CAP_PROP_POS_FRAMES) + 1)) { - debout << "Warning: number of frames detected by OpenCV library (" << mMaxFrames << ") seems to be incorrect! (set to estimated value: "<< (mVideoCapture.get(cv::CAP_PROP_POS_FRAMES)+1) << ") [video codec: " << FOURCC << "]" << std::endl; - mMaxFrames = mVideoCapture.get(cv::CAP_PROP_POS_FRAMES)+1; - mSourceOutFrame = mMaxFrames-1; + debout << "Warning: number of frames detected by OpenCV library (" << mMaxFrames + << ") seems to be incorrect! (set to estimated value: " + << (mVideoCapture.get(cv::CAP_PROP_POS_FRAMES) + 1) << ") [video codec: " << FOURCC << "]" + << std::endl; + mMaxFrames = mVideoCapture.get(cv::CAP_PROP_POS_FRAMES) + 1; + mSourceOutFrame = mMaxFrames - 1; } // Check if the last frame of the video is readable/OK? cv::Mat frame; - while( !mVideoCapture.read(frame) ){ - mVideoCapture.set(cv::CAP_PROP_POS_FRAMES,mVideoCapture.get(cv::CAP_PROP_POS_FRAMES)-2); - mMaxFrames = mVideoCapture.get(cv::CAP_PROP_POS_FRAMES)+1; - if( mVideoCapture.get(cv::CAP_PROP_POS_FRAMES) < 0 ){ + while(!mVideoCapture.read(frame)) + { + mVideoCapture.set(cv::CAP_PROP_POS_FRAMES, mVideoCapture.get(cv::CAP_PROP_POS_FRAMES) - 2); + mMaxFrames = mVideoCapture.get(cv::CAP_PROP_POS_FRAMES) + 1; + if(mVideoCapture.get(cv::CAP_PROP_POS_FRAMES) < 0) + { std::cerr << "Warning: video file seems to be broken!" << std::endl; - mMaxFrames = -1; - mSourceOutFrame = mMaxFrames-1; + mMaxFrames = -1; + mSourceOutFrame = mMaxFrames - 1; return false; } } @@ -1105,16 +1136,18 @@ bool Animation::getInfoVideo(QString /*fileName*/) // Since we don't trust OpenCV, another check is never enough :-) int defaultFrames = 10000; - int maxFrames = 9999999; // > 111 h @ 25fps - if (getNumFrames() <= 0) + int maxFrames = 9999999; // > 111 h @ 25fps + if(getNumFrames() <= 0) { - debout << "Error: Incorrect number ("<<getNumFrames()<<") of frames. Setting it to "<<defaultFrames<<"." << std::endl; - mSourceOutFrame = getSourceInFrameNum()+defaultFrames; + debout << "Error: Incorrect number (" << getNumFrames() << ") of frames. Setting it to " << defaultFrames << "." + << std::endl; + mSourceOutFrame = getSourceInFrameNum() + defaultFrames; } - if (getNumFrames() > maxFrames)// = 6h * 60mins * 60 secs * 25 frames + if(getNumFrames() > maxFrames) // = 6h * 60mins * 60 secs * 25 frames { - debout << "Warning: Number of frames ("<<getNumFrames()<<") seems to be incorrect. Setting it to "<<defaultFrames<<"." << std::endl; - mSourceOutFrame = getSourceInFrameNum()+defaultFrames; + debout << "Warning: Number of frames (" << getNumFrames() << ") seems to be incorrect. Setting it to " + << defaultFrames << "." << std::endl; + mSourceOutFrame = getSourceInFrameNum() + defaultFrames; } setSourceOutFrameNum(mSourceOutFrame); return true; @@ -1123,15 +1156,16 @@ bool Animation::getInfoVideo(QString /*fileName*/) bool Animation::getCameraInfo() { cv::Mat tempImg = getFrameVideo(0); - if (tempImg.empty()) + if(tempImg.empty()) { debout << "Error: No frame could be retrieved from the capture during getInfoVideo." << std::endl; return false; } // 1 or 3 channel and 8 bit per pixel - if (!(((tempImg.channels() == 1) || (tempImg.channels() == 3)) && (tempImg.depth() == CV_8U))) + if(!(((tempImg.channels() == 1) || (tempImg.channels() == 3)) && (tempImg.depth() == CV_8U))) { - debout << "Warning: Only 1 or 3 channels (you are using "<< tempImg.channels() <<") and 8 bpp (you are using "<< tempImg.depth() <<") are supported!" << std::endl; + debout << "Warning: Only 1 or 3 channels (you are using " << tempImg.channels() << ") and 8 bpp (you are using " + << tempImg.depth() << ") are supported!" << std::endl; } // Set the size in the QSize structure mSize.setHeight(tempImg.rows); @@ -1139,13 +1173,13 @@ bool Animation::getCameraInfo() // Release the temporary frame // We get the FPS number with the cvGetCaptureProperty function // Note that this doesn't work if no frame has already retrieved!! - if (mVideoCapture.get(cv::CAP_PROP_FPS)){ + if(mVideoCapture.get(cv::CAP_PROP_FPS)) + { setFPS(mVideoCapture.get(cv::CAP_PROP_FPS)); mOriginalFps = mVideoCapture.get(cv::CAP_PROP_FPS); } - return true; } @@ -1153,14 +1187,13 @@ bool Animation::getCameraInfo() void Animation::freeVideo() { // Release the capture device - if (mVideoCapture.isOpened()) + if(mVideoCapture.isOpened()) { mVideoCapture.release(); } // Release the image pointer - if (!mImage.empty()) + if(!mImage.empty()) { mImage = cv::Mat(); } - } diff --git a/src/autoCalib.cpp b/src/autoCalib.cpp index 8e6c6c023152d49c1202886685ad5ea80ebfb15c..073b25474523b7161837a05e8d858f0c2618e610 100644 --- a/src/autoCalib.cpp +++ b/src/autoCalib.cpp @@ -18,39 +18,38 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QFileInfo> -#include <QFileDialog> -#include <QProgressDialog> -#include <QApplication> - -#include <opencv2/highgui.hpp> - #include "autoCalib.h" -#include "petrack.h" + #include "control.h" #include "pMessageBox.h" +#include "petrack.h" + +#include <QApplication> +#include <QFileDialog> +#include <QFileInfo> +#include <QProgressDialog> +#include <opencv2/highgui.hpp> -#define SHOW_CALIB_MAINWINDOW ///< definieren, wenn das Schachbrett im Mainwindow und nicht separat angezeigt werden soll: - // fuehrt nach Calibration dazu dass play des originalvideos abstuerzt, insb wenn intr apply nicht ausgewaehlt war +/// definieren, wenn das Schachbrett im Mainwindow und nicht separat angezeigt werden soll: +/// fuehrt nach Calibration dazu dass play des originalvideos abstuerzt, insb wenn intr apply nicht ausgewaehlt war +#define SHOW_CALIB_MAINWINDOW AutoCalib::AutoCalib() { - mMainWindow = nullptr; + mMainWindow = nullptr; mControlWidget = nullptr; // 6x8 und 4.6cm passen zu dem Schachbrettmuster auf der Eisenplatte mit Griff mBoardSizeX = 6; - mBoardSizeY = 8; //{6, 9}; //{6, 8}; // passt zu meinem Schachbrett, was ich ausgedruckt habe - mSquareSize = 4.6f; //3.f; //5.25f; + mBoardSizeY = 8; //{6, 9}; //{6, 8}; // passt zu meinem Schachbrett, was ich ausgedruckt habe + mSquareSize = 4.6f; // 3.f; //5.25f; } -AutoCalib::~AutoCalib() -{ -} +AutoCalib::~AutoCalib() {} void AutoCalib::setMainWindow(Petrack *mw) { - mMainWindow = mw; + mMainWindow = mw; mControlWidget = mw->getControlWidget(); } @@ -66,7 +65,7 @@ void AutoCalib::addCalibFile(const QString &f) QString AutoCalib::getCalibFile(int i) { - if (i < mCalibFiles.size()) + if(i < mCalibFiles.size()) return mCalibFiles.at(i); else return QString(); @@ -84,16 +83,21 @@ void AutoCalib::setCalibFiles(const QStringList &fl) bool AutoCalib::openCalibFiles() { - if (mMainWindow) + if(mMainWindow) { static QString lastDir; - - if (!mCalibFiles.isEmpty()) + + if(!mCalibFiles.isEmpty()) lastDir = QFileInfo(mCalibFiles.first()).path(); - - QStringList calibFiles = QFileDialog::getOpenFileNames(mMainWindow, Petrack::tr("Open calibration sequence"), lastDir, "All supported types (*.bmp *.dib *.jpeg *.jpg *.jpe *.png *.pbm *.pgm *.ppm *.sr *.ras *.tiff *.tif *.exr *.jp2);;All files (*.*)"); - if (!calibFiles.isEmpty()) - { + + QStringList calibFiles = QFileDialog::getOpenFileNames( + mMainWindow, + Petrack::tr("Open calibration sequence"), + lastDir, + "All supported types (*.bmp *.dib *.jpeg *.jpg *.jpe *.png *.pbm *.pgm *.ppm *.sr *.ras *.tiff *.tif *.exr " + "*.jp2);;All files (*.*)"); + if(!calibFiles.isEmpty()) + { mCalibFiles = calibFiles; return true; } @@ -113,57 +117,63 @@ bool AutoCalib::openCalibFiles() */ void AutoCalib::autoCalib() { - if (mMainWindow) + if(mMainWindow) { // no files are selected for calibration - if (mCalibFiles.isEmpty()) + if(mCalibFiles.isEmpty()) { PInformation(mMainWindow, Petrack::tr("Petrack"), Petrack::tr("At first you have to select files.")); return; } - cv::Size board_size(mBoardSizeX, mBoardSizeY); //{6, 9}; //{6, 8}; // passt zu meinem Schachbrett, was ich ausgedruckt habe - float square_size = mSquareSize; //5.25f; // 3.f; // da 3x3cm hat Schachbrett, was ich ausgedruckt habe + cv::Size board_size( + mBoardSizeX, mBoardSizeY); //{6, 9}; //{6, 8}; // passt zu meinem Schachbrett, was ich ausgedruckt habe + float square_size = mSquareSize; // 5.25f; // 3.f; // da 3x3cm hat Schachbrett, was ich ausgedruckt habe float aspect_ratio = 1.f; - int flags = 0; - std::vector<cv::Point2f> corners; - std::vector<std::vector<cv::Point2f> > image_points; - cv::Mat camera_matrix = cv::Mat::eye(3, 3, CV_64F); - cv::Mat dist_coeffs = cv::Mat::zeros(1, 8, CV_64F); - cv::Mat extr_params; - double reproj_errs; - cv::Mat view, view_gray; - bool found = false; - cv::Mat origImg; - cv::Size imgSize; + int flags = 0; + std::vector<cv::Point2f> corners; + std::vector<std::vector<cv::Point2f>> image_points; + cv::Mat camera_matrix = cv::Mat::eye(3, 3, CV_64F); + cv::Mat dist_coeffs = cv::Mat::zeros(1, 8, CV_64F); + cv::Mat extr_params; + double reproj_errs; + cv::Mat view, view_gray; + bool found = false; + cv::Mat origImg; + cv::Size imgSize; #ifdef SHOW_CALIB_MAINWINDOW - if (!mMainWindow->getImg().empty()) + if(!mMainWindow->getImg().empty()) origImg = mMainWindow->getImg().clone(); // must be cloned, because mIplImg will be deleted in updateImage #endif - QProgressDialog progress("Calculating intrinsic camera parameters...", "Abort calculation", 0, mCalibFiles.size(), mMainWindow); + QProgressDialog progress( + "Calculating intrinsic camera parameters...", "Abort calculation", 0, mCalibFiles.size(), mMainWindow); progress.setWindowModality(Qt::WindowModal); // blocks main window - debout << "Search for cheesboard pattern (" << board_size.width << "x" << board_size.height << ") with square size: " << square_size << "cm..." << std::endl; + debout << "Search for cheesboard pattern (" << board_size.width << "x" << board_size.height + << ") with square size: " << square_size << "cm..." << std::endl; bool min_one_pattern_found = false; // search for chessbord corners in every image - for (int i = 0; i < mCalibFiles.size(); ++i) + for(int i = 0; i < mCalibFiles.size(); ++i) { progress.setValue(i); qApp->processEvents(); - if (progress.wasCanceled()) + if(progress.wasCanceled()) break; // cannot load image - view = cv::imread(mCalibFiles.at(i).toStdString(),cv::IMREAD_COLOR); - if (view.empty()) + view = cv::imread(mCalibFiles.at(i).toStdString(), cv::IMREAD_COLOR); + if(view.empty()) { progress.setValue(mCalibFiles.size()); - PCritical(mMainWindow, Petrack::tr("Petrack"), Petrack::tr("Cannot load %1.\nTerminate Calibration.").arg(mCalibFiles.at(i))); + PCritical( + mMainWindow, + Petrack::tr("Petrack"), + Petrack::tr("Cannot load %1.\nTerminate Calibration.").arg(mCalibFiles.at(i))); #ifdef SHOW_CALIB_MAINWINDOW - // reset view to animation image - if (!origImg.empty()) + // reset view to animation image + if(!origImg.empty()) { mMainWindow->updateImage(origImg); // now the last view will be deleted } @@ -172,26 +182,30 @@ void AutoCalib::autoCalib() } // muss nur bei einem bild gemacht werden - if (i==0) - imgSize = cv::Size(view.rows,view.cols); + if(i == 0) + imgSize = cv::Size(view.rows, view.cols); // search for chessboard corners - found = findChessboardCorners(view,board_size,corners,cv::CALIB_CB_ADAPTIVE_THRESH); + found = findChessboardCorners(view, board_size, corners, cv::CALIB_CB_ADAPTIVE_THRESH); - if (found) + if(found) { // improve the found corners' coordinate accuracy - cv::cvtColor(view,view_gray,cv::COLOR_BGR2GRAY); - cv::cornerSubPix(view_gray,corners,cv::Size(11,11), - cv::Size(-1,-1),cv::TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,0.1)); - + cv::cvtColor(view, view_gray, cv::COLOR_BGR2GRAY); + cv::cornerSubPix( + view_gray, + corners, + cv::Size(11, 11), + cv::Size(-1, -1), + cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1)); + image_points.push_back(corners); - drawChessboardCorners(view,board_size,corners,found); + drawChessboardCorners(view, board_size, corners, found); #ifndef SHOW_CALIB_MAINWINDOW - namedWindow("img", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll + namedWindow("img", CV_WINDOW_AUTOSIZE); // 0 wenn skalierbar sein soll imShow("img", view); - //cvWaitKey( 0 ); // zahl statt null, wenn nach bestimmter zeit weitergegangen werden soll + // cvWaitKey( 0 ); // zahl statt null, wenn nach bestimmter zeit weitergegangen werden soll #endif #ifdef SHOW_CALIB_MAINWINDOW // show image in view to show calculation @@ -201,62 +215,80 @@ void AutoCalib::autoCalib() min_one_pattern_found = true; } else - debout << "Calibration pattern not found in: "<< mCalibFiles.at(i).toStdString() << std::endl; + debout << "Calibration pattern not found in: " << mCalibFiles.at(i).toStdString() << std::endl; } - if( !min_one_pattern_found ) + if(!min_one_pattern_found) { debout << "Calibration failed. No patterns found!" << std::endl; - PWarning(mMainWindow, - QString("Calibration failed"), - QString("Chessboard pattern (%1x%2) not found in calibration files.").arg(board_size.width).arg(board_size.height)); + PWarning( + mMainWindow, + QString("Calibration failed"), + QString("Chessboard pattern (%1x%2) not found in calibration files.") + .arg(board_size.width) + .arg(board_size.height)); return; } // set flags for calibration - if (mControlWidget->quadAspectRatio->isChecked()) - flags |= CV_CALIB_FIX_ASPECT_RATIO; //durch setzen von aspect_ratio kann fix ascpect anders als 1:1 eingestellt werden - if (mControlWidget->fixCenter->isChecked()) + if(mControlWidget->quadAspectRatio->isChecked()) + flags |= CV_CALIB_FIX_ASPECT_RATIO; // durch setzen von aspect_ratio kann fix ascpect anders als 1:1 + // eingestellt werden + if(mControlWidget->fixCenter->isChecked()) flags |= CV_CALIB_FIX_PRINCIPAL_POINT; - if (!mControlWidget->tangDist->isChecked()) + if(!mControlWidget->tangDist->isChecked()) flags |= CV_CALIB_ZERO_TANGENT_DIST; // run calibration - bool ok = runCalibration( image_points, view.size(), board_size, - square_size, aspect_ratio, flags, camera_matrix, dist_coeffs, &reproj_errs); - debout << (ok ? "Calibration succeeded." : "Calibration failed.") << std::endl; // "Avgage reprojection error is " << avg_reproj_err << endl; + bool ok = runCalibration( + image_points, + view.size(), + board_size, + square_size, + aspect_ratio, + flags, + camera_matrix, + dist_coeffs, + &reproj_errs); + debout << (ok ? "Calibration succeeded." : "Calibration failed.") + << std::endl; // "Avgage reprojection error is " << avg_reproj_err << endl; debout << "Intrinsic reprojection error is: " << reproj_errs << std::endl; progress.setValue(mCalibFiles.size()); debout << "Cameramatrix: " << std::endl; - debout << "( " << camera_matrix.at<double>(0,0) << " " << camera_matrix.at<double>(0,1) << " " << camera_matrix.at<double>(0,2) << ")" << std::endl; - debout << "( " << camera_matrix.at<double>(1,0) << " " << camera_matrix.at<double>(1,1) << " " << camera_matrix.at<double>(1,2) << ")" << std::endl; - debout << "( " << camera_matrix.at<double>(2,0) << " " << camera_matrix.at<double>(2,1) << " " << camera_matrix.at<double>(2,2) << ")" << std::endl; + debout << "( " << camera_matrix.at<double>(0, 0) << " " << camera_matrix.at<double>(0, 1) << " " + << camera_matrix.at<double>(0, 2) << ")" << std::endl; + debout << "( " << camera_matrix.at<double>(1, 0) << " " << camera_matrix.at<double>(1, 1) << " " + << camera_matrix.at<double>(1, 2) << ")" << std::endl; + debout << "( " << camera_matrix.at<double>(2, 0) << " " << camera_matrix.at<double>(2, 1) << " " + << camera_matrix.at<double>(2, 2) << ")" << std::endl; debout << "Distortioncoefficients: " << std::endl; - debout << "r2: " << dist_coeffs.at<double>(0,0) << " r4: " << dist_coeffs.at<double>(0,1) << " r6: " << dist_coeffs.at<double>(0,4) << std::endl; - debout << "tx: " << dist_coeffs.at<double>(0,2) << " ty: " << dist_coeffs.at<double>(0,3) << std::endl; - debout << "k4: " << dist_coeffs.at<double>(0,5) << " k5: " << dist_coeffs.at<double>(0,6) << " k6: " << dist_coeffs.at<double>(0,7) << std::endl; + debout << "r2: " << dist_coeffs.at<double>(0, 0) << " r4: " << dist_coeffs.at<double>(0, 1) + << " r6: " << dist_coeffs.at<double>(0, 4) << std::endl; + debout << "tx: " << dist_coeffs.at<double>(0, 2) << " ty: " << dist_coeffs.at<double>(0, 3) << std::endl; + debout << "k4: " << dist_coeffs.at<double>(0, 5) << " k5: " << dist_coeffs.at<double>(0, 6) + << " k6: " << dist_coeffs.at<double>(0, 7) << std::endl; // set calibration values - mControlWidget->setCalibFxValue(camera_matrix.at<double>(0,0)); - mControlWidget->setCalibFyValue(camera_matrix.at<double>(1,1)); - mControlWidget->setCalibCxValue(camera_matrix.at<double>(0,2) + mMainWindow->getImageBorderSize()); - mControlWidget->setCalibCyValue(camera_matrix.at<double>(1,2) + mMainWindow->getImageBorderSize()); - mControlWidget->setCalibR2Value(dist_coeffs.at<double>(0,0)); - mControlWidget->setCalibR4Value(dist_coeffs.at<double>(0,1)); - mControlWidget->setCalibTxValue(dist_coeffs.at<double>(0,2)); - mControlWidget->setCalibTyValue(dist_coeffs.at<double>(0,3)); - mControlWidget->setCalibR6Value(dist_coeffs.at<double>(0,4)); - mControlWidget->setCalibK4Value(dist_coeffs.at<double>(0,5)); - mControlWidget->setCalibK5Value(dist_coeffs.at<double>(0,6)); - mControlWidget->setCalibK6Value(dist_coeffs.at<double>(0,7)); + mControlWidget->setCalibFxValue(camera_matrix.at<double>(0, 0)); + mControlWidget->setCalibFyValue(camera_matrix.at<double>(1, 1)); + mControlWidget->setCalibCxValue(camera_matrix.at<double>(0, 2) + mMainWindow->getImageBorderSize()); + mControlWidget->setCalibCyValue(camera_matrix.at<double>(1, 2) + mMainWindow->getImageBorderSize()); + mControlWidget->setCalibR2Value(dist_coeffs.at<double>(0, 0)); + mControlWidget->setCalibR4Value(dist_coeffs.at<double>(0, 1)); + mControlWidget->setCalibTxValue(dist_coeffs.at<double>(0, 2)); + mControlWidget->setCalibTyValue(dist_coeffs.at<double>(0, 3)); + mControlWidget->setCalibR6Value(dist_coeffs.at<double>(0, 4)); + mControlWidget->setCalibK4Value(dist_coeffs.at<double>(0, 5)); + mControlWidget->setCalibK5Value(dist_coeffs.at<double>(0, 6)); + mControlWidget->setCalibK6Value(dist_coeffs.at<double>(0, 7)); #ifdef SHOW_CALIB_MAINWINDOW - // reset view to animation image - if (!origImg.empty()) + // reset view to animation image + if(!origImg.empty()) { mMainWindow->updateImage(origImg); // now the last view will be deleted } @@ -280,22 +312,29 @@ void AutoCalib::autoCalib() * @param reproj_errs[out] * @return */ -int AutoCalib::runCalibration(std::vector<std::vector<cv::Point2f> > image_points, cv::Size img_size, cv::Size board_size, - float square_size, float aspect_ratio, int flags, - cv::Mat &camera_matrix, cv::Mat &dist_coeffs, double *reproj_errs) +int AutoCalib::runCalibration( + std::vector<std::vector<cv::Point2f>> image_points, + cv::Size img_size, + cv::Size board_size, + float square_size, + float aspect_ratio, + int flags, + cv::Mat & camera_matrix, + cv::Mat & dist_coeffs, + double * reproj_errs) { int code; - std::vector<std::vector<cv::Point3f> > object_points; + std::vector<std::vector<cv::Point3f>> object_points; // initialize arrays of points - for(size_t j=0; j<image_points.size();j++) + for(size_t j = 0; j < image_points.size(); j++) { std::vector<cv::Point3f> points_3d; - for(int i=0; i<board_size.width*board_size.height;i++) + for(int i = 0; i < board_size.width * board_size.height; i++) { - points_3d.push_back(cv::Point3f(float((i/board_size.width)*square_size),float((i%board_size.width)*square_size),0)); - + points_3d.push_back(cv::Point3f( + float((i / board_size.width) * square_size), float((i % board_size.width) * square_size), 0)); } object_points.push_back(points_3d); } @@ -308,9 +347,9 @@ int AutoCalib::runCalibration(std::vector<std::vector<cv::Point2f> > image_point camera_matrix.ptr<double>(1)[1] = 1.; } - *reproj_errs = calibrateCamera(object_points,image_points,img_size,camera_matrix,dist_coeffs,rot_vects,trans_vects,flags); + *reproj_errs = calibrateCamera( + object_points, image_points, img_size, camera_matrix, dist_coeffs, rot_vects, trans_vects, flags); code = 1; return code; } - diff --git a/src/aviFileWriter.cpp b/src/aviFileWriter.cpp index 0b6a4c4eca5482f3af1e4d96b58812051bd25e04..0c643598c951aafddaf5391a9b6cb0758811df16 100644 --- a/src/aviFileWriter.cpp +++ b/src/aviFileWriter.cpp @@ -18,11 +18,11 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include "aviFileWriter.h" + #include <cassert> #include <cstdio> #include <iostream> - -#include "aviFileWriter.h" #include <opencv2/videoio/videoio_c.h> // @@ -32,176 +32,141 @@ AviFileWriter::AviFileWriter() { - // m_pavifile = NULL; - // m_pstream = NULL; - // m_pstreamcompressed = NULL; - m_pTempBMPBuffer = nullptr; - m_pTempBuffer = nullptr; - // m_pBitmapInfo = NULL; - - m_iTimeIndex = 0; - - m_iCols = 0; - m_iRows = 0; - m_iBPP = 0; - m_iSize = 0; - m_iRowInc = 0; - m_frameRate = 0.0; - - m_bSizeLimited = false; - m_iSplitFile = 0; - m_isColor = true; - - // Default compression options. - //m_compvars.fccHandler = mmioFOURCC( 'D', 'I', 'B', ' ' ); // uncompressed - //m_compvars.fccHandler = mmioFOURCC( 'I', 'V', '5', '0' ); - //m_compvars.dwFlags = 0x0; - //m_compvars.lQ = ICQUALITY_DEFAULT; - - //m_compvars.lpState = NULL; - - m_liBytesWritten = 0; -} - - -AviFileWriter::~AviFileWriter() -{ - close(); + m_pTempBMPBuffer = nullptr; + m_pTempBuffer = nullptr; - /*if( m_pBitmapInfo != NULL ) - { - free( m_pBitmapInfo ); - m_pBitmapInfo = NULL; - }*/ + m_iTimeIndex = 0; - if( m_pTempBuffer != nullptr ) - { - delete [] m_pTempBuffer; - m_pTempBuffer = nullptr; - } + m_iCols = 0; + m_iRows = 0; + m_iBPP = 0; + m_iSize = 0; + m_iRowInc = 0; + m_frameRate = 0.0; - if( m_pTempBMPBuffer != nullptr ) - { - delete [] m_pTempBMPBuffer; - m_pTempBMPBuffer = nullptr; - } + m_bSizeLimited = false; + m_iSplitFile = 0; + m_isColor = true; - /*if( m_compvars.lpState != NULL ) - { - delete [] (char *) m_compvars.lpState; // (char *) nur um warnung zu unterdruecken - m_compvars.lpState = NULL; - }*/ + m_liBytesWritten = 0; } -bool AviFileWriter::openSizeLimitedAVI( - const char* pszFilename, - int iCols, - int iRows, - int ibpp, - double dFramerate ) +AviFileWriter::~AviFileWriter() { - std::string szAVIFile; - m_bSizeLimited = true; - m_iSplitFile = 0; + close(); + + if(m_pTempBuffer != nullptr) + { + delete[] m_pTempBuffer; + m_pTempBuffer = nullptr; + } + + if(m_pTempBMPBuffer != nullptr) + { + delete[] m_pTempBMPBuffer; + m_pTempBMPBuffer = nullptr; + } +} - std::stringstream stringStream; - stringStream << pszFilename; - szAVIFile = stringStream.str(); - // Remove any extensions. - size_t lastindex = szAVIFile.find_first_of('.'); - szAVIFile = szAVIFile.substr(0, lastindex); - - // - // Keep the basic avi file name in m_szAVIDestFile. - // - stringStream.str(""); - stringStream << szAVIFile; - m_szAVIDestFile = stringStream.str(); - - // - // The avi file names will be in the form of ***_0000.avi, ***_0001.avi, - // ***_0002.avi... - // The size of each avi file is limited by AVI_FILE_SPLIT_SIZE bytes - // - stringStream.str(""); - stringStream << m_szAVIDestFile << "_" << std::setfill('0') << std::setw(4) << m_iSplitFile << ".avi"; - szAVIFile = stringStream.str(); - return open( szAVIFile.c_str(), iCols, iRows, ibpp, dFramerate ); +bool AviFileWriter::openSizeLimitedAVI(const char *pszFilename, int iCols, int iRows, int ibpp, double dFramerate) +{ + std::string szAVIFile; + m_bSizeLimited = true; + m_iSplitFile = 0; + + std::stringstream stringStream; + stringStream << pszFilename; + szAVIFile = stringStream.str(); + + // Remove any extensions. + size_t lastindex = szAVIFile.find_first_of('.'); + szAVIFile = szAVIFile.substr(0, lastindex); + + // + // Keep the basic avi file name in m_szAVIDestFile. + // + stringStream.str(""); + stringStream << szAVIFile; + m_szAVIDestFile = stringStream.str(); + + // + // The avi file names will be in the form of ***_0000.avi, ***_0001.avi, + // ***_0002.avi... + // The size of each avi file is limited by AVI_FILE_SPLIT_SIZE bytes + // + stringStream.str(""); + stringStream << m_szAVIDestFile << "_" << std::setfill('0') << std::setw(4) << m_iSplitFile << ".avi"; + szAVIFile = stringStream.str(); + return open(szAVIFile.c_str(), iCols, iRows, ibpp, dFramerate); } -bool AviFileWriter::open(const char* pszFilename, int iCols, int iRows, int ibpp, double dFramerate) +bool AviFileWriter::open(const char *pszFilename, int iCols, int iRows, int ibpp, double dFramerate) { - // - // Initialize the library. - // - //::AVIFileInit(); - - if( !checkOpenCVVersion() ) - { - return false; - } - - if(pszFilename == nullptr || iRows <= 0 || iCols <= 0 || dFramerate <= 0.0) - { - assert( false ); - return false; - } - - /*if(ibpp != 24 && ibpp != 32 && ibpp != 8 && ibpp != 16) - { - assert( false ); - return false; - }*/ - - m_frameRate = dFramerate; - m_iTimeIndex = 0; - m_liBytesWritten = 0; - // - // If these parameters change, set them and allocate the buffers - // - if (m_iCols != iCols || m_iRows != iRows || m_iBPP != ibpp) - { - // - // Initialize members. - // - m_iCols = iCols; - m_iRows = iRows; - m_iBPP = ibpp; - m_iRowInc = m_iCols * ( m_iBPP / 8 ); - m_iSize = m_iRows * m_iRowInc; - // - // Allocate temp image buffers. - // - if(m_pTempBMPBuffer != nullptr) - { - delete [] m_pTempBMPBuffer; - m_pTempBMPBuffer = nullptr; - } - m_pTempBMPBuffer = new unsigned char[m_iSize + EXTRA_TEMP_SPACE]; - - if(m_pTempBuffer != nullptr) - { - delete [] m_pTempBuffer; - m_pTempBuffer = nullptr; - } - m_pTempBuffer = new unsigned char[ m_iSize ]; - } - - if (m_pTempBMPBuffer == nullptr || m_pTempBuffer == nullptr) - return false; - - // - // If this function is called from openSizeLimitedAVI(), pszFilename - // is the file to open. m_szAVIDestFile should not be changed because - // it is the base file name used in appendFrame() to generate the next - // split file name. - // - // If this function is called directly (not by openSizeLimitedAVI()), - // the AVI file can not be splited and m_szAVIDestFile is not used. - // So we do not need to save the file name to m_szAVIDestFile. - // + // + // Initialize the library. + // + //::AVIFileInit(); + + if(!checkOpenCVVersion()) + { + return false; + } + + if(pszFilename == nullptr || iRows <= 0 || iCols <= 0 || dFramerate <= 0.0) + { + assert(false); + return false; + } + + m_frameRate = dFramerate; + m_iTimeIndex = 0; + m_liBytesWritten = 0; + // + // If these parameters change, set them and allocate the buffers + // + if(m_iCols != iCols || m_iRows != iRows || m_iBPP != ibpp) + { + // + // Initialize members. + // + m_iCols = iCols; + m_iRows = iRows; + m_iBPP = ibpp; + m_iRowInc = m_iCols * (m_iBPP / 8); + m_iSize = m_iRows * m_iRowInc; + // + // Allocate temp image buffers. + // + if(m_pTempBMPBuffer != nullptr) + { + delete[] m_pTempBMPBuffer; + m_pTempBMPBuffer = nullptr; + } + m_pTempBMPBuffer = new unsigned char[m_iSize + EXTRA_TEMP_SPACE]; + + if(m_pTempBuffer != nullptr) + { + delete[] m_pTempBuffer; + m_pTempBuffer = nullptr; + } + m_pTempBuffer = new unsigned char[m_iSize]; + } + + if(m_pTempBMPBuffer == nullptr || m_pTempBuffer == nullptr) + return false; + + // + // If this function is called from openSizeLimitedAVI(), pszFilename + // is the file to open. m_szAVIDestFile should not be changed because + // it is the base file name used in appendFrame() to generate the next + // split file name. + // + // If this function is called directly (not by openSizeLimitedAVI()), + // the AVI file can not be splited and m_szAVIDestFile is not used. + // So we do not need to save the file name to m_szAVIDestFile. + // #if 0 sprintf(m_szAVIDestFile, "%s", pszFilename ); @@ -217,193 +182,120 @@ bool AviFileWriter::open(const char* pszFilename, int iCols, int iRows, int ibp sprintf(szAVIFile, "%s.avi", m_szAVIDestFile); #endif - // - // Open the file. - // - //char *c = "Ein C-String"; - //WCHAR wc[13]; - //for (int i = 0; i < 13; i++){ - // wc[i] = (WCHAR) c[i]; - //} - -//#ifdef UNICODE -// printf("UNICODE\n"); -//#else -// printf("NO UNICODE\n"); -//#endif - //m_vWriter.open(pszFilename, CV_FOURCC_DEFAULT, dFramerate, Size(iCols,iRows), m_isColor); - return m_vWriter.open(pszFilename, CV_FOURCC_DEFAULT/*PROMPT*/, dFramerate, cv::Size(iCols,iRows), m_isColor); - //m_vWriter.open(pszFilename, CV_FOURCC('H', 'F', 'Y', 'U'), dFramerate, Size(iCols,iRows), m_isColor); - //m_vWriter.open(pszFilename, CV_FOURCC('X', 'V', 'I', 'D'), dFramerate, Size(iCols,iRows), m_isColor); - //m_vWriter.open(pszFilename, CV_FOURCC('I', '4', '2', '0'), dFramerate, Size(iCols,iRows), m_isColor); - //m_vWriter.open(pszFilename, CV_FOURCC('X', '2', '6', '4'), dFramerate, Size(iCols,iRows), m_isColor); - //m_vWriter.open(pszFilename, CV_FOURCC('P', 'I', 'M', '1'), dFramerate, Size(iCols,iRows), m_isColor); - //m_vWriter.open(pszFilename,CV_FOURCC('M', 'J', 'P', 'G'),dFramerate,Size(iCols,iRows),m_isColor); - //m_vWriter.open(pszFilename,CV_FOURCC('I', 'V', '5', '0'),dFramerate,Size(iCols,iRows),m_isColor); - //HRESULT hr = ::AVIFileOpen(&m_pavifile, pszFilename, OF_WRITE | OF_CREATE, NULL); //(WCHAR*) pszFilename L"mbhuhu.avi" - - - //return true; + return m_vWriter.open(pszFilename, CV_FOURCC_DEFAULT /*PROMPT*/, dFramerate, cv::Size(iCols, iRows), m_isColor); } -bool AviFileWriter::open( - const char* pszFilename, - int iCols, - int iRows, - int /*ibpp*/, - int iFramerate ) +bool AviFileWriter::open(const char *pszFilename, int iCols, int iRows, int /*ibpp*/, int iFramerate) { - //return m_vWriter.open(pszFilename,CV_FOURCC_DEFAULT,(double) iFramerate,Size(iCols,iRows),m_isColor); - return m_vWriter.open(pszFilename,CV_FOURCC_PROMPT,(double) iFramerate,cv::Size(iCols,iRows),m_isColor); - //return m_vWriter.open(pszFilename,CV_FOURCC('H', 'F', 'Y', 'U'),(double) iFramerate,Size(iCols,iRows),m_isColor); - //return m_vWriter.open(pszFilename,CV_FOURCC('X', 'V', 'I', 'D'),(double) iFramerate,Size(iCols,iRows),m_isColor); - //return m_vWriter.open(pszFilename,CV_FOURCC('I', '4', '2', '0'),(double) iFramerate,Size(iCols,iRows),m_isColor); - //return m_vWriter.open(pszFilename,CV_FOURCC('X', '2', '6', '4'),(double) iFramerate,Size(iCols,iRows),m_isColor); - //return m_vWriter.open(pszFilename,CV_FOURCC('P', 'I', 'M', '1'),(double) iFramerate,Size(iCols,iRows),m_isColor); + return m_vWriter.open(pszFilename, CV_FOURCC_PROMPT, (double) iFramerate, cv::Size(iCols, iRows), m_isColor); } long int AviFileWriter::bytesWritten() const { - return m_liBytesWritten; - //return m_iTimeIndex * m_iSize; + return m_liBytesWritten; } -bool AviFileWriter::appendFrame(const unsigned char* pBuffer, bool /*bInvert*/) +bool AviFileWriter::appendFrame(const unsigned char *pBuffer, bool /*bInvert*/) { - if( !m_vWriter.isOpened() ){ - assert(false); - return false; - } - - - unsigned char* pWriteBuffer = (unsigned char*) pBuffer; - cv::Mat frame; - -// cout << "m_iRowInc: " << m_iRowInc << endl; -// cout << "rows: " << m_iRows << " cols: " << m_iCols << endl; -// cout << m_iRowInc / m_iCols << endl; - - if( (m_iRowInc / m_iCols) == 1 ) - { - frame = cv::Mat(m_iRows, m_iCols, CV_8UC1, pWriteBuffer, m_iRowInc);// = imread(pszFilename); - }else if ( (m_iRowInc / m_iCols) == 3 ) - { - frame = cv::Mat(m_iRows, m_iCols, CV_8UC3, pWriteBuffer, m_iRowInc);// = imread(pszFilename); - }else if ( (m_iRowInc / m_iCols) == 4 ) - { - frame = cv::Mat(m_iRows, m_iCols, CV_8UC4, pWriteBuffer, m_iRowInc);// = imread(pszFilename); - cv::cvtColor(frame,frame,cv::COLOR_RGBA2RGB); // need for right image interpretation - }else - { - std::cout << "error: unkown video format." << std::endl; - return false; - } - if( !frame.data ) - { - std::cout << "error: while saving video data." << std::endl; - return false; - } - - - //frame.create(m_vWriter.get(CV_CAP_PROP_FRAME_WIDTH),m_vWriter.get(CV_CAP_PROP_FRAME_HEIGHT),CV_8UC3); - //frame.data = (unsigned char*) pBuffer; - - //const unsigned char* pWriteBuffer = pBuffer; - -// namedWindow("TEST"); -// imshow("TEST",frame); -// waitKey(1); - -// cout << "Frame size: " << frame.rows << "x" << frame.cols << endl; -// cout << "Videowriter size:" << m_iRows << "x" << m_iCols << endl; - -// m_vWriter.write(frame.clone()); - m_vWriter.write(frame); - - /** - * ToDo: invertieren - * - */ - - //LONG lSamplesWritten; - //LONG lBytesWritten; - long lBytesWritten = 0; - - // - // If the AVI file is opened with openSizeLimitedAVI(), split it if necessory. - // - if (m_bSizeLimited) - { - // - // Split the file if it is more than 'AVI_FILE_SPLIT_SIZE' bytes - // - //if(bytesWritten() >= (__int64)(AVI_FILE_SPLIT_SIZE)) - if(bytesWritten() >= (long int)(AVI_FILE_SPLIT_SIZE)) - { - std::string szAVIFile; - std::stringstream stringStream; - close(); - m_iSplitFile++; - stringStream << m_szAVIDestFile << "_" << std::setfill('0') << std::setw(4) << m_iSplitFile << ".avi"; - szAVIFile = stringStream.str(); - - if( !open( szAVIFile.c_str(), m_iCols, m_iRows, m_iBPP, m_frameRate ) ) - return false; - } - } - - m_liBytesWritten += lBytesWritten; - - m_iTimeIndex++; - - return true; + if(!m_vWriter.isOpened()) + { + assert(false); + return false; + } + + + unsigned char *pWriteBuffer = (unsigned char *) pBuffer; + cv::Mat frame; + + if((m_iRowInc / m_iCols) == 1) + { + frame = cv::Mat(m_iRows, m_iCols, CV_8UC1, pWriteBuffer, m_iRowInc); // = imread(pszFilename); + } + else if((m_iRowInc / m_iCols) == 3) + { + frame = cv::Mat(m_iRows, m_iCols, CV_8UC3, pWriteBuffer, m_iRowInc); // = imread(pszFilename); + } + else if((m_iRowInc / m_iCols) == 4) + { + frame = cv::Mat(m_iRows, m_iCols, CV_8UC4, pWriteBuffer, m_iRowInc); // = imread(pszFilename); + cv::cvtColor(frame, frame, cv::COLOR_RGBA2RGB); // need for right image interpretation + } + else + { + std::cout << "error: unkown video format." << std::endl; + return false; + } + if(!frame.data) + { + std::cout << "error: while saving video data." << std::endl; + return false; + } + + m_vWriter.write(frame); + + /** + * ToDo: invertieren + * + */ + + long lBytesWritten = 0; + + // + // If the AVI file is opened with openSizeLimitedAVI(), split it if necessory. + // + if(m_bSizeLimited) + { + // + // Split the file if it is more than 'AVI_FILE_SPLIT_SIZE' bytes + // + // if(bytesWritten() >= (__int64)(AVI_FILE_SPLIT_SIZE)) + if(bytesWritten() >= (long int) (AVI_FILE_SPLIT_SIZE)) + { + std::string szAVIFile; + std::stringstream stringStream; + close(); + m_iSplitFile++; + stringStream << m_szAVIDestFile << "_" << std::setfill('0') << std::setw(4) << m_iSplitFile << ".avi"; + szAVIFile = stringStream.str(); + + if(!open(szAVIFile.c_str(), m_iCols, m_iRows, m_iBPP, m_frameRate)) + return false; + } + } + + m_liBytesWritten += lBytesWritten; + + m_iTimeIndex++; + + return true; } bool AviFileWriter::close() { - m_vWriter.release(); - return true; + m_vWriter.release(); + return true; } -bool AviFileWriter::appendBMP( const char* pszFilename ) +bool AviFileWriter::appendBMP(const char *pszFilename) { + cv::Mat bmpFrame = cv::imread(pszFilename); - cv::Mat bmpFrame = cv::imread(pszFilename); + m_vWriter.write(bmpFrame); - m_vWriter.write(bmpFrame); + m_iTimeIndex++; - m_iTimeIndex++; - - return true; + return true; } bool AviFileWriter::checkOpenCVVersion() { - //std::cout << "Established OpenCV Version: " << CV_VERSION << std::endl; - //cout << "Version: " << CV_VERSION - // << ", Major Version: " << CV_MAJOR_VERSION - // << ", Minor Version: " << CV_MINOR_VERSION - // << ", Subminor Version: " << CV_SUBMINOR_VERSION - // << endl; - - //DWORD dwVer = ::VideoForWindowsVersion(); - - if constexpr ( CV_MAJOR_VERSION < 3 ) - { - assert( false ); // opencv version too old. - return false; - } - //else - // if( CV_MINOR_VERSION < 1 ) - //{ - // assert( false ); - // return false; - //} - - return true; + if constexpr(CV_MAJOR_VERSION < 3) + { + assert(false); // opencv version too old. + return false; + } + return true; } - - diff --git a/src/backgroundFilter.cpp b/src/backgroundFilter.cpp index 4ac9fc7f19f5a5bff6f4d70ebeb1193e7b5cb215..86b721eb0062fa97d609c9c670cb018dd251174e 100644 --- a/src/backgroundFilter.cpp +++ b/src/backgroundFilter.cpp @@ -19,13 +19,15 @@ */ #include "backgroundFilter.h" + #include "stereoContext.h" // nur temporaer fuer anzeige -#include <opencv2/highgui.hpp> #include "helper.h" -//TODO spaeter entfernen naechsten beiden zeilen +#include <opencv2/highgui.hpp> + +// TODO spaeter entfernen naechsten beiden zeilen #include "control.h" extern Control *cw; @@ -38,23 +40,21 @@ extern Control *cw; #define MIN_FOREGROUND_AREA -1000 // war:-400 -BackgroundFilter::BackgroundFilter() - :Filter() +BackgroundFilter::BackgroundFilter() : Filter() { - setOnCopy(false); // da img nur ausgelesen, aber bnicht veraendert wird kann auf eine kopie verzichtet werden (true ist default bei filter) + // da img nur ausgelesen, aber bnicht veraendert wird kann auf eine kopie verzichtet werden (true ist default bei + // filter) + setOnCopy(false); mLastFile = ""; } -BackgroundFilter::~BackgroundFilter() -{ - -} +BackgroundFilter::~BackgroundFilter() {} -cv::Mat BackgroundFilter::getForeground() // nutzen, wenn ueber ganzes bild foreground benutzt wird; NULL, wenn keine background subtraction aktiviert +// nutzen, wenn ueber ganzes bild foreground benutzt wird; NULL, wenn keine background subtraction aktiviert +cv::Mat BackgroundFilter::getForeground() { - return mForeground; } @@ -69,8 +69,8 @@ cv::Mat BackgroundFilter::getForeground() // nutzen, wenn ueber ganzes bild fore */ bool BackgroundFilter::isForeground(int coloumn, int row) { - if (!mForeground.empty()) - return (bool) mForeground.data[row*mForeground.cols+coloumn]; // 0 background, 1 foreground + if(!mForeground.empty()) + return (bool) mForeground.data[row * mForeground.cols + coloumn]; // 0 background, 1 foreground else return false; } @@ -78,11 +78,12 @@ bool BackgroundFilter::isForeground(int coloumn, int row) /// zuruecksetzen, wenn zB helligkeit veraendert wird oder schaerfe void BackgroundFilter::reset() { - if (!mForeground.empty()) mForeground = cv::Scalar::all(0); - if (!mBgModel.empty()) mBgModel->clear(); + if(!mForeground.empty()) + mForeground = cv::Scalar::all(0); + if(!mBgModel.empty()) + mBgModel->clear(); setChanged(true); - } QString BackgroundFilter::getFilename() @@ -95,97 +96,104 @@ void BackgroundFilter::setFilename(const QString &fn) } // rueckgabe, ob speichern geklappt hat -bool BackgroundFilter::save(QString /*dest*/) //default = "" +bool BackgroundFilter::save(QString /*dest*/) // default = "" { #ifndef STEREO_DISABLED - if (*stereoContext() && !mBgPointCloud.empty()) + if(*stereoContext() && !mBgPointCloud.empty()) { // if no destination file or folder is given - if (dest.isEmpty()) + if(dest.isEmpty()) { - dest = QFileDialog::getSaveFileName(NULL, "Select file for background subtraction in stereo mode", mLastFile, - "Background picture (*.png);;All files (*.*)"); + dest = QFileDialog::getSaveFileName( + NULL, + "Select file for background subtraction in stereo mode", + mLastFile, + "Background picture (*.png);;All files (*.*)"); } - if (!dest.isEmpty()) + if(!dest.isEmpty()) { - if (dest.right(4) != ".png") + if(dest.right(4) != ".png") dest = dest + ".png"; - Mat bgImg(Size(mBgPointCloud.cols,mBgPointCloud.rows),CV_8UC1); -// IplImage *bgImg = cvCreateImage(cvSize(mBgPointCloud->width, mBgPointCloud->height), IPL_DEPTH_8U, 1); // CV_8UC1 8, 1 + Mat bgImg(Size(mBgPointCloud.cols, mBgPointCloud.rows), CV_8UC1); + // IplImage *bgImg = cvCreateImage(cvSize(mBgPointCloud->width, mBgPointCloud->height), + // IPL_DEPTH_8U, 1); // CV_8UC1 8, 1 // minimum der z-Werte bestimmen - float* data = (float*) mBgPointCloud.data; - float* yData = data; - int x,y; - float min = FLT_MAX; - float max = FLT_MIN; + float *data = (float *) mBgPointCloud.data; + float *yData = data; + int x, y; + float min = FLT_MAX; + float max = FLT_MIN; - for (y = 0; y < mBgPointCloud.rows; ++y) + for(y = 0; y < mBgPointCloud.rows; ++y) { - for (x = 0; x < mBgPointCloud.cols; ++x) + for(x = 0; x < mBgPointCloud.cols; ++x) { - if (data[2] != -1) + if(data[2] != -1) { - if (data[2] > max) + if(data[2] > max) max = data[2]; - else if (data[2] < min) + else if(data[2] < min) min = data[2]; } - data+=3; + data += 3; } - data = (yData += mBgPointCloud.cols/sizeof(float)); + data = (yData += mBgPointCloud.cols / sizeof(float)); } // uebetragen der z-werte in 8-bit-bild --------------------------------------------------------- // quantisierung fuehrt dazu, dass bei 10m maximaler spannweite pro grauwertstufe 4cm - data = (float*) mBgPointCloud.data; - yData = data; - float scale = (255-1)/(max-min); // 10 wird als unterster Wert genommen, damit 0 fuer ungueltigen wert stehen kann - unsigned char* bgImgData = (unsigned char*) bgImg.data; - unsigned char* ybgImgData = bgImgData; - - for (y = 0; y < mBgPointCloud.rows; ++y) + data = (float *) mBgPointCloud.data; + yData = data; + float scale = (255 - 1) / + (max - min); // 10 wird als unterster Wert genommen, damit 0 fuer ungueltigen wert stehen kann + unsigned char *bgImgData = (unsigned char *) bgImg.data; + unsigned char *ybgImgData = bgImgData; + + for(y = 0; y < mBgPointCloud.rows; ++y) { - for (x = 0; x < mBgPointCloud.cols; ++x) + for(x = 0; x < mBgPointCloud.cols; ++x) { - if (data[2] != -1) - *bgImgData = 1+scale*(data[2]-min); + if(data[2] != -1) + *bgImgData = 1 + scale * (data[2] - min); else // schwarz bedeutet keine Info *bgImgData = 0; - data+=3; + data += 3; ++bgImgData; } - data = (yData += mBgPointCloud.cols/sizeof(float)); + data = (yData += mBgPointCloud.cols / sizeof(float)); bgImgData = (ybgImgData += bgImg.cols); } // min max in den ersten bytes des bildes verstecken ---------------------------------------- - if (sizeof(float) != 4) + if(sizeof(float) != 4) { debout << "Warning: the height range coded inside the background picture is not portable!" << endl; } memmove(bgImg.data, &min, sizeof(float)); - memmove(bgImg.data+sizeof(float), &max, sizeof(float)); -// double dmin, dmax; -// cvMinMaxLoc(bgImg, &dmin, &dmax); -// debout << dmin << " " << dmax << endl; -// debout << bgImg->depth << " " << bgImg->nChannels << endl; -// debout << (int)*((char *) bgImg->imageData) << " " -// << (int)*(((char *) bgImg->imageData)+1) << " " -// << (int)*(((char *) bgImg->imageData)+2) << " " -// << (int)*(((char *) bgImg->imageData)+3) <<endl; -// debout << min << " " << max << endl; - - // wg, koennte es auch ueber meta-daten uebertragen werden CVAPI(int) cvSaveImage( const char* filename, const CvArr* image, const int* params CV_DEFAULT(0) ); - imwrite(dest.toStdString(),bgImg); -// cvSaveImage(dest.toStdString().c_str(), bgImg); + memmove(bgImg.data + sizeof(float), &max, sizeof(float)); + // double dmin, dmax; + // cvMinMaxLoc(bgImg, &dmin, &dmax); + // debout << dmin << " " << dmax << endl; + // debout << bgImg->depth << " " << bgImg->nChannels << endl; + // debout << (int)*((char *) bgImg->imageData) << " " + // << (int)*(((char *) bgImg->imageData)+1) << " " + // << (int)*(((char *) bgImg->imageData)+2) << " " + // << (int)*(((char *) bgImg->imageData)+3) <<endl; + // debout << min << " " << max << endl; + + // wg, koennte es auch ueber meta-daten uebertragen werden CVAPI(int) cvSaveImage( const char* filename, + // const CvArr* image, const int* params CV_DEFAULT(0) ); + imwrite(dest.toStdString(), bgImg); + // cvSaveImage(dest.toStdString().c_str(), bgImg); mLastFile = dest; - debout << "export background subtraction file for stereo mode: " << dest << " (minimal z value "<<min<<", maximal z value "<<max<<")." << endl; + debout << "export background subtraction file for stereo mode: " << dest << " (minimal z value " << min + << ", maximal z value " << max << ")." << endl; } else return false; @@ -199,69 +207,75 @@ bool BackgroundFilter::save(QString /*dest*/) //default = "" } // rueckgabe, ob einlesen geklappt hat -// das mappen von foat->char->float fuehrt dazu, dass beim laden nicht mehr volle 256 beim erneuten herausschreiben vorhanden sind!!!!!!!!!!!!!!!!!!!!! -// wenn mit photoshop backgroundImgage veraendert wird muss darauf geachtet werden, dass photoshop in greyscale modus arbeitet!!!!!!!!!!!!!!!!!!!!!!!! -bool BackgroundFilter::load(QString dest) //default = "" +// das mappen von foat->char->float fuehrt dazu, dass beim laden nicht mehr volle 256 beim erneuten herausschreiben +// vorhanden sind!!!!!!!!!!!!!!!!!!!!! wenn mit photoshop backgroundImgage veraendert wird muss darauf geachtet werden, +// dass photoshop in greyscale modus arbeitet!!!!!!!!!!!!!!!!!!!!!!!! +bool BackgroundFilter::load(QString dest) // default = "" { - if (!mBgPointCloud.empty() || mBgModel != nullptr) // initialisierung - debout << "Warning: Eliminate existing background!" <<std::endl; + if(!mBgPointCloud.empty() || mBgModel != nullptr) // initialisierung + debout << "Warning: Eliminate existing background!" << std::endl; - if (1) // (*stereoContext()) // auskommentiert, damit bg auch angelegt werden kann, wenn noch kein video geladen wurde + if(1) // (*stereoContext()) // auskommentiert, damit bg auch angelegt werden kann, wenn noch kein video geladen + // wurde { // if no destination file or folder is given - if (dest.isEmpty()) + if(dest.isEmpty()) { - dest = QFileDialog::getOpenFileName(nullptr, "Select file for background subtraction in stereo mode", mLastFile, - "Background picture (*.png);;All files (*.*)"); + dest = QFileDialog::getOpenFileName( + nullptr, + "Select file for background subtraction in stereo mode", + mLastFile, + "Background picture (*.png);;All files (*.*)"); } - if (!dest.isEmpty()) + if(!dest.isEmpty()) { - cv::Mat bgImg = cv::imread(dest.toStdString(),cv::IMREAD_GRAYSCALE); - if (bgImg.empty()) + cv::Mat bgImg = cv::imread(dest.toStdString(), cv::IMREAD_GRAYSCALE); + if(bgImg.empty()) { - debout << "Error: could not read background subtraction file " << dest << "!" <<std::endl; + debout << "Error: could not read background subtraction file " << dest << "!" << std::endl; return false; } - if (mBgPointCloud.empty()) - mBgPointCloud.create(bgImg.rows,bgImg.cols, CV_32FC3); + if(mBgPointCloud.empty()) + mBgPointCloud.create(bgImg.rows, bgImg.cols, CV_32FC3); float min, max; // min max aus den ersten bytes auslesen memmove(&min, bgImg.data, sizeof(float)); - memmove(&max, bgImg.data+sizeof(float), sizeof(float)); + memmove(&max, bgImg.data + sizeof(float), sizeof(float)); - if constexpr (sizeof(float) != 4) + if constexpr(sizeof(float) != 4) debout << "Warning: the height range coded inside the background picture is not portable!" << std::endl; // uebetragen der z-werte in 8-bit-bild --------------------------------------------------------- // quantisierung fuehrt dazu, dass bei 10m maximaler spannweite pro grauwertstufe 4cm - float *data = (float*) mBgPointCloud.data; + float *data = (float *) mBgPointCloud.data; float *yData = data; - float scale = (max-min)/(255-1); // 10 wird als unterster Wert genommen, damit 0 fuer ungueltigen wert stehen kann - unsigned char* bgImgData = (unsigned char*) bgImg.data; - unsigned char* ybgImgData = bgImgData; - int x, y; + float scale = (max - min) / + (255 - 1); // 10 wird als unterster Wert genommen, damit 0 fuer ungueltigen wert stehen kann + unsigned char *bgImgData = (unsigned char *) bgImg.data; + unsigned char *ybgImgData = bgImgData; + int x, y; - for (y = 0; y < mBgPointCloud.rows; ++y) + for(y = 0; y < mBgPointCloud.rows; ++y) { - for (x = 0; x < mBgPointCloud.cols; ++x) + for(x = 0; x < mBgPointCloud.cols; ++x) { - if (*bgImgData != 0) - data[2] = min+scale*(*bgImgData-1); // -1, da 0 nicht gueltig markiert - else // schwarz bedeutet keine Info + if(*bgImgData != 0) + data[2] = min + scale * (*bgImgData - 1); // -1, da 0 nicht gueltig markiert + else // schwarz bedeutet keine Info data[2] = -1; data += 3; ++bgImgData; } - data = (yData += mBgPointCloud.cols/sizeof(float)); + data = (yData += mBgPointCloud.cols / sizeof(float)); bgImgData = (ybgImgData += bgImg.cols); } // size war in bild versteckt - umsetzung muss nun eliminert werden - data = (float*) mBgPointCloud.data; - for (y = 0; y < ((int) (2*sizeof(float))); ++y) + data = (float *) mBgPointCloud.data; + for(y = 0; y < ((int) (2 * sizeof(float))); ++y) { data[2] = -1; data += 3; @@ -270,10 +284,13 @@ bool BackgroundFilter::load(QString dest) //default = "" setChanged(true); mLastFile = dest; - if (mForeground.empty()) // wenn zuvor noch keine background subtraction an war oder ist - mForeground.create(cv::Size(bgImg.cols,bgImg.rows),CV_8UC1);// = cvCreateImage(cvSize(bgImg->width, bgImg->height), IPL_DEPTH_8U, 1); // CV_8UC1 8, 1 + if(mForeground.empty()) // wenn zuvor noch keine background subtraction an war oder ist + mForeground.create( + cv::Size(bgImg.cols, bgImg.rows), + CV_8UC1); // = cvCreateImage(cvSize(bgImg->width, bgImg->height), IPL_DEPTH_8U, 1); // CV_8UC1 8, 1 - debout << "import background subtraction file (min "<<min<<", max "<<max<<") for stereo mode: " << dest << "." << std::endl; + debout << "import background subtraction file (min " << min << ", max " << max + << ") for stereo mode: " << dest << "." << std::endl; } else return false; // keine dest ausgesucht @@ -304,7 +321,7 @@ void BackgroundFilter::setStereoContext(pet::StereoContext **sc) { mStereoContext = sc; } -pet::StereoContext** BackgroundFilter::stereoContext() +pet::StereoContext **BackgroundFilter::stereoContext() { return mStereoContext; } @@ -312,15 +329,17 @@ pet::StereoContext** BackgroundFilter::stereoContext() cv::Mat BackgroundFilter::act(cv::Mat &img, cv::Mat &res) { #ifdef SHOW_TMP_IMG -namedWindow("BackgroundFilter"); -imshow("BackgroundFilter",img); -waitKey(); + namedWindow("BackgroundFilter"); + imshow("BackgroundFilter", img); + waitKey(); #endif - if ((mBgPointCloud.empty() && mBgModel.empty()) || mForeground.empty() || mForeground.size != img.size) // initialisierung wenn entwerder stereo oder model + if((mBgPointCloud.empty() && mBgModel.empty()) || mForeground.empty() || + mForeground.size != img.size) // initialisierung wenn entwerder stereo oder model { #ifndef STEREO_DISABLED -// For StereoImaging use heightfiled for foreground extraction ------------------------------------------------------------------------------- - if (*stereoContext()) + // For StereoImaging use heightfiled for foreground extraction + // ------------------------------------------------------------------------------- + if(*stereoContext()) { // aktuell wird pro pixel nur der z-wert betrachtet, // um aber entlang waenden personen auch vom hintergrund abheben zu koennen @@ -328,243 +347,256 @@ waitKey(); // dafuer datenstruktue (zB aequidistantes gitter) in dem korrespondierender z-wert gesucht wird // -> plan view statistic - //bgDisparity = cvCloneImage((*stereoContext())->getDisparity()); - mBgPointCloud = cvarrToMat((*stereoContext())->getPointCloud()).clone();// = cvCloneMat((*stereoContext())->getPointCloud()); + // bgDisparity = cvCloneImage((*stereoContext())->getDisparity()); + mBgPointCloud = cvarrToMat((*stereoContext())->getPointCloud()) + .clone(); // = cvCloneMat((*stereoContext())->getPointCloud()); // interpolate z-values inbetween innerhalb zeile - int x, y; + int x, y; float *vorPtr; // zeigt auf den letzten gueltigen Wert vor ungueltigem wert in einer Zeile float *nachPtr; // zeigt auf den ersten gueltigen Wert nach ungueltigen in einer Zeile float *fPtr; - float step; + float step; - float *bgPcData = (float *) mBgPointCloud.data; + float *bgPcData = (float *) mBgPointCloud.data; float *bgyPcData = bgPcData; - for (y = 0; y < mBgPointCloud.rows; ++y) + for(y = 0; y < mBgPointCloud.rows; ++y) { vorPtr = nachPtr = NULL; - for (x = 0; x < (mBgPointCloud.cols)-1; ++x) // -1 da in zukunft getestet wird, dadurch letztes pixel ungeprueft + for(x = 0; x < (mBgPointCloud.cols) - 1; + ++x) // -1 da in zukunft getestet wird, dadurch letztes pixel ungeprueft { - if (vorPtr == NULL && bgPcData[2] != -1 && bgPcData[5] == -1) // eine unbestimmte gap beginnt + if(vorPtr == NULL && bgPcData[2] != -1 && bgPcData[5] == -1) // eine unbestimmte gap beginnt vorPtr = bgPcData; - else if (nachPtr == NULL && bgPcData[2] == -1 && bgPcData[5] != -1) // eine unbestimmte gap endet + else if(nachPtr == NULL && bgPcData[2] == -1 && bgPcData[5] != -1) // eine unbestimmte gap endet { - if (vorPtr != NULL) // innenliegende gap - nachPtr = bgPcData+3; + if(vorPtr != NULL) // innenliegende gap + nachPtr = bgPcData + 3; else // zeilenbeginn { - for (fPtr = bgyPcData; fPtr < bgPcData+3; fPtr+=3) + for(fPtr = bgyPcData; fPtr < bgPcData + 3; fPtr += 3) { fPtr[2] = bgPcData[5]; } } } - if (vorPtr != NULL && nachPtr != NULL) // gap bestimmt, fuellung mit interpolerten werten + if(vorPtr != NULL && nachPtr != NULL) // gap bestimmt, fuellung mit interpolerten werten { - //debout << vorPtr[2] <<endl; - //debout << nachPtr[2] <<endl; - step = ((nachPtr[2]-vorPtr[2])/(nachPtr-vorPtr)); // lange zeit war falsch: /9.; // /3 ein /3 durch (fPtr-vorPtr) und nicht (fPtr-vorPtr)/3 in schleife - for (fPtr = vorPtr+3; fPtr < nachPtr; fPtr+=3) + // debout << vorPtr[2] <<endl; + // debout << nachPtr[2] <<endl; + step = + ((nachPtr[2] - vorPtr[2]) / + (nachPtr - vorPtr)); // lange zeit war falsch: /9.; // /3 ein /3 durch (fPtr-vorPtr) und + // nicht (fPtr-vorPtr)/3 in schleife + for(fPtr = vorPtr + 3; fPtr < nachPtr; fPtr += 3) { - //fPtr[0] = ; // x - //fPtr[1] = ; // y - fPtr[2] = vorPtr[2]+(fPtr-vorPtr)*step; - //debout << fPtr[2] <<endl; + // fPtr[0] = ; // x + // fPtr[1] = ; // y + fPtr[2] = vorPtr[2] + (fPtr - vorPtr) * step; + // debout << fPtr[2] <<endl; } vorPtr = nachPtr = NULL; } - bgPcData+=3; + bgPcData += 3; } - if (vorPtr != NULL) // gap am zeilenende + if(vorPtr != NULL) // gap am zeilenende { - for (fPtr = vorPtr; fPtr < bgPcData; fPtr+=3) + for(fPtr = vorPtr; fPtr < bgPcData; fPtr += 3) { fPtr[2] = vorPtr[-1]; } } - bgPcData = (bgyPcData += mBgPointCloud.cols/sizeof(float)); + bgPcData = (bgyPcData += mBgPointCloud.cols / sizeof(float)); } - mForeground.create(Size(img.cols,img.rows),CV_8UC1); -// mForeground = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_8U, 1); // CV_8UC1 8, 1 + mForeground.create(Size(img.cols, img.rows), CV_8UC1); + // mForeground = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_8U, 1); // CV_8UC1 8, 1 } else // nicht stereo -#endif // STEREO_DISABLED +#endif // STEREO_DISABLED { - -// GaussBGStatModel --------------------------------------------------------------------------------------------------------------------- - + // GaussBGStatModel + // --------------------------------------------------------------------------------------------------------------------- - if(!mBgModel.empty()) - mBgModel->clear(); + if(!mBgModel.empty()) + mBgModel->clear(); - mBgModel = cv::createBackgroundSubtractorMOG2(); + mBgModel = cv::createBackgroundSubtractorMOG2(); - mForeground.create(cv::Size(img.cols,img.rows),CV_8UC1); + mForeground.create(cv::Size(img.cols, img.rows), CV_8UC1); - mBgModel->apply(img,mForeground,1); + mBgModel->apply(img, mForeground, 1); #ifdef SHOW_TMP_IMG -namedWindow("BackgroundFilter"); -imshow("BackgroundFilter",mForeground); -waitKey(); + namedWindow("BackgroundFilter"); + imshow("BackgroundFilter", mForeground); + waitKey(); #endif -// FGDStatModel --------------------------------------------------------------------------------------------------------------------- + // FGDStatModel + // --------------------------------------------------------------------------------------------------------------------- - // DOCUMENTATION: http://opencv.willowgarage.com/wiki/VideoSurveillance + // DOCUMENTATION: http://opencv.willowgarage.com/wiki/VideoSurveillance } // nicht stereo } else // nicht initialisierung { - -// SteroBild beruecksichtigen nur disparity -------------------------------------------------------------------------------------------------------- - if (*stereoContext()) - { + // SteroBild beruecksichtigen nur disparity + // -------------------------------------------------------------------------------------------------------- + if(*stereoContext()) + { #ifndef STEREO_DISABLED -// fuer update waere bei stereo denkbar: mittelwert der disp/zwerte, aber Achtung: invalidDisp beruecksichtigen! + // fuer update waere bei stereo denkbar: mittelwert der disp/zwerte, aber Achtung: invalidDisp + // beruecksichtigen! + + + // unsigned short* bgData = (unsigned short*) bgDisparity->imageData; // disparity zum + // reset-Zeitpunkt (Hintergrund) unsigned short* bgyData = bgData; + + // IplImage *disparity = (*stereoContext())->getDisparity(); + // unsigned short* data = (unsigned short*) disparity->imageData; + // unsigned short* yData = data; + + // int x,y; + + // for (y = 0; y < bgDisparity->height; ++y) + // { + // for (x = 0; x < bgDisparity->width; ++x) + // { + // if ((*stereoContext())->dispValueValid(*data) && + // (*stereoContext())->dispValueValid(*bgData)) + // { + // if (fabs(*data-*bgData) > 100) + // mForeground->imageData[y*bgDisparity->width+x] = 1; + // } + // ++data; + // ++bgData; + // pcData+=3; + // bgPcData+=3; + // } + // data = (yData += disparity->width); + // bgData = (bgyData += bgDisparity->width); + // } + + // SteroBild beruecksichtigen z-wert + // -------------------------------------------------------------------------------------------------------- + int x, y; -// unsigned short* bgData = (unsigned short*) bgDisparity->imageData; // disparity zum reset-Zeitpunkt (Hintergrund) -// unsigned short* bgyData = bgData; - -// IplImage *disparity = (*stereoContext())->getDisparity(); -// unsigned short* data = (unsigned short*) disparity->imageData; -// unsigned short* yData = data; - -// int x,y; - -// for (y = 0; y < bgDisparity->height; ++y) -// { -// for (x = 0; x < bgDisparity->width; ++x) -// { -// if ((*stereoContext())->dispValueValid(*data) && (*stereoContext())->dispValueValid(*bgData)) -// { -// if (fabs(*data-*bgData) > 100) -// mForeground->imageData[y*bgDisparity->width+x] = 1; -// } -// ++data; -// ++bgData; -// pcData+=3; -// bgPcData+=3; -// } -// data = (yData += disparity->width); -// bgData = (bgyData += bgDisparity->width); -// } - -// SteroBild beruecksichtigen z-wert -------------------------------------------------------------------------------------------------------- - - int x,y; - - float *bgPcData = (float *) mBgPointCloud.data; - float *bgyPcData = bgPcData; + float *bgPcData = (float *) mBgPointCloud.data; + float *bgyPcData = bgPcData; - Mat pointCloud = cvarrToMat((*stereoContext())->getPointCloud()); - float *pcData = (float *) pointCloud.data; - float *yPcData = pcData; + Mat pointCloud = cvarrToMat((*stereoContext())->getPointCloud()); + float *pcData = (float *) pointCloud.data; + float *yPcData = pcData; - mForeground = Scalar(0,0,0); -// cvSet(mForeground, CV_RGB(0,0,0)); -// cvFillImage(mForeground, 0); //um vorherige foreground-berechungen zu vergessen + mForeground = Scalar(0, 0, 0); + // cvSet(mForeground, CV_RGB(0,0,0)); + // cvFillImage(mForeground, 0); //um vorherige foreground-berechungen zu vergessen - for (y = 0; y < pointCloud.rows; ++y) + for(y = 0; y < pointCloud.rows; ++y) + { + for(x = 0; x < pointCloud.cols; ++x) { - for (x = 0; x < pointCloud.cols; ++x) + if((bgPcData[2] != -1) && (pcData[2] != -1)) { - if ((bgPcData[2] != -1) && (pcData[2] != -1)) + if((bgPcData[2] - pcData[2]) > + FOREGROUND_DISTANCE) // z-Wert in m (nicht cm!) wenn z-wert 1m unter defaultgroesse { - if ((bgPcData[2]-pcData[2]) > FOREGROUND_DISTANCE) // z-Wert in m (nicht cm!) wenn z-wert 1m unter defaultgroesse - { - mForeground.data[y*pointCloud.cols+x] = 1; - } - //if (y == 488) - // debout << bgPcData[2] << " " << pcData[2] <<endl; + mForeground.data[y * pointCloud.cols + x] = 1; } - pcData+=3; - bgPcData+=3; + // if (y == 488) + // debout << bgPcData[2] << " " << pcData[2] <<endl; } - pcData = (yPcData += pointCloud.cols/sizeof(float)); - bgPcData = (bgyPcData += mBgPointCloud.cols/sizeof(float)); + pcData += 3; + bgPcData += 3; } + pcData = (yPcData += pointCloud.cols / sizeof(float)); + bgPcData = (bgyPcData += mBgPointCloud.cols / sizeof(float)); + } #endif - } -else // nicht stereo - { - -// GaussBGStatModel --------------------------------------------------------------------------------------------------------------------- + } + else // nicht stereo + { + // GaussBGStatModel + // --------------------------------------------------------------------------------------------------------------------- - mBgModel->apply(img, mForeground, update() ? -1 : 0); + mBgModel->apply(img, mForeground, update() ? -1 : 0); #ifdef SHOW_TMP_IMG -imshow("BackgroundFilter",img); -waitKey(); + imshow("BackgroundFilter", img); + waitKey(); #endif - - } + } #ifdef SHOW_TMP_IMG -imshow("BackgroundFilter",mForeground); -waitKey(); + imshow("BackgroundFilter", mForeground); + waitKey(); #endif - // einfache methode, um kleine gebiete in maske zu eliminieren und ausfransungen zu entfernen --------------------------------------------------- + // einfache methode, um kleine gebiete in maske zu eliminieren und ausfransungen zu entfernen + // --------------------------------------------------- - cv::erode(mForeground,mForeground,cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3)),cv::Point(-1,-1),1); + cv::erode( + mForeground, mForeground, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)), cv::Point(-1, -1), 1); #ifdef SHOW_TMP_IMG -imshow("BackgroundFilter",mForeground); -waitKey(); + imshow("BackgroundFilter", mForeground); + waitKey(); #endif - cv::dilate(mForeground,mForeground,cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3)),cv::Point(-1,-1),2); + cv::dilate( + mForeground, mForeground, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)), cv::Point(-1, -1), 2); #ifdef SHOW_TMP_IMG -imshow("BackgroundFilter",mForeground); -waitKey(); + imshow("BackgroundFilter", mForeground); + waitKey(); #endif - cv::GaussianBlur(mForeground,mForeground,cv::Size(11,11),3.5,3.5); + cv::GaussianBlur(mForeground, mForeground, cv::Size(11, 11), 3.5, 3.5); #ifdef SHOW_TMP_IMG -imshow("BackgroundFilter",mForeground); -waitKey(); + imshow("BackgroundFilter", mForeground); + waitKey(); #endif - cv::threshold(mForeground,mForeground,20,255,cv::THRESH_BINARY); + cv::threshold(mForeground, mForeground, 20, 255, cv::THRESH_BINARY); #ifdef SHOW_TMP_IMG -imshow("BackgroundFilter",mForeground); -waitKey(); + imshow("BackgroundFilter", mForeground); + waitKey(); #endif - // loecher schliessen ------------------------------------------------------------------------------------------------------------ - // floodfill den aussenbereich und suchen nach ungefuelltem koennte auch loechder finden alssen - std::vector<std::vector<cv::Point> > contours; - double contourArea; - // find contours and store them all as a list - cv::findContours(mForeground,contours,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE); - - // test each contour - - while (!contours.empty()) - { - std::vector<cv::Point> contour = contours.back(); - - contourArea = cv::contourArea(contour, true); - if (contourArea > 0 && contourArea < 400) // kleine innere loecher schliessen - { - // Get contour point set. - cv::fillPoly(mForeground,cv::Mat(contour),cv::Scalar::all(1)); - } - else if (contourArea > MIN_FOREGROUND_AREA -400) // kleine Bereiche werden eliminiert, dies koennte in Abhaengigkeit von der disparity gemacht werden!!!!!!!! - { - // Get contour point set. - cv::fillPoly(mForeground,cv::Mat(contour),cv::Scalar::all(0)); - } - // take the next contour - contours.pop_back(); - } + // loecher schliessen + // ------------------------------------------------------------------------------------------------------------ + // floodfill den aussenbereich und suchen nach ungefuelltem koennte auch loechder finden alssen + std::vector<std::vector<cv::Point>> contours; + double contourArea; + // find contours and store them all as a list + cv::findContours(mForeground, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); + + // test each contour + + while(!contours.empty()) + { + std::vector<cv::Point> contour = contours.back(); + + contourArea = cv::contourArea(contour, true); + if(contourArea > 0 && contourArea < 400) // kleine innere loecher schliessen + { + // Get contour point set. + cv::fillPoly(mForeground, cv::Mat(contour), cv::Scalar::all(1)); + } + else if(contourArea > MIN_FOREGROUND_AREA - 400) // kleine Bereiche werden eliminiert, dies koennte in + // Abhaengigkeit von der disparity gemacht werden!!!!!!!! + { + // Get contour point set. + cv::fillPoly(mForeground, cv::Mat(contour), cv::Scalar::all(0)); + } + // take the next contour + contours.pop_back(); + } #ifdef SHOW_TMP_IMG -imshow("BackgroundFilter",mForeground); -waitKey(); + imshow("BackgroundFilter", mForeground); + waitKey(); #endif } @@ -576,32 +608,32 @@ waitKey(); // bisher nur fuer float void BackgroundFilter::maskBg(cv::Mat &mat, float val) { - if (getEnabled() && !mForeground.empty()) + if(getEnabled() && !mForeground.empty()) { - int x, y; + int x, y; - int lineLen = mat.cols/sizeof(float); - int ch = lineLen/mat.cols; - float *pcData = ((float *) mat.data) + ch-1; // ch-1 um beim letzten element zu stehen (wie pcData[2]) - float *yPcData = pcData; + int lineLen = mat.cols / sizeof(float); + int ch = lineLen / mat.cols; + float *pcData = ((float *) mat.data) + ch - 1; // ch-1 um beim letzten element zu stehen (wie pcData[2]) + float *yPcData = pcData; - unsigned char* fgData = (unsigned char*) mForeground.data; - unsigned char* yFgData = fgData; + unsigned char *fgData = (unsigned char *) mForeground.data; + unsigned char *yFgData = fgData; - for (y = 0; y < mat.rows; ++y) + for(y = 0; y < mat.rows; ++y) + { + for(x = 0; x < mat.cols; ++x) { - for (x = 0; x < mat.cols; ++x) + // 0 background, 1 foreground + if(!*fgData) { - // 0 background, 1 foreground - if(!*fgData) - { - *pcData = val; - } - ++fgData; - pcData += ch; + *pcData = val; } - pcData = (yPcData += lineLen); - fgData = (yFgData += mForeground.cols); + ++fgData; + pcData += ch; } + pcData = (yPcData += lineLen); + fgData = (yFgData += mForeground.cols); + } } } diff --git a/src/backgroundItem.cpp b/src/backgroundItem.cpp index ce803644c2453c2313714fbd3b2da757c8052e93..81ab3793ba53de18362391676715e0061dc74b75 100644 --- a/src/backgroundItem.cpp +++ b/src/backgroundItem.cpp @@ -18,20 +18,20 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> +#include "backgroundItem.h" #include "petrack.h" #include "view.h" -#include "backgroundItem.h" + +#include <QtWidgets> // in x und y gleichermassen skaliertes koordinatensystem, // da von einer vorherigen intrinsischen kamerakalibrierung ausgegenagen wird, -// so dass pixel quadratisch -BackgroundItem::BackgroundItem(QWidget *wParent, QGraphicsItem * parent) - : QGraphicsItem(parent) +// so dass pixel quadratisch +BackgroundItem::BackgroundItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) { - mMainWindow = (class Petrack*) wParent; - mImage = nullptr; + mMainWindow = (class Petrack *) wParent; + mImage = nullptr; // setEnabled(false); // all mouse events cannot access this item, but it will be seen // einzig move koennte interessant sein, um grid zu verschieben?! } @@ -46,49 +46,53 @@ BackgroundItem::BackgroundItem(QWidget *wParent, QGraphicsItem * parent) */ QRectF BackgroundItem::boundingRect() const { - if (mMainWindow->getImage()) - return QRectF(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), mMainWindow->getImage()->width(), mMainWindow->getImage()->height()); + if(mMainWindow->getImage()) + return QRectF( + -mMainWindow->getImageBorderSize(), + -mMainWindow->getImageBorderSize(), + mMainWindow->getImage()->width(), + mMainWindow->getImage()->height()); else return QRectF(0, 0, 0, 0); } - -void BackgroundItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) + +void BackgroundItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { cv::Mat fg; - if (mMainWindow->getBackgroundFilter()) + if(mMainWindow->getBackgroundFilter()) fg = mMainWindow->getBackgroundFilter()->getForeground(); else return; - if (!fg.empty()) + if(!fg.empty()) { - if ((mImage != nullptr) && ((mImage->width() != fg.cols) || (mImage->height() != fg.rows))) + if((mImage != nullptr) && ((mImage->width() != fg.cols) || (mImage->height() != fg.rows))) delete mImage; - if (mImage == nullptr) // zu Beginn oder wenn sich die Groesse aendert + if(mImage == nullptr) // zu Beginn oder wenn sich die Groesse aendert mImage = new QImage(fg.cols, fg.rows, QImage::Format_ARGB32); - int x,y; - auto* data = fg.data; - auto* yData = data; + int x, y; + auto *data = fg.data; + auto *yData = data; - for (y = 0; y < fg.rows; y++) + for(y = 0; y < fg.rows; y++) { // Pointer to the data information in the QImage for just one column // set pointer to value before, because ++p is faster than p++ - auto* p = mImage->scanLine(y)-1; - for (x = 0; x < fg.cols; x++) + auto *p = mImage->scanLine(y) - 1; + for(x = 0; x < fg.cols; x++) { - *(++p) = 255; // color.red(); - *(++p) = 255; // color.green(); - *(++p) = 255; // color.blue(); - *(++p) = (1-*data)*255; // color.alpha(); // 255; + *(++p) = 255; // color.red(); + *(++p) = 255; // color.green(); + *(++p) = 255; // color.blue(); + *(++p) = (1 - *data) * 255; // color.alpha(); // 255; ++data; } data = (yData += fg.cols); } painter->setOpacity(0.7); - painter->drawImage(-mMainWindow->getImageBorderSize(),-mMainWindow->getImageBorderSize(), *mImage); + painter->drawImage(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), *mImage); } } diff --git a/src/blurFilter.cpp b/src/blurFilter.cpp index 387bb6c6687ac03821f692af662656caa240536b..d16c6044d7a10a53f9184440d395e371d2385276 100644 --- a/src/blurFilter.cpp +++ b/src/blurFilter.cpp @@ -19,17 +19,18 @@ */ #include "blurFilter.h" -#include <opencv2/opencv.hpp> +#include <opencv2/opencv.hpp> -cv::Mat BlurFilter::act(cv::Mat &img, cv::Mat &res){ - GaussianBlur(img,res,cv::Size(0,0),p*10+1,p*10+1); +cv::Mat BlurFilter::act(cv::Mat &img, cv::Mat &res) +{ + GaussianBlur(img, res, cv::Size(0, 0), p * 10 + 1, p * 10 + 1); return res; } -void BlurFilter::setParam(double newp){ +void BlurFilter::setParam(double newp) +{ p = newp; } - diff --git a/src/borderFilter.cpp b/src/borderFilter.cpp index 6e88dd013a875889c16a51e4c0564782856f64cf..6ff7fa2dbdb0d969db318b9676ae75e872e84979 100644 --- a/src/borderFilter.cpp +++ b/src/borderFilter.cpp @@ -21,8 +21,7 @@ #include "borderFilter.h" -BorderFilter::BorderFilter() - :Filter() +BorderFilter::BorderFilter() : Filter() { mS.setMinimum(0.); mS.setMaximum(200.); @@ -50,29 +49,30 @@ BorderFilter::BorderFilter() cv::Mat BorderFilter::act(cv::Mat &img, cv::Mat &res) { // border size - int s = (int) mS.getValue(); // schon beim zuweisen auf param gemacht (2*, da undistord filter anscheinend sonst probleme hat) + int s = (int) mS.getValue(); // schon beim zuweisen auf param gemacht (2*, da undistord filter anscheinend sonst + // probleme hat) int r = (int) mR.getValue(); int g = (int) mG.getValue(); int b = (int) mB.getValue(); - cv::copyMakeBorder(img,res, s, s, s, s,cv::BORDER_CONSTANT,cv::Scalar(b,g,r)); + cv::copyMakeBorder(img, res, s, s, s, s, cv::BORDER_CONSTANT, cv::Scalar(b, g, r)); return res; } -Parameter* BorderFilter::getBorderSize() +Parameter *BorderFilter::getBorderSize() { return &mS; } -Parameter* BorderFilter::getBorderColR() +Parameter *BorderFilter::getBorderColR() { return &mR; } -Parameter* BorderFilter::getBorderColG() +Parameter *BorderFilter::getBorderColG() { return &mG; } -Parameter* BorderFilter::getBorderColB() +Parameter *BorderFilter::getBorderColB() { return &mB; } diff --git a/src/brightContrastFilter.cpp b/src/brightContrastFilter.cpp index fd236d6ae1129e5023e542e91334354a7709acec..9523dbfcc49bed62838a39f7752fd2fa6493720a 100644 --- a/src/brightContrastFilter.cpp +++ b/src/brightContrastFilter.cpp @@ -21,8 +21,7 @@ #include "brightContrastFilter.h" -BrightContrastFilter::BrightContrastFilter() - :Filter() +BrightContrastFilter::BrightContrastFilter() : Filter() { mB.setMinimum(-100.); mB.setMaximum(100.); @@ -37,35 +36,34 @@ BrightContrastFilter::BrightContrastFilter() cv::Mat BrightContrastFilter::act(cv::Mat &img, cv::Mat &res) { - double delta, a, b; /* * The algorithm is by Werner D. Streidt * (http://visca.com/ffactory/archives/5-99/msg00021.html) */ - if (mC.getValue() > 0) + if(mC.getValue() > 0) { - delta = 127.*mC.getValue()/100.; - a = 255./(255. - delta*2.); - b = a*(mB.getValue() - delta); + delta = 127. * mC.getValue() / 100.; + a = 255. / (255. - delta * 2.); + b = a * (mB.getValue() - delta); } else { - delta = -128.*mC.getValue()/100.; - a = (256.-delta*2.)/255.; - b = a*mB.getValue() + delta; + delta = -128. * mC.getValue() / 100.; + a = (256. - delta * 2.) / 255.; + b = a * mB.getValue() + delta; } - img.convertTo(res,-1,a,b); + img.convertTo(res, -1, a, b); return res; } -Parameter* BrightContrastFilter::getBrightness() +Parameter *BrightContrastFilter::getBrightness() { return &mB; } -Parameter* BrightContrastFilter::getContrast() +Parameter *BrightContrastFilter::getContrast() { return &mC; } diff --git a/src/calibFilter.cpp b/src/calibFilter.cpp index 044bf355432f76fa5ab121cca895f3c99b9bee8e..4b7f4a151a07b3d3a56fe85ae0e11c8f0647bdaf 100644 --- a/src/calibFilter.cpp +++ b/src/calibFilter.cpp @@ -19,11 +19,11 @@ */ #include "calibFilter.h" + #include "helper.h" -CalibFilter::CalibFilter() - :Filter() +CalibFilter::CalibFilter() : Filter() { getFx()->setMinimum(500.); getFx()->setMaximum(5000.); @@ -100,70 +100,79 @@ cv::Mat CalibFilter::act(cv::Mat &img, cv::Mat &res) { if(this->changed() || map1.size() != img.size()) { - cv::Mat camera = (cv::Mat_<float>(3,3) << getFx()->getValue(), 0, getCx()->getValue(), - 0, getFy()->getValue(), getCy()->getValue(), - 0, 0, 1 ); - cv::Mat dist = (cv::Mat_<float>(1,8) << getR2()->getValue(), getR4()->getValue(), - getTx()->getValue(), getTy()->getValue(), - getR6()->getValue(), - getK4()->getValue(), getK5()->getValue(), getK6()->getValue()); - - - initUndistortRectifyMap(camera, dist, cv::Mat_<double>::eye(3,3), - camera, - img.size(), CV_16SC2, map1, map2); + cv::Mat camera = + (cv::Mat_<float>(3, 3) << getFx()->getValue(), + 0, + getCx()->getValue(), + 0, + getFy()->getValue(), + getCy()->getValue(), + 0, + 0, + 1); + cv::Mat dist = + (cv::Mat_<float>(1, 8) << getR2()->getValue(), + getR4()->getValue(), + getTx()->getValue(), + getTy()->getValue(), + getR6()->getValue(), + getK4()->getValue(), + getK5()->getValue(), + getK6()->getValue()); + + + initUndistortRectifyMap(camera, dist, cv::Mat_<double>::eye(3, 3), camera, img.size(), CV_16SC2, map1, map2); } cv::remap(img, res, map1, map2, cv::INTER_LINEAR, cv::BORDER_CONSTANT); return res; } -Parameter* CalibFilter::getFx() +Parameter *CalibFilter::getFx() { return &mFx; } -Parameter* CalibFilter::getFy() +Parameter *CalibFilter::getFy() { return &mFy; } -Parameter* CalibFilter::getCx() +Parameter *CalibFilter::getCx() { return &mCx; } -Parameter* CalibFilter::getCy() +Parameter *CalibFilter::getCy() { return &mCy; } -Parameter* CalibFilter::getR2() +Parameter *CalibFilter::getR2() { return &mR2; } -Parameter* CalibFilter::getR4() +Parameter *CalibFilter::getR4() { return &mR4; } -Parameter* CalibFilter::getTx() +Parameter *CalibFilter::getTx() { return &mTx; } -Parameter* CalibFilter::getTy() +Parameter *CalibFilter::getTy() { return &mTy; } -Parameter* CalibFilter::getR6() +Parameter *CalibFilter::getR6() { return &mR6; } -Parameter* CalibFilter::getK4() +Parameter *CalibFilter::getK4() { return &mK4; } -Parameter* CalibFilter::getK5() +Parameter *CalibFilter::getK5() { return &mK5; } -Parameter* CalibFilter::getK6() +Parameter *CalibFilter::getK6() { return &mK6; } - diff --git a/src/calibStereoFilter.cpp b/src/calibStereoFilter.cpp index 37addd08fffea32fec3a15c56f7f72f0be9b51d0..10a39b8919daf3f836b409739fb0447d0406ed30 100644 --- a/src/calibStereoFilter.cpp +++ b/src/calibStereoFilter.cpp @@ -20,21 +20,17 @@ #include "calibStereoFilter.h" -CalibStereoFilter::CalibStereoFilter() - :Filter() +CalibStereoFilter::CalibStereoFilter() : Filter() { setOnCopy(false); // da in stereoContext der Speicherplatz fuer res liegt } - - -cv::Mat CalibStereoFilter::act(cv::Mat &/*img*/, cv::Mat &/*res*/) +cv::Mat CalibStereoFilter::act(cv::Mat & /*img*/, cv::Mat & /*res*/) { return cv::Mat(); - } -void CalibStereoFilter::setStereoContext(pet::StereoContext* stereoContext) + +void CalibStereoFilter::setStereoContext(pet::StereoContext *stereoContext) { mStereoContext = stereoContext; } - diff --git a/src/codeMarkerItem.cpp b/src/codeMarkerItem.cpp index ba27927ee8b75dae682429ed27eb9d2256b5e4d8..2e4ab101bd977154b1bc65b2f2133a2f7f92da0c 100644 --- a/src/codeMarkerItem.cpp +++ b/src/codeMarkerItem.cpp @@ -18,22 +18,23 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> - -#include "petrack.h" -#include "view.h" #include "codeMarkerItem.h" + #include "codeMarkerWidget.h" -#include "tracker.h" #include "control.h" +#include "petrack.h" +#include "tracker.h" +#include "view.h" + +#include <QtWidgets> // in x und y gleichermassen skaliertes koordinatensystem, // da von einer vorherigen intrinsischen kamerakalibrierung ausgegenagen wird, // so dass pixel quadratisch -CodeMarkerItem::CodeMarkerItem(QWidget *wParent, const reco::CodeMarkerOptions &options, QGraphicsItem * parent) - : QGraphicsItem(parent), mArucoOptions(options) +CodeMarkerItem::CodeMarkerItem(QWidget *wParent, const reco::CodeMarkerOptions &options, QGraphicsItem *parent) : + QGraphicsItem(parent), mArucoOptions(options) { - mMainWindow = (class Petrack*) wParent; + mMainWindow = (class Petrack *) wParent; } @@ -47,13 +48,17 @@ CodeMarkerItem::CodeMarkerItem(QWidget *wParent, const reco::CodeMarkerOptions & */ QRectF CodeMarkerItem::boundingRect() const { - if (mMainWindow->getImage()) - return QRectF(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), mMainWindow->getImage()->width(), mMainWindow->getImage()->height()); + if(mMainWindow->getImage()) + return QRectF( + -mMainWindow->getImageBorderSize(), + -mMainWindow->getImageBorderSize(), + mMainWindow->getImage()->width(), + mMainWindow->getImage()->height()); else return QRectF(0, 0, 0, 0); } -void CodeMarkerItem::setRect(Vec2F& v) +void CodeMarkerItem::setRect(Vec2F &v) { mUlc = v; // upper left corner to draw } @@ -62,20 +67,19 @@ void CodeMarkerItem::setRect(Vec2F& v) * @brief draws colored shapes at heads in image to indicate detection status * * different calculations of position depending on whether function is called out of findCodeMarker() Function - * only (== recoMethod 6) or if findCodeMarker() Function is called out of findMulticolorMarker() Function (== recoMethod 5). - * In the first case the offset is added automatically via 'offset' and 'v'. - * In the second case the offset from cropRect to ROI has to be added manually. + * only (== recoMethod 6) or if findCodeMarker() Function is called out of findMulticolorMarker() Function (== + * recoMethod 5). In the first case the offset is added automatically via 'offset' and 'v'. In the second case the + * offset from cropRect to ROI has to be added manually. * * @param painter * @param option * @param widget */ -void CodeMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) +void CodeMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - - if (mMainWindow->getCodeMarkerWidget()->showDetectedCandidates()) + if(mMainWindow->getCodeMarkerWidget()->showDetectedCandidates()) { - int nMarkers = static_cast<int>(mCorners.size()); + int nMarkers = static_cast<int>(mCorners.size()); int nRejected = static_cast<int>(mRejected.size()); cv::Point2f p0, p1; @@ -89,39 +93,37 @@ void CodeMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */* } } - if (false) // Show min/max marker size + if(false) // Show min/max marker size { - int minPerimeter = mArucoOptions.getDetectorParams().getMinMarkerPerimeter(); - int maxPerimeter = mArucoOptions.getDetectorParams().getMaxMarkerPerimeter(); - double height = mMainWindow->getStatusPosRealHeight(); - - cv::Point2f p0,p1,p2,p3; - - p0 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(0,0,height)); - p1 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(maxPerimeter,0,height)); - p2 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(maxPerimeter,maxPerimeter,height)); - p3 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(0,maxPerimeter,height)); - - painter->setPen(qRgb(0,0,0)); - painter->drawLine(p0.x,+p0.y,p1.x,p1.y); - painter->drawLine(p1.x,+p1.y,p2.x,p2.y); - painter->drawLine(p2.x,+p2.y,p3.x,p3.y); - painter->drawLine(p3.x,p3.y,p0.x,p0.y); - - - p0 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(0,0,height)); - p1 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(minPerimeter,0,height)); - p2 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(minPerimeter,minPerimeter,height)); - p3 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(0,minPerimeter,height)); - - painter->setPen(qRgb(255,255,255)); - painter->drawLine(p0.x,p0.y,p1.x,p1.y); - painter->drawLine(p1.x,p1.y,p2.x,p2.y); - painter->drawLine(p2.x,p2.y,p3.x,p3.y); - painter->drawLine(p3.x,p3.y,p0.x,p0.y); - + int minPerimeter = mArucoOptions.getDetectorParams().getMinMarkerPerimeter(); + int maxPerimeter = mArucoOptions.getDetectorParams().getMaxMarkerPerimeter(); + double height = mMainWindow->getStatusPosRealHeight(); + + cv::Point2f p0, p1, p2, p3; + + p0 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(0, 0, height)); + p1 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(maxPerimeter, 0, height)); + p2 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(maxPerimeter, maxPerimeter, height)); + p3 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(0, maxPerimeter, height)); + + painter->setPen(qRgb(0, 0, 0)); + painter->drawLine(p0.x, +p0.y, p1.x, p1.y); + painter->drawLine(p1.x, +p1.y, p2.x, p2.y); + painter->drawLine(p2.x, +p2.y, p3.x, p3.y); + painter->drawLine(p3.x, p3.y, p0.x, p0.y); + + + p0 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(0, 0, height)); + p1 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(minPerimeter, 0, height)); + p2 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(minPerimeter, minPerimeter, height)); + p3 = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(0, minPerimeter, height)); + + painter->setPen(qRgb(255, 255, 255)); + painter->drawLine(p0.x, p0.y, p1.x, p1.y); + painter->drawLine(p1.x, p1.y, p2.x, p2.y); + painter->drawLine(p2.x, p2.y, p3.x, p3.y); + painter->drawLine(p3.x, p3.y, p0.x, p0.y); } - } /** @@ -134,22 +136,24 @@ void CodeMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */* * @param borderColor color of the rect drawn * @param painter painter with which to draw */ -void CodeMarkerItem::drawMarker(const OffsetMarker& currentMarker, int id, const QColor& borderColor, QPainter *painter) +void CodeMarkerItem::drawMarker(const OffsetMarker ¤tMarker, int id, const QColor &borderColor, QPainter *painter) { Vec2F offset = currentMarker.offset; // draw marker sides - for(int j = 0; j < numCorners; j++) { + for(int j = 0; j < numCorners; j++) + { Vec2F p0 = currentMarker.corners.at(j); Vec2F p1 = currentMarker.corners.at((j + 1) % numCorners); painter->setPen(borderColor); painter->drawLine((mUlc + p0 + offset).toQPointF(), (mUlc + p1 + offset).toQPointF()); } - Vec2F topLeftCorner {currentMarker.corners.at(0)}; + Vec2F topLeftCorner{currentMarker.corners.at(0)}; painter->setPen(mCornerColor); - if(id != -1) { - painter->drawText((mUlc + topLeftCorner + offset + Vec2F(10,10)).toQPointF(), QString::number(id)); + if(id != -1) + { + painter->drawText((mUlc + topLeftCorner + offset + Vec2F(10, 10)).toQPointF(), QString::number(id)); } - painter->drawRect(QRectF((mUlc + topLeftCorner + offset - Vec2F(3,3)).toQPointF(), QSize(6.0,6.0))); + painter->drawRect(QRectF((mUlc + topLeftCorner + offset - Vec2F(3, 3)).toQPointF(), QSize(6.0, 6.0))); } /** @@ -161,7 +165,10 @@ void CodeMarkerItem::drawMarker(const OffsetMarker& currentMarker, int id, const * @param ids ids of the detected markers * @param offset offset from marker-coords to recognition ROI */ -void CodeMarkerItem::addDetectedMarkers(std::vector<std::vector<cv::Point2f> > corners, std::vector<int> ids, Vec2F offset /* = (0,0)*/) +void CodeMarkerItem::addDetectedMarkers( + std::vector<std::vector<cv::Point2f>> corners, + std::vector<int> ids, + Vec2F offset /* = (0,0)*/) { for(std::vector<cv::Point2f> singleMarkerCorners : corners) { @@ -176,7 +183,7 @@ void CodeMarkerItem::addDetectedMarkers(std::vector<std::vector<cv::Point2f> > c * @param rejected corners of the rejected markers * @param offset offset from marker-coords to recognition ROI */ -void CodeMarkerItem::addRejectedMarkers(std::vector<std::vector<cv::Point2f> > rejected, Vec2F offset /* = (0,0)*/) +void CodeMarkerItem::addRejectedMarkers(std::vector<std::vector<cv::Point2f>> rejected, Vec2F offset /* = (0,0)*/) { for(std::vector<cv::Point2f> singleMarkerCorners : rejected) { diff --git a/src/codeMarkerWidget.cpp b/src/codeMarkerWidget.cpp index 0982a4385573cd1fb1a234754d013ed49de87064..c8681320973e9029343a22d0a021cb736a2b8c4b 100644 --- a/src/codeMarkerWidget.cpp +++ b/src/codeMarkerWidget.cpp @@ -18,51 +18,59 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <opencv2/core/version.hpp> +#include "codeMarkerWidget.h" +#include "pMessageBox.h" +#include "recognition.h" #include "ui_codeMarker.h" -#include "codeMarkerWidget.h" -#include "recognition.h" -#include "pMessageBox.h" +#include <opencv2/core/version.hpp> -CodeMarkerWidget::CodeMarkerWidget(QWidget *parent, reco::CodeMarkerOptions& codeMarkerOpt, Ui::CodeMarker* ui) - : QWidget(parent), mCodeMarkerOpt(codeMarkerOpt) +CodeMarkerWidget::CodeMarkerWidget(QWidget *parent, reco::CodeMarkerOptions &codeMarkerOpt, Ui::CodeMarker *ui) : + QWidget(parent), mCodeMarkerOpt(codeMarkerOpt) { - mMainWindow = (class Petrack*) parent; - if(!ui){ + mMainWindow = (class Petrack *) parent; + if(!ui) + { mUi = new Ui::CodeMarker(); - }else{ + } + else + { mUi = ui; } mUi->setupUi(this); - mUi->dictList->addItem("DICT_4X4_50"); // 0 - mUi->dictList->addItem("DICT_4X4_100"); // 1 - mUi->dictList->addItem("DICT_4X4_250"); // 2 - mUi->dictList->addItem("DICT_4X4_1000");// 3 + mUi->dictList->addItem("DICT_4X4_50"); // 0 + mUi->dictList->addItem("DICT_4X4_100"); // 1 + mUi->dictList->addItem("DICT_4X4_250"); // 2 + mUi->dictList->addItem("DICT_4X4_1000"); // 3 - mUi->dictList->addItem("DICT_5X5_50"); // 4 - mUi->dictList->addItem("DICT_5X5_100"); // 5 - mUi->dictList->addItem("DICT_5X5_250"); // 6 - mUi->dictList->addItem("DICT_5X5_1000");// 7 + mUi->dictList->addItem("DICT_5X5_50"); // 4 + mUi->dictList->addItem("DICT_5X5_100"); // 5 + mUi->dictList->addItem("DICT_5X5_250"); // 6 + mUi->dictList->addItem("DICT_5X5_1000"); // 7 - mUi->dictList->addItem("DICT_6X6_50"); // 8 - mUi->dictList->addItem("DICT_6X6_100"); // 9 - mUi->dictList->addItem("DICT_6X6_250"); // 10 - mUi->dictList->addItem("DICT_6X6_1000");// 11 + mUi->dictList->addItem("DICT_6X6_50"); // 8 + mUi->dictList->addItem("DICT_6X6_100"); // 9 + mUi->dictList->addItem("DICT_6X6_250"); // 10 + mUi->dictList->addItem("DICT_6X6_1000"); // 11 - mUi->dictList->addItem("DICT_7X7_50"); // 12 - mUi->dictList->addItem("DICT_7X7_100"); // 13 - mUi->dictList->addItem("DICT_7X7_250"); // 14 - mUi->dictList->addItem("DICT_7X7_1000");// 15 + mUi->dictList->addItem("DICT_7X7_50"); // 12 + mUi->dictList->addItem("DICT_7X7_100"); // 13 + mUi->dictList->addItem("DICT_7X7_250"); // 14 + mUi->dictList->addItem("DICT_7X7_1000"); // 15 mUi->dictList->addItem("DICT_ARUCO_ORGINAL"); // 16 - mUi->dictList->addItem("DICT_mip_36h12");//17 + mUi->dictList->addItem("DICT_mip_36h12"); // 17 - connect(&mCodeMarkerOpt, &reco::CodeMarkerOptions::detectorParamsChanged, this, &CodeMarkerWidget::readDetectorParams); - connect(&mCodeMarkerOpt, &reco::CodeMarkerOptions::indexOfMarkerDictChanged, this, &CodeMarkerWidget::readDictListIndex); + connect( + &mCodeMarkerOpt, &reco::CodeMarkerOptions::detectorParamsChanged, this, &CodeMarkerWidget::readDetectorParams); + connect( + &mCodeMarkerOpt, + &reco::CodeMarkerOptions::indexOfMarkerDictChanged, + this, + &CodeMarkerWidget::readDictListIndex); // get default values from Options readDetectorParams(); @@ -71,11 +79,15 @@ CodeMarkerWidget::CodeMarkerWidget(QWidget *parent, reco::CodeMarkerOptions& cod // NOTE: No parameter validation done here // Can result in crash, when invalid params are chosen (e.g. min larger than max) - auto changedParams = [&](){ - try{ - sendDetectorParams(packDetectorParams(mUi)); - notifyChanged(); - }catch(std::invalid_argument &e){ + auto changedParams = [&]() + { + try + { + sendDetectorParams(packDetectorParams(mUi)); + notifyChanged(); + } + catch(std::invalid_argument &e) + { PWarning(this, "Wrong Value", e.what()); readDetectorParams(); } @@ -101,7 +113,10 @@ CodeMarkerWidget::CodeMarkerWidget(QWidget *parent, reco::CodeMarkerOptions& cod connect(mUi->markerBorderBits, QOverload<int>::of(&QSpinBox::valueChanged), changedParams); connect(mUi->perspectiveRemovePixelPerCell, QOverload<int>::of(&QSpinBox::valueChanged), changedParams); - connect(mUi->perspectiveRemoveIgnoredMarginPerCell, QOverload<double>::of(&QDoubleSpinBox::valueChanged), changedParams); + connect( + mUi->perspectiveRemoveIgnoredMarginPerCell, + QOverload<double>::of(&QDoubleSpinBox::valueChanged), + changedParams); connect(mUi->maxErroneousBitsInBorderRate, QOverload<double>::of(&QDoubleSpinBox::valueChanged), changedParams); connect(mUi->errorCorrectionRate, QOverload<double>::of(&QDoubleSpinBox::valueChanged), changedParams); connect(mUi->minOtsuStdDev, QOverload<double>::of(&QDoubleSpinBox::valueChanged), changedParams); @@ -124,90 +139,95 @@ void CodeMarkerWidget::setXml(QDomElement &elem) elem.appendChild(subElem); subElem = (elem.ownerDocument()).createElement("PARAM"); - subElem.setAttribute("ADAPTIVE_THRESH_WIN_SIZE_MIN",mUi->adaptiveThreshWinSizeMin->value()); - subElem.setAttribute("ADAPTIVE_THRESH_WIN_SIZE_MAX",mUi->adaptiveThreshWinSizeMax->value()); - subElem.setAttribute("ADAPTIVE_THRESH_WIN_SIZE_STEP",mUi->adaptiveThreshWinSizeStep->value()); - subElem.setAttribute("ADAPTIVE_THRESH_CONSTANT",mUi->adaptiveThreshConstant->value()); - subElem.setAttribute("MIN_MARKER_PERIMETER",mUi->minMarkerPerimeter->value()); - subElem.setAttribute("MAX_MARKER_PERIMETER",mUi->maxMarkerPerimeter->value()); - subElem.setAttribute("MAX_RATIO_ERROR",mUi->polygonalApproxAccuracyRate->value()); - subElem.setAttribute("MIN_CORNER_DISTANCE",mUi->minCornerDistance->value()); - subElem.setAttribute("MIN_DISTANCE_TO_BORDER",mUi->minDistanceToBorder->value()); - subElem.setAttribute("MIN_MARKER_DISTANCE",mUi->minMarkerDistance->value()); - subElem.setAttribute("CORNER_REFINEMENT",mUi-> doCornerRefinement->isChecked()); - subElem.setAttribute("CORNER_REFINEMENT_WIN_SIZE",mUi->cornerRefinementWinSize->value()); - subElem.setAttribute("CORNER_REFINEMENT_MAX_ITERATIONS",mUi->cornerRefinementMaxIterations->value()); - subElem.setAttribute("CORNER_REFINEMENT_MIN_ACCURACY",mUi->cornerRefinementMinAccuracy->value()); - subElem.setAttribute("MARKER_BORDER_BITS",mUi->markerBorderBits->value()); - subElem.setAttribute("PERSPECTIVE_REMOVE_PIXEL_PER_CELL",mUi->perspectiveRemovePixelPerCell->value()); - subElem.setAttribute("PERSPECTIVE_REMOVE_IGNORED_MARGIN_PER_CELL",mUi->perspectiveRemoveIgnoredMarginPerCell->value()); - subElem.setAttribute("MAX_ERRONEOUS_BITS_IN_BORDER_RATE",mUi->maxErroneousBitsInBorderRate->value()); - subElem.setAttribute("MIN_OTSU_STD_DEV",mUi->minOtsuStdDev->value()); - subElem.setAttribute("ERROR_CORRECTION_RATE",mUi->errorCorrectionRate->value()); - subElem.setAttribute("SHOW_DETECTED_CANDIDATES",mUi-> showDetectedCandidates->isChecked()); + subElem.setAttribute("ADAPTIVE_THRESH_WIN_SIZE_MIN", mUi->adaptiveThreshWinSizeMin->value()); + subElem.setAttribute("ADAPTIVE_THRESH_WIN_SIZE_MAX", mUi->adaptiveThreshWinSizeMax->value()); + subElem.setAttribute("ADAPTIVE_THRESH_WIN_SIZE_STEP", mUi->adaptiveThreshWinSizeStep->value()); + subElem.setAttribute("ADAPTIVE_THRESH_CONSTANT", mUi->adaptiveThreshConstant->value()); + subElem.setAttribute("MIN_MARKER_PERIMETER", mUi->minMarkerPerimeter->value()); + subElem.setAttribute("MAX_MARKER_PERIMETER", mUi->maxMarkerPerimeter->value()); + subElem.setAttribute("MAX_RATIO_ERROR", mUi->polygonalApproxAccuracyRate->value()); + subElem.setAttribute("MIN_CORNER_DISTANCE", mUi->minCornerDistance->value()); + subElem.setAttribute("MIN_DISTANCE_TO_BORDER", mUi->minDistanceToBorder->value()); + subElem.setAttribute("MIN_MARKER_DISTANCE", mUi->minMarkerDistance->value()); + subElem.setAttribute("CORNER_REFINEMENT", mUi->doCornerRefinement->isChecked()); + subElem.setAttribute("CORNER_REFINEMENT_WIN_SIZE", mUi->cornerRefinementWinSize->value()); + subElem.setAttribute("CORNER_REFINEMENT_MAX_ITERATIONS", mUi->cornerRefinementMaxIterations->value()); + subElem.setAttribute("CORNER_REFINEMENT_MIN_ACCURACY", mUi->cornerRefinementMinAccuracy->value()); + subElem.setAttribute("MARKER_BORDER_BITS", mUi->markerBorderBits->value()); + subElem.setAttribute("PERSPECTIVE_REMOVE_PIXEL_PER_CELL", mUi->perspectiveRemovePixelPerCell->value()); + subElem.setAttribute( + "PERSPECTIVE_REMOVE_IGNORED_MARGIN_PER_CELL", mUi->perspectiveRemoveIgnoredMarginPerCell->value()); + subElem.setAttribute("MAX_ERRONEOUS_BITS_IN_BORDER_RATE", mUi->maxErroneousBitsInBorderRate->value()); + subElem.setAttribute("MIN_OTSU_STD_DEV", mUi->minOtsuStdDev->value()); + subElem.setAttribute("ERROR_CORRECTION_RATE", mUi->errorCorrectionRate->value()); + subElem.setAttribute("SHOW_DETECTED_CANDIDATES", mUi->showDetectedCandidates->isChecked()); elem.appendChild(subElem); - } /// read data from xml node void CodeMarkerWidget::getXml(QDomElement &elem) { QDomElement subElem; - QString styleString; + QString styleString; for(subElem = elem.firstChildElement(); !subElem.isNull(); subElem = subElem.nextSiblingElement()) { - - if (subElem.tagName() == "DICTIONARY") + if(subElem.tagName() == "DICTIONARY") { - if (subElem.hasAttribute("ID")) + if(subElem.hasAttribute("ID")) mUi->dictList->setCurrentIndex(subElem.attribute("ID").toInt()); } - if (subElem.tagName() == "PARAM") + if(subElem.tagName() == "PARAM") { - if (subElem.hasAttribute("ADAPTIVE_TRHESH_WIN_SIZE_MIN")) + if(subElem.hasAttribute("ADAPTIVE_TRHESH_WIN_SIZE_MIN")) mUi->adaptiveThreshWinSizeMin->setValue(subElem.attribute("ADAPTIVE_THRESH_WIN_SIZE_MIN").toInt()); - if (subElem.hasAttribute("ADAPTIVE_TRHESH_WIN_SIZE_MAX")) + if(subElem.hasAttribute("ADAPTIVE_TRHESH_WIN_SIZE_MAX")) mUi->adaptiveThreshWinSizeMax->setValue(subElem.attribute("ADAPTIVE_THRESH_WIN_SIZE_MAX").toInt()); - if (subElem.hasAttribute("ADAPTIVE_TRHESH_WIN_SIZE_STEP")) + if(subElem.hasAttribute("ADAPTIVE_TRHESH_WIN_SIZE_STEP")) mUi->adaptiveThreshWinSizeStep->setValue(subElem.attribute("ADAPTIVE_THRESH_WIN_SIZE_STEP").toInt()); - if (subElem.hasAttribute("ADAPTIVE_TRHESH_CONSTANT")) + if(subElem.hasAttribute("ADAPTIVE_TRHESH_CONSTANT")) mUi->adaptiveThreshConstant->setValue(subElem.attribute("ADAPTIVE_THRESH_CONSTANT").toInt()); - if (subElem.hasAttribute("MIN_MARKER_PERIMETER")) + if(subElem.hasAttribute("MIN_MARKER_PERIMETER")) mUi->minMarkerPerimeter->setValue(subElem.attribute("MIN_MARKER_PERIMETER").toDouble()); - if (subElem.hasAttribute("MAX_MARKER_PERIMETER")) + if(subElem.hasAttribute("MAX_MARKER_PERIMETER")) mUi->maxMarkerPerimeter->setValue(subElem.attribute("MAX_MARKER_PERIMETER").toDouble()); - if (subElem.hasAttribute("MAX_RATIO_ERROR")) + if(subElem.hasAttribute("MAX_RATIO_ERROR")) mUi->polygonalApproxAccuracyRate->setValue(subElem.attribute("MAX_RATIO_ERROR").toDouble()); - if (subElem.hasAttribute("MIN_CORNER_DISTANCE")) + if(subElem.hasAttribute("MIN_CORNER_DISTANCE")) mUi->minCornerDistance->setValue(subElem.attribute("MIN_CORNER_DISTANCE").toDouble()); - if (subElem.hasAttribute("MIN_DISTANCE_TO_BORDER")) + if(subElem.hasAttribute("MIN_DISTANCE_TO_BORDER")) mUi->minDistanceToBorder->setValue(subElem.attribute("MIN_DISTANCE_TO_BORDER").toInt()); - if (subElem.hasAttribute("MIN_MARKER_DISTANCE")) + if(subElem.hasAttribute("MIN_MARKER_DISTANCE")) mUi->minMarkerDistance->setValue(subElem.attribute("MIN_MARKER_DISTANCE").toDouble()); - if (subElem.hasAttribute("CORNER_REFINEMENT")) + if(subElem.hasAttribute("CORNER_REFINEMENT")) mUi->doCornerRefinement->setChecked(subElem.attribute("CORNER_REFINEMENT").toInt()); - if (subElem.hasAttribute("CORNER_REFINEMENT_WIN_SIZE")) + if(subElem.hasAttribute("CORNER_REFINEMENT_WIN_SIZE")) mUi->cornerRefinementWinSize->setValue(subElem.attribute("CORNER_REFINEMENT_WIN_SIZE").toInt()); - if (subElem.hasAttribute("CORNER_REFINEMENT_MAX_ITERATIONS")) - mUi->cornerRefinementMaxIterations->setValue(subElem.attribute("CORNER_REFINEMENT_MAX_ITERATIONS").toInt()); - if (subElem.hasAttribute("CORNER_REFINEMENT_MIN_ACCURACY")) - mUi->cornerRefinementMinAccuracy->setValue(subElem.attribute("CORNER_REFINEMENT_MIN_ACCURACY").toDouble()); - if (subElem.hasAttribute("MARKER_BORDER_BITS")) + if(subElem.hasAttribute("CORNER_REFINEMENT_MAX_ITERATIONS")) + mUi->cornerRefinementMaxIterations->setValue( + subElem.attribute("CORNER_REFINEMENT_MAX_ITERATIONS").toInt()); + if(subElem.hasAttribute("CORNER_REFINEMENT_MIN_ACCURACY")) + mUi->cornerRefinementMinAccuracy->setValue( + subElem.attribute("CORNER_REFINEMENT_MIN_ACCURACY").toDouble()); + if(subElem.hasAttribute("MARKER_BORDER_BITS")) mUi->markerBorderBits->setValue(subElem.attribute("MARKER_BORDER_BITS").toInt()); - if (subElem.hasAttribute("PERSPECTIVE_REMOVE_PIXEL_PER_CELL")) - mUi->perspectiveRemovePixelPerCell->setValue(subElem.attribute("PERSPECTIVE_REMOVE_PIXEL_PER_CELL").toInt()); - if (subElem.hasAttribute("PERSPECTIVE_REMOVE_IGNORED_MARGIN_PER_CELL")) - mUi->perspectiveRemoveIgnoredMarginPerCell->setValue(subElem.attribute("PERSPECTIVE_REMOVE_IGNORED_MARGIN_PER_CELL").toDouble()); - if (subElem.hasAttribute("MAX_ERRONEOUS_BITS_IN_BORDER_RATE")) - mUi->maxErroneousBitsInBorderRate->setValue(subElem.attribute("MAX_ERRONEOUS_BITS_IN_BORDER_RATE").toDouble()); - if (subElem.hasAttribute("MIN_OTSU_STD_DEV")) + if(subElem.hasAttribute("PERSPECTIVE_REMOVE_PIXEL_PER_CELL")) + mUi->perspectiveRemovePixelPerCell->setValue( + subElem.attribute("PERSPECTIVE_REMOVE_PIXEL_PER_CELL").toInt()); + if(subElem.hasAttribute("PERSPECTIVE_REMOVE_IGNORED_MARGIN_PER_CELL")) + mUi->perspectiveRemoveIgnoredMarginPerCell->setValue( + subElem.attribute("PERSPECTIVE_REMOVE_IGNORED_MARGIN_PER_CELL").toDouble()); + if(subElem.hasAttribute("MAX_ERRONEOUS_BITS_IN_BORDER_RATE")) + mUi->maxErroneousBitsInBorderRate->setValue( + subElem.attribute("MAX_ERRONEOUS_BITS_IN_BORDER_RATE").toDouble()); + if(subElem.hasAttribute("MIN_OTSU_STD_DEV")) mUi->minOtsuStdDev->setValue(subElem.attribute("MIN_OTSU_STD_DEV").toDouble()); - if (subElem.hasAttribute("ERROR_CORRECTION_RATE")) + if(subElem.hasAttribute("ERROR_CORRECTION_RATE")) mUi->errorCorrectionRate->setValue(subElem.attribute("ERROR_CORRECTION_RATE").toDouble()); - if (subElem.hasAttribute("SHOW_DETECTED_CANDIDATES")) - mUi->showDetectedCandidates->setCheckState(subElem.attribute("SHOW_DETECTED_CANDIDATES").toInt() ? Qt::Checked : Qt::Unchecked); + if(subElem.hasAttribute("SHOW_DETECTED_CANDIDATES")) + mUi->showDetectedCandidates->setCheckState( + subElem.attribute("SHOW_DETECTED_CANDIDATES").toInt() ? Qt::Checked : Qt::Unchecked); } } } @@ -246,15 +266,19 @@ bool CodeMarkerWidget::showDetectedCandidates() void CodeMarkerWidget::on_showDetectedCandidates_stateChanged(int i) { mMainWindow->getCodeMarkerItem()->setVisible(i); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->getScene()->update(); } void CodeMarkerWidget::on_moreInfosButton_clicked() { -#define CV_NUMERIC_VERSION CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION) - QDesktopServices::openUrl(QUrl("http://docs.opencv.org/" CV_NUMERIC_VERSION "/d1/dcd/structcv_1_1aruco_1_1DetectorParameters.html#details", QUrl::TolerantMode)); - QDesktopServices::openUrl(QUrl("http://docs.opencv.org/" CV_NUMERIC_VERSION "/d5/dae/tutorial_aruco_detection.html", QUrl::TolerantMode)); +#define CV_NUMERIC_VERSION \ + CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION) + QDesktopServices::openUrl(QUrl( + "http://docs.opencv.org/" CV_NUMERIC_VERSION "/d1/dcd/structcv_1_1aruco_1_1DetectorParameters.html#details", + QUrl::TolerantMode)); + QDesktopServices::openUrl( + QUrl("http://docs.opencv.org/" CV_NUMERIC_VERSION "/d5/dae/tutorial_aruco_detection.html", QUrl::TolerantMode)); } void CodeMarkerWidget::on_dictList_currentIndexChanged(int i) @@ -266,8 +290,8 @@ void CodeMarkerWidget::on_dictList_currentIndexChanged(int i) void CodeMarkerWidget::notifyChanged() { - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } diff --git a/src/colorMarkerItem.cpp b/src/colorMarkerItem.cpp index b9701c50b552c2628caf9587ff0ff61e5eace5a1..280f3cf023cacf5f04142c29ee73c8029efb0915 100644 --- a/src/colorMarkerItem.cpp +++ b/src/colorMarkerItem.cpp @@ -18,24 +18,24 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> - -#include "petrack.h" -#include "view.h" #include "colorMarkerItem.h" + +#include "animation.h" #include "colorMarkerWidget.h" +#include "petrack.h" #include "tracker.h" -#include "animation.h" +#include "view.h" + +#include <QtWidgets> // in x und y gleichermassen skaliertes koordinatensystem, // da von einer vorherigen intrinsischen kamerakalibrierung ausgegenagen wird, -// so dass pixel quadratisch -ColorMarkerItem::ColorMarkerItem(QWidget *wParent, QGraphicsItem * parent) - : QGraphicsItem(parent) +// so dass pixel quadratisch +ColorMarkerItem::ColorMarkerItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) { - mMainWindow = (class Petrack*) wParent; - mImage = nullptr; + mMainWindow = (class Petrack *) wParent; + mImage = nullptr; } /** @@ -48,13 +48,17 @@ ColorMarkerItem::ColorMarkerItem(QWidget *wParent, QGraphicsItem * parent) */ QRectF ColorMarkerItem::boundingRect() const { - if (mMainWindow->getImage()) - return QRectF(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), mMainWindow->getImage()->width(), mMainWindow->getImage()->height()); + if(mMainWindow->getImage()) + return QRectF( + -mMainWindow->getImageBorderSize(), + -mMainWindow->getImageBorderSize(), + mMainWindow->getImage()->width(), + mMainWindow->getImage()->height()); else return QRectF(0, 0, 0, 0); } -void ColorMarkerItem::setRect(Vec2F& v) +void ColorMarkerItem::setRect(Vec2F &v) { mUlc = v; // upper left corner to draw } @@ -68,41 +72,40 @@ void ColorMarkerItem::setRect(Vec2F& v) * * @param painter */ -void ColorMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) +void ColorMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - if (!mMask.empty()) + if(!mMask.empty()) { - if ((mImage != nullptr) && ((mImage->width() != mMask.cols) || (mImage->height() != mMask.rows))) + if((mImage != nullptr) && ((mImage->width() != mMask.cols) || (mImage->height() != mMask.rows))) { - delete mImage; // delete null pointer is ok + delete mImage; // delete null pointer is ok mImage = nullptr; // is not been done by delete } - if (mImage == nullptr) // zu Beginn oder wenn sich die Groesse aendert + if(mImage == nullptr) // zu Beginn oder wenn sich die Groesse aendert mImage = new QImage(mMask.cols, mMask.rows, QImage::Format_ARGB32); - int x,y; - auto* data = mMask.data;//->imageData); - auto* yData = data; - int notMaskMask = ((int) !mMainWindow->getColorMarkerWidget()->maskMask->isChecked())*255; // 255 oder 0 + int x, y; + auto *data = mMask.data; //->imageData); + auto *yData = data; + int notMaskMask = ((int) !mMainWindow->getColorMarkerWidget()->maskMask->isChecked()) * 255; // 255 oder 0 - for (y = 0; y < mMask.rows; y++) + for(y = 0; y < mMask.rows; y++) { // Pointer to the data information in the QImage for just one column // set pointer to value before, because ++p is faster than p++ - auto * p = mImage->scanLine(y)-1; - for (x = 0; x < mMask.cols; x++) + auto *p = mImage->scanLine(y) - 1; + for(x = 0; x < mMask.cols; x++) { - *(++p) = *data; // color.blue(); - *(++p) = *data; // color.green(); - *(++p) = *data; // color.red(); + *(++p) = *data; // color.blue(); + *(++p) = *data; // color.green(); + *(++p) = *data; // color.red(); *(++p) = *data ? notMaskMask : 255; // color.alpha(); // 255; ++data; } - data = (yData += mMask.cols/sizeof(char)); // because sometimes widthStep != width + data = (yData += mMask.cols / sizeof(char)); // because sometimes widthStep != width } - painter->setOpacity(mMainWindow->getColorMarkerWidget()->opacity->value()/100.); - painter->drawImage(mUlc.x(),mUlc.y(), *mImage); - + painter->setOpacity(mMainWindow->getColorMarkerWidget()->opacity->value() / 100.); + painter->drawImage(mUlc.x(), mUlc.y(), *mImage); } } @@ -115,9 +118,9 @@ void ColorMarkerItem::setMask(cv::Mat &mask) /// original width w and height h must be given cv::Mat ColorMarkerItem::createMask(int w, int h) { - if (w>0 && h>0 && (mMask.empty() || (!mMask.empty() && (w != mMask.cols || h != mMask.rows)))) + if(w > 0 && h > 0 && (mMask.empty() || (!mMask.empty() && (w != mMask.cols || h != mMask.rows)))) { - mMask.create(h,w,CV_8UC1); + mMask.create(h, w, CV_8UC1); } return mMask; } diff --git a/src/colorMarkerWidget.cpp b/src/colorMarkerWidget.cpp index f3c380afc9d3d41a903106b91716a8bcfe54317c..bbd6c3b9e0cfb3b10a04d86927846d449b17dfd9 100644 --- a/src/colorMarkerWidget.cpp +++ b/src/colorMarkerWidget.cpp @@ -20,17 +20,16 @@ #include "colorMarkerWidget.h" -ColorMarkerWidget::ColorMarkerWidget(QWidget *parent) - : QWidget(parent) +ColorMarkerWidget::ColorMarkerWidget(QWidget *parent) : QWidget(parent) { - mMainWindow = (class Petrack*) parent; + mMainWindow = (class Petrack *) parent; fromHue = 0; fromSat = 0; fromVal = 128; - toHue = 359; - toSat = 255; - toVal = 255; + toHue = 359; + toSat = 255; + toVal = 255; setupUi(this); @@ -93,33 +92,33 @@ void ColorMarkerWidget::setXml(QDomElement &elem) void ColorMarkerWidget::getXml(QDomElement &elem) { QDomElement subElem; - int h=0, s=0, v=0; // init, damit compiler nicht meckert - QString styleString; - QColor col; + int h = 0, s = 0, v = 0; // init, damit compiler nicht meckert + QString styleString; + QColor col; col = col.toHsv(); for(subElem = elem.firstChildElement(); !subElem.isNull(); subElem = subElem.nextSiblingElement()) { - if (subElem.tagName() == "MASK") + if(subElem.tagName() == "MASK") { - if (subElem.hasAttribute("SHOW")) + if(subElem.hasAttribute("SHOW")) showMask->setCheckState(subElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("OPACITY")) + if(subElem.hasAttribute("OPACITY")) opacity->setValue(subElem.attribute("OPACITY").toInt()); - if (subElem.hasAttribute("MASK")) + if(subElem.hasAttribute("MASK")) maskMask->setCheckState(subElem.attribute("MASK").toInt() ? Qt::Checked : Qt::Unchecked); } - if (subElem.tagName() == "FROM_COLOR") + if(subElem.tagName() == "FROM_COLOR") { - if (subElem.hasAttribute("HUE")) + if(subElem.hasAttribute("HUE")) h = subElem.attribute("HUE").toInt(); - if (subElem.hasAttribute("SATURATION")) + if(subElem.hasAttribute("SATURATION")) s = subElem.attribute("SATURATION").toInt(); - if (subElem.hasAttribute("VALUE")) + if(subElem.hasAttribute("VALUE")) v = subElem.attribute("VALUE").toInt(); col.setHsv(h, s, v); - if (col.isValid()) + if(col.isValid()) { fromHue = h; fromSat = s; @@ -129,17 +128,17 @@ void ColorMarkerWidget::getXml(QDomElement &elem) fromColor->setStyleSheet(styleString); } } - if (subElem.tagName() == "TO_COLOR") + if(subElem.tagName() == "TO_COLOR") { - if (subElem.hasAttribute("HUE")) + if(subElem.hasAttribute("HUE")) h = subElem.attribute("HUE").toInt(); - if (subElem.hasAttribute("SATURATION")) + if(subElem.hasAttribute("SATURATION")) s = subElem.attribute("SATURATION").toInt(); - if (subElem.hasAttribute("VALUE")) + if(subElem.hasAttribute("VALUE")) v = subElem.attribute("VALUE").toInt(); col.setHsv(h, s, v); - if (col.isValid()) + if(col.isValid()) { toHue = h; toSat = s; @@ -149,23 +148,23 @@ void ColorMarkerWidget::getXml(QDomElement &elem) toColor->setStyleSheet(styleString); } } - if (subElem.tagName() == "PARAM") + if(subElem.tagName() == "PARAM") { - if (subElem.hasAttribute("INVERS_HUE")) + if(subElem.hasAttribute("INVERS_HUE")) inversHue->setCheckState(subElem.attribute("INVERS_HUE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("CLOSE_RADIUS")) + if(subElem.hasAttribute("CLOSE_RADIUS")) closeRadius->setValue(subElem.attribute("CLOSE_RADIUS").toInt()); - if (subElem.hasAttribute("CLOSE_USED")) + if(subElem.hasAttribute("CLOSE_USED")) useClose->setCheckState(subElem.attribute("CLOSE_USED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("OPEN_RADIUS")) + if(subElem.hasAttribute("OPEN_RADIUS")) openRadius->setValue(subElem.attribute("OPEN_RADIUS").toInt()); - if (subElem.hasAttribute("OPEN_USED")) + if(subElem.hasAttribute("OPEN_USED")) useOpen->setCheckState(subElem.attribute("OPEN_USED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("MIN_AREA")) + if(subElem.hasAttribute("MIN_AREA")) minArea->setValue(subElem.attribute("MIN_AREA").toInt()); - if (subElem.hasAttribute("MAX_AREA")) + if(subElem.hasAttribute("MAX_AREA")) maxArea->setValue(subElem.attribute("MAX_AREA").toInt()); - if (subElem.hasAttribute("MAX_RATIO")) + if(subElem.hasAttribute("MAX_RATIO")) maxRatio->setValue(subElem.attribute("MAX_RATIO").toDouble()); } } @@ -173,20 +172,24 @@ void ColorMarkerWidget::getXml(QDomElement &elem) void ColorMarkerWidget::on_fromTriangle_colorChanged(const QColor &col) { - fromHue = col.hue(); fromSat = col.saturation(); fromVal = col.value(); + fromHue = col.hue(); + fromSat = col.saturation(); + fromVal = col.value(); QString styleString = QString("background-color: hsv(%1,%2,%3)").arg(fromHue).arg(fromSat).arg(fromVal); fromColor->setStyleSheet(styleString); - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void ColorMarkerWidget::on_toTriangle_colorChanged(const QColor &col) { - toHue = col.hue(); toSat = col.saturation(); toVal = col.value(); + toHue = col.hue(); + toSat = col.saturation(); + toVal = col.value(); QString styleString = QString("background-color: hsv(%1,%2,%3)").arg(toHue).arg(toSat).arg(toVal); toColor->setStyleSheet(styleString); - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } @@ -195,9 +198,10 @@ void ColorMarkerWidget::on_fromColor_clicked() // QWindowsXpStyle uses native theming engine which causes some palette modifications not to have any effect. // ueber palette war der button ausser initial nicht zu aendern!!! QColor colBefore; - colBefore = QColor::fromHsv(fromHue, fromSat, fromVal); - QColor col = (QColorDialog::getColor(colBefore, this, "Select color from which value a pixel belongs to marker")).convertTo(QColor::Hsv); - if (col.isValid() && col != colBefore) + colBefore = QColor::fromHsv(fromHue, fromSat, fromVal); + QColor col = (QColorDialog::getColor(colBefore, this, "Select color from which value a pixel belongs to marker")) + .convertTo(QColor::Hsv); + if(col.isValid() && col != colBefore) { on_fromTriangle_colorChanged(col); fromTriangle->setColor(col); @@ -209,9 +213,10 @@ void ColorMarkerWidget::on_toColor_clicked() // QWindowsXpStyle uses native theming engine which causes some palette modifications not to have any effect. // ueber palette war der button ausser initial nicht zu aendern!!! QColor colBefore; - colBefore = QColor::fromHsv(toHue, toSat, toVal); - QColor col = (QColorDialog::getColor(colBefore, this, "Select color to which value a pixel belongs to marker")).convertTo(QColor::Hsv); - if (col.isValid() && col != colBefore) + colBefore = QColor::fromHsv(toHue, toSat, toVal); + QColor col = (QColorDialog::getColor(colBefore, this, "Select color to which value a pixel belongs to marker")) + .convertTo(QColor::Hsv); + if(col.isValid() && col != colBefore) { on_toTriangle_colorChanged(col); toTriangle->setColor(col); diff --git a/src/colorPlot.cpp b/src/colorPlot.cpp index 165d019a6c585ef9a6cceb9bcf51f7bd48e1008e..9b728135a3750bdddbdcff56b2609c0516053dc9 100644 --- a/src/colorPlot.cpp +++ b/src/colorPlot.cpp @@ -18,29 +18,25 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <iomanip> +#include "colorPlot.h" -#include <QPainter> -#include <QMouseEvent> +#include "control.h" +#include "tracker.h" +#include <QMouseEvent> +#include <QPainter> +#include <iomanip> +#include <qwt_compat.h> #include <qwt_plot_layout.h> #include <qwt_plot_zoomer.h> -#include <qwt_symbol.h> #include <qwt_scale_engine.h> -#include <qwt_compat.h> - -#include "colorPlot.h" -#include "control.h" -#include "tracker.h" +#include <qwt_symbol.h> -class ImagePlotItem: public QwtPlotItem +class ImagePlotItem : public QwtPlotItem { public: - ImagePlotItem() - { - mImage = new QImage(360,360,QImage::Format_RGB32); - } + ImagePlotItem() { mImage = new QImage(360, 360, QImage::Format_RGB32); } /** * @brief Draws the mImage at the right position in correct size. @@ -48,11 +44,11 @@ public: * @param mx * @param my */ - void draw(QPainter* p, const QwtScaleMap& mx, const QwtScaleMap& my, const QRectF& /*r*/) const + void draw(QPainter *p, const QwtScaleMap &mx, const QwtScaleMap &my, const QRectF & /*r*/) const { p->save(); - p->scale(mx.p2()/(mx.s2() - mx.s1()), my.p1()/(my.s2() - my.s1()));// - p->translate(-mx.s1(), my.s2()-((ColorPlot *) plot())->yMax()); + p->scale(mx.p2() / (mx.s2() - mx.s1()), my.p1() / (my.s2() - my.s1())); // + p->translate(-mx.s1(), my.s2() - ((ColorPlot *) plot())->yMax()); p->drawImage(0, 0, *mImage); p->restore(); } @@ -71,37 +67,36 @@ public: void generateImage(int model, int x, int y, int z) { QColor col; - int i, j; + int i, j; - if (model == 0) // HSV + if(model == 0) // HSV { - for (i = 0; i < (x==0?360:256); ++i) - for (j = 0; j < (y==0?360:256); ++j) + for(i = 0; i < (x == 0 ? 360 : 256); ++i) + for(j = 0; j < (y == 0 ? 360 : 256); ++j) { - col.setHsv(x==0?(y==0?std::min(i, j):i):(y==0?j:myRound(z*360./256.)), - x==1?(y==1?std::min(i, j):i):(y==1?j:z), - x==2?(y==2?std::min(i, j):i):(y==2?j:z)); - mImage->setPixel(i, (y==0?359:255)-j, col.rgb()); + col.setHsv( + x == 0 ? (y == 0 ? std::min(i, j) : i) : (y == 0 ? j : myRound(z * 360. / 256.)), + x == 1 ? (y == 1 ? std::min(i, j) : i) : (y == 1 ? j : z), + x == 2 ? (y == 2 ? std::min(i, j) : i) : (y == 2 ? j : z)); + mImage->setPixel(i, (y == 0 ? 359 : 255) - j, col.rgb()); } } else // RGB { - for (i = 0; i < 256; ++i) - for (j = 0; j < 256; ++j) + for(i = 0; i < 256; ++i) + for(j = 0; j < 256; ++j) { - col.setRgb(x==0?(y==0?std::min(i, j):i):(y==0?j:z), - x==1?(y==1?std::min(i, j):i):(y==1?j:z), - x==2?(y==2?std::min(i, j):i):(y==2?j:z)); - mImage->setPixel(i, 255-j, col.rgb()); + col.setRgb( + x == 0 ? (y == 0 ? std::min(i, j) : i) : (y == 0 ? j : z), + x == 1 ? (y == 1 ? std::min(i, j) : i) : (y == 1 ? j : z), + x == 2 ? (y == 2 ? std::min(i, j) : i) : (y == 2 ? j : z)); + mImage->setPixel(i, 255 - j, col.rgb()); } } } - inline QImage *getImage() const - { - return mImage; - } - + inline QImage *getImage() const { return mImage; } + private: QImage *mImage; }; @@ -122,43 +117,45 @@ TrackerPlotItem::TrackerPlotItem() * @param mapX * @param mapY */ -void TrackerPlotItem::draw(QPainter* p, const QwtScaleMap& mapX, const QwtScaleMap& mapY, const QRectF& /*re*/) const +void TrackerPlotItem::draw(QPainter *p, const QwtScaleMap &mapX, const QwtScaleMap &mapY, const QRectF & /*re*/) const { QRectF rect; - double sx = mapX.p2()/(mapX.s2() - mapX.s1()); - double sy = mapY.p1()/(mapY.s2() - mapY.s1()); - double yMax = ((ColorPlot *) plot())->yMax(); + double sx = mapX.p2() / (mapX.s2() - mapX.s1()); + double sy = mapY.p1() / (mapY.s2() - mapY.s1()); + double yMax = ((ColorPlot *) plot())->yMax(); double circleSize = ((ColorPlot *) plot())->symbolSize(); - int i, z; - int plotZ = ((ColorPlot *) plot())->zValue(); + int i, z; + int plotZ = ((ColorPlot *) plot())->zValue(); double diff; // TODO ganz leicht verschiebung: eigentlich muessten noch andere werte wie diese einfliessen: // p->scale((mx.p2() - mx.p1())/(mx.s2() - mx.s1()), (my.p1() - my.p2())/(my.s2() - my.s1()));// - //mx.p1()-mx.s1(), my.s2()+my.p2()-((ColorPlot *) plot())->yMax() + // mx.p1()-mx.s1(), my.s2()+my.p2()-((ColorPlot *) plot())->yMax() p->save(); p->scale(sx, sy); - p->translate(-mapX.s1(), mapY.s2()-yMax); + p->translate(-mapX.s1(), mapY.s2() - yMax); - sx = circleSize/sx; - sy = circleSize/sy; + sx = circleSize / sx; + sy = circleSize / sy; - if (mTracker) + if(mTracker) { - for (i = 0; i < mTracker->size(); ++i) + for(i = 0; i < mTracker->size(); ++i) { - if ((*mTracker)[i].color().isValid()) // insbesondere von hand eingefuegte trackpoint/persons haben keine farbe + if((*mTracker)[i] + .color() + .isValid()) // insbesondere von hand eingefuegte trackpoint/persons haben keine farbe { QPoint point = ((ColorPlot *) plot())->getPos((*mTracker)[i].color(), &z); - diff = (255.-abs(z-plotZ))/255.; - rect.setWidth(diff*sx); - rect.setHeight(diff*sy); - rect.moveLeft(point.x()-diff*sx/2.); - rect.moveTop(point.y()-diff*sy/2.); - + diff = (255. - abs(z - plotZ)) / 255.; + rect.setWidth(diff * sx); + rect.setHeight(diff * sy); + rect.moveLeft(point.x() - diff * sx / 2.); + rect.moveTop(point.y() - diff * sy / 2.); + p->setBrush(QBrush((*mTracker)[i].color())); - if (((ColorPlot *) plot())->isGrey((*mTracker)[i].color())) + if(((ColorPlot *) plot())->isGrey((*mTracker)[i].color())) p->setPen(Qt::red); else p->setPen(mPen); @@ -179,7 +176,7 @@ void TrackerPlotItem::setTracker(Tracker *tracker) { mTracker = tracker; } -Tracker * TrackerPlotItem::getTracker() +Tracker *TrackerPlotItem::getTracker() { return mTracker; } @@ -187,76 +184,85 @@ Tracker * TrackerPlotItem::getTracker() //----------------------------------------------------------------------------------------- -RectPlotItem::RectPlotItem() - : mActIndex(-1) -{ -} +RectPlotItem::RectPlotItem() : mActIndex(-1) {} /// auch wenn punkt auf linie liegt, wird er als drinnen gezaehlt!!!! /// es wird einfach der erste treffer in map-list genommen - unterscheidung zwischen farbe und graustufe /// wird keine farbige map fuer farbige col gefunden, wird in grauen map der erste treffer genommen und /// andersherum: wird fuer graue col keine graue map gefunden, wird erste farbige map zurueckgegeben /// und hoehe zurueckgegeben -double RectPlotItem::map(const QColor &col) const //const TrackPerson &tp RectMap ... double x, double y +double RectPlotItem::map(const QColor &col) const // const TrackPerson &tp RectMap ... double x, double y { - double yMax = ((ColorPlot *) plot())->yMax(); + double yMax = ((ColorPlot *) plot())->yMax(); RectMap map; - bool isGrey; - bool contains; - double fallback = -1; // -1 soll anzeigen, dass nichts gefunden wurde + bool isGrey; + bool contains; + double fallback = -1; // -1 soll anzeigen, dass nichts gefunden wurde - for (int i = 0; i < mMaps.size(); ++i) + for(int i = 0; i < mMaps.size(); ++i) { map = mMaps[i]; - map.moveTop(yMax-map.y()-map.height()); // nicht setY!!!!!, da dann height angepast wird + map.moveTop(yMax - map.y() - map.height()); // nicht setY!!!!!, da dann height angepast wird isGrey = ((ColorPlot *) plot())->isGrey(col); - if (map.invHue()) + if(map.invHue()) { // Split inversHue Map into 2 maps, one for the left side and one for the right side - QRectF leftMap(0,0,map.x(),map.height()), - rightMap(map.x()+map.width(),0,360-map.x()-map.width(),map.height()); + QRectF leftMap(0, 0, map.x(), map.height()), + rightMap(map.x() + map.width(), 0, 360 - map.x() - map.width(), map.height()); contains = leftMap.contains(((ColorPlot *) plot())->getPos(col)) || rightMap.contains(((ColorPlot *) plot())->getPos(col)); - }else + } + else { contains = map.contains(((ColorPlot *) plot())->getPos(col)); } - if (!isGrey && map.colored() && contains) + if(!isGrey && map.colored() && contains) return map.mapHeight(); - else if (isGrey && !map.colored() && contains) + else if(isGrey && !map.colored() && contains) return map.mapHeight(); - else if (!isGrey && !map.colored() && contains && fallback == -1) // fallback == -1 damit der erste gefundene genommen wird + else if(!isGrey && !map.colored() && contains && fallback == -1) // fallback == -1 damit der erste gefundene + // genommen wird fallback = map.mapHeight(); - else if (isGrey && map.colored() && contains && fallback == -1) + else if(isGrey && map.colored() && contains && fallback == -1) fallback = map.mapHeight(); } return fallback; // -1 soll anzeigen, dass nichts gefunden wurde } -int RectPlotItem::addMap(double x, double y, double w, double h, bool colored, double height, QColor &fromCol, QColor &toCol, bool invHue) +int RectPlotItem::addMap( + double x, + double y, + double w, + double h, + bool colored, + double height, + QColor &fromCol, + QColor &toCol, + bool invHue) { mMaps.append(RectMap(x, y, w, h, colored, height)); mMaps.last().setFromColor(fromCol); mMaps.last().setToColor(toCol); mMaps.last().setInvHue(invHue); - if (mActIndex < 0) + if(mActIndex < 0) mActIndex = 0; - return mMaps.size()-1; + return mMaps.size() - 1; } int RectPlotItem::addMap() { - if (mMaps.size()>0) + if(mMaps.size() > 0) mMaps.append(mMaps.last()); else mMaps.append(RectMap(0, 0, 0, 0, true, DEFAULT_HEIGHT)); - if (mActIndex < 0) + if(mActIndex < 0) mActIndex = 0; - return mMaps.size()-1; + return mMaps.size() - 1; } void RectPlotItem::delMap(int index) { - if(mMaps.size() == 1){ + if(mMaps.size() == 1) + { if(index != 0) { debout << "Invalid index for map deletion!" << std::endl; @@ -266,7 +272,7 @@ void RectPlotItem::delMap(int index) return; } - if (index >= 0 && index < mMaps.size() && mMaps.size() > 0) + if(index >= 0 && index < mMaps.size() && mMaps.size() > 0) { mMaps.removeAt(index); return; @@ -278,7 +284,7 @@ void RectPlotItem::delMap(int index) void RectPlotItem::changeMap(int index, double x, double y, double w, double h, bool colored, double mapHeight) { - if (index >= 0 && index < mMaps.size()) + if(index >= 0 && index < mMaps.size()) { mMaps[index].setRect(x, y, w, h); // wenn mMaps[index].setColored(colored); @@ -289,7 +295,7 @@ void RectPlotItem::changeMap(int index, double x, double y, double w, double h, void RectPlotItem::changeActMapInvHue(bool b) { - if (mActIndex >= 0 && mActIndex < mMaps.size()) + if(mActIndex >= 0 && mActIndex < mMaps.size()) { mMaps[mActIndex].setInvHue(b); } @@ -297,7 +303,7 @@ void RectPlotItem::changeActMapInvHue(bool b) void RectPlotItem::changeActMapFromColor(const QColor &fromCol) { - if (mActIndex >= 0 && mActIndex < mMaps.size()) + if(mActIndex >= 0 && mActIndex < mMaps.size()) { mMaps[mActIndex].setFromColor(fromCol); } @@ -305,7 +311,7 @@ void RectPlotItem::changeActMapFromColor(const QColor &fromCol) void RectPlotItem::changeActMapToColor(const QColor &toCol) { - if (mActIndex >= 0 && mActIndex < mMaps.size()) + if(mActIndex >= 0 && mActIndex < mMaps.size()) { mMaps[mActIndex].setToColor(toCol); } @@ -313,7 +319,7 @@ void RectPlotItem::changeActMapToColor(const QColor &toCol) bool RectPlotItem::getActMapInvHue() { - if (mActIndex >= 0 && mActIndex < mMaps.size()) + if(mActIndex >= 0 && mActIndex < mMaps.size()) { return mMaps[mActIndex].invHue(); } @@ -322,7 +328,7 @@ bool RectPlotItem::getActMapInvHue() QColor RectPlotItem::getActMapToColor() { - if (mActIndex >= 0 && mActIndex < mMaps.size()) + if(mActIndex >= 0 && mActIndex < mMaps.size()) { return mMaps[mActIndex].toColor(); } @@ -331,7 +337,7 @@ QColor RectPlotItem::getActMapToColor() QColor RectPlotItem::getActMapFromColor() { - if (mActIndex >= 0 && mActIndex < mMaps.size()) + if(mActIndex >= 0 && mActIndex < mMaps.size()) { return mMaps[mActIndex].fromColor(); } @@ -340,7 +346,7 @@ QColor RectPlotItem::getActMapFromColor() RectMap RectPlotItem::getMap(int index) const { - if (index >= 0 && index < mMaps.size()) + if(index >= 0 && index < mMaps.size()) return mMaps[index]; else return RectMap(); @@ -355,50 +361,50 @@ RectMap RectPlotItem::getMap(int index) const * @param mapX * @param mapY */ -void RectPlotItem::draw(QPainter* p, const QwtScaleMap& mapX, const QwtScaleMap& mapY, const QRectF& /*re*/) const +void RectPlotItem::draw(QPainter *p, const QwtScaleMap &mapX, const QwtScaleMap &mapY, const QRectF & /*re*/) const { QRectF rect; - double sx = mapX.p2()/(mapX.s2() - mapX.s1()); - double sy = mapY.p1()/(mapY.s2() - mapY.s1()); + double sx = mapX.p2() / (mapX.s2() - mapX.s1()); + double sy = mapY.p1() / (mapY.s2() - mapY.s1()); double xMax = ((ColorPlot *) plot())->xMax(); double yMax = ((ColorPlot *) plot())->yMax(); - int i; - float rX,rW; + int i; + float rX, rW; // TODO ganz leicht verschiebung: eigentlich muessten noch andere werte wie diese einfliessen: // p->scale((mx.p2() - mx.p1())/(mx.s2() - mx.s1()), (my.p1() - my.p2())/(my.s2() - my.s1()));// - //mx.p1()-mx.s1(), my.s2()+my.p2()-((ColorPlot *) plot())->yMax() + // mx.p1()-mx.s1(), my.s2()+my.p2()-((ColorPlot *) plot())->yMax() p->save(); p->scale(sx, sy); - p->translate(-mapX.s1(), mapY.s2()-yMax); + p->translate(-mapX.s1(), mapY.s2() - yMax); - for (i = 0; i < mMaps.size(); ++i) + for(i = 0; i < mMaps.size(); ++i) { - if (i == mActIndex) + if(i == mActIndex) p->setPen(Qt::green); - else if (!mMaps[i].colored()) + else if(!mMaps[i].colored()) p->setPen(Qt::red); else p->setPen(mPen); - if (mMaps[i].invHue()) + if(mMaps[i].invHue()) { rect = mMaps[i]; - rect.moveTop(yMax-rect.y()-rect.height()); // nicht setY!!!!!, da dann height angepast wird + rect.moveTop(yMax - rect.y() - rect.height()); // nicht setY!!!!!, da dann height angepast wird rX = rect.x(); rW = rect.width(); rect.setX(0); rect.setWidth(rX); p->drawRect(rect); - rect.setX(rX+rW); - rect.setWidth(xMax-rX-rW); + rect.setX(rX + rW); + rect.setWidth(xMax - rX - rW); p->drawRect(rect); } else { rect = mMaps[i]; - rect.moveTop(yMax-rect.y()-rect.height()); // nicht setY!!!!!, da dann height angepast wird + rect.moveTop(yMax - rect.y() - rect.height()); // nicht setY!!!!!, da dann height angepast wird p->drawRect(rect); } } @@ -411,11 +417,10 @@ void RectPlotItem::setPen(const QPen &pen) } //----------------------------------------------------------------- -class Zoomer: public QwtPlotZoomer +class Zoomer : public QwtPlotZoomer { public: - Zoomer(int xAxis, int yAxis, QWidget *canvas) - : QwtPlotZoomer(xAxis, yAxis, canvas) + Zoomer(int xAxis, int yAxis, QWidget *canvas) : QwtPlotZoomer(xAxis, yAxis, canvas) { // RightButton: zoom out by 1 // Ctrl+RightButton: zoom out to full size @@ -425,35 +430,32 @@ public: setMousePattern(QwtEventPattern::MouseSelect3, Qt::RightButton); setRubberBand(QwtPicker::RectRubberBand); - setTrackerMode(QwtPicker::AlwaysOn); //ActiveOnly (only when the selection is active), AlwaysOff + setTrackerMode(QwtPicker::AlwaysOn); // ActiveOnly (only when the selection is active), AlwaysOff } // ueberschrieben, da so kommazahlen unterdrueckt werden, da intervall mindestens 5 umfasst - QSizeF minZoomSize() const override - { - return QwtDoubleSize(5., 5.); - } + QSizeF minZoomSize() const override { return QwtDoubleSize(5., 5.); } /** * @brief Allows movement in the zoomed in color plot via dragging with a pressed down middle mouse button. - * @param e - */ + * @param e + */ void widgetMouseMoveEvent(QMouseEvent *e) override { static int lastX = -1; static int lastY = -1; - int dx = e->x()-lastX; - int dy = e->y()-lastY; + int dx = e->x() - lastX; + int dy = e->y() - lastY; lastX = e->x(); lastY = e->y(); - if (e->buttons() == Qt::MiddleButton) + if(e->buttons() == Qt::MiddleButton) { plot()->setAutoReplot(false); - for (int axis = 0; axis < QwtPlot::axisCnt; axis++) + for(int axis = 0; axis < QwtPlot::axisCnt; axis++) { - if (axis == QwtPlot::xBottom || axis == QwtPlot::yLeft) + if(axis == QwtPlot::xBottom || axis == QwtPlot::yLeft) { const QwtScaleMap map = plot()->canvasMap(axis); @@ -461,7 +463,7 @@ public: const int i2 = map.transform(plot()->axisScaleDiv(axis).upperBound()); double d1, d2; - if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) + if(axis == QwtPlot::xBottom || axis == QwtPlot::xTop) { d1 = map.invTransform(i1 - dx); d2 = map.invTransform(i2 - dx); @@ -472,27 +474,26 @@ public: d2 = map.invTransform(i2 - dy); } - if (d1 < 0) + if(d1 < 0) { - d2 = d2-d1; + d2 = d2 - d1; d1 = 0; - } - else if ((axis == QwtPlot::xBottom) && (d2 > zoomBase().width())) + } + else if((axis == QwtPlot::xBottom) && (d2 > zoomBase().width())) { - d1 = d1-(d2-zoomBase().width()); + d1 = d1 - (d2 - zoomBase().width()); d2 = zoomBase().width(); - } - else if ((axis == QwtPlot::yLeft) && (d2 > zoomBase().height())) + } + else if((axis == QwtPlot::yLeft) && (d2 > zoomBase().height())) { - d1 = d1-(d2-zoomBase().height()); + d1 = d1 - (d2 - zoomBase().height()); d2 = zoomBase().height(); - } + } plot()->setAxisScale(axis, d1, d2); } } plot()->setAutoReplot(true); plot()->replot(); - } QwtPlotZoomer::widgetMouseMoveEvent(e); } @@ -515,12 +516,10 @@ public: //----------------------------------------------------------------------------------------- -class ViewColorPlotItem: public QwtPlotItem +class ViewColorPlotItem : public QwtPlotItem { public: - ViewColorPlotItem() - { - } + ViewColorPlotItem() {} /** * @brief Marks the point in color plot with the color under the cursor in the image. @@ -532,74 +531,66 @@ public: * @param mapX * @param mapY */ - void draw(QPainter* p, const QwtScaleMap& mapX, const QwtScaleMap& mapY, const QRectF& /*re*/) const + void draw(QPainter *p, const QwtScaleMap &mapX, const QwtScaleMap &mapY, const QRectF & /*re*/) const { - double sx = mapX.p2()/(mapX.s2() - mapX.s1()); - double sy = mapY.p1()/(mapY.s2() - mapY.s1()); + double sx = mapX.p2() / (mapX.s2() - mapX.s1()); + double sy = mapY.p1() / (mapY.s2() - mapY.s1()); double yMax = ((ColorPlot *) plot())->yMax(); - double sS = ((ColorPlot *) plot())->symbolSize()*0.35355339; + double sS = ((ColorPlot *) plot())->symbolSize() * 0.35355339; // TODO ganz leicht verschiebung: eigentlich muessten noch andere werte wie diese einfliessen: // p->scale((mx.p2() - mx.p1())/(mx.s2() - mx.s1()), (my.p1() - my.p2())/(my.s2() - my.s1()));// - //mx.p1()-mx.s1(), my.s2()+my.p2()-((ColorPlot *) plot())->yMax() + // mx.p1()-mx.s1(), my.s2()+my.p2()-((ColorPlot *) plot())->yMax() p->save(); p->scale(sx, sy); - p->translate(-mapX.s1(), mapY.s2()-yMax); + p->translate(-mapX.s1(), mapY.s2() - yMax); p->setPen(mPen); QPointF p1, p2; QPointF point = mPoint; - p1.setX(point.x()+sS/sx); - p1.setY(point.y()+sS/sy); - p2.setX(point.x()-sS/sx); - p2.setY(point.y()-sS/sy); + p1.setX(point.x() + sS / sx); + p1.setY(point.y() + sS / sy); + p2.setX(point.x() - sS / sx); + p2.setY(point.y() - sS / sy); p->drawLine(p1, p2); - p1.setY(point.y()-sS/sy); - p2.setY(point.y()+sS/sy); + p1.setY(point.y() - sS / sy); + p2.setY(point.y() + sS / sy); p->drawLine(p1, p2); p->restore(); } - void setPen(const QPen &pen) - { - mPen = pen; - } + void setPen(const QPen &pen) { mPen = pen; } - inline void setPoint(const QPoint &p) - { - mPoint = p; - } + inline void setPoint(const QPoint &p) { mPoint = p; } - inline QPoint point() const - { - return mPoint; - } + inline QPoint point() const { return mPoint; } private: QPoint mPoint; - QPen mPen; + QPen mPen; }; //----------------------------------------------------------------------------------------- ColorPlot::ColorPlot(QWidget *parent) // default= NULL - : QwtPlot(parent) + : + QwtPlot(parent) { mControlWidget = nullptr; - mGreyDiff = 50; - mSymbolSize = 10.; + mGreyDiff = 50; + mSymbolSize = 10.; QwtText titleX("x"); QwtText titleY("y"); setAxisTitle(xBottom, titleX); //"x" - setAxisTitle(yLeft, titleY); //"y" + setAxisTitle(yLeft, titleY); //"y" plotLayout()->setAlignCanvasToScales(true); mImageItem = new ImagePlotItem(); @@ -607,14 +598,14 @@ ColorPlot::ColorPlot(QWidget *parent) // default= NULL mZoomer = new Zoomer(xBottom, yLeft, canvas()); - mTrackerItem = new TrackerPlotItem(); - mTrackerItem->attach(this); + mTrackerItem = new TrackerPlotItem(); + mTrackerItem->attach(this); - mRectItem = new RectPlotItem(); - mRectItem->attach(this); + mRectItem = new RectPlotItem(); + mRectItem->attach(this); - mViewColorItem = new ViewColorPlotItem(); - mViewColorItem->attach(this); + mViewColorItem = new ViewColorPlotItem(); + mViewColorItem->attach(this); } void ColorPlot::replot() @@ -625,7 +616,7 @@ void ColorPlot::replot() double ColorPlot::map(const QColor &col) const { double height = mRectItem->map(col); - if (height < 0) + if(height < 0) return mControlWidget->mapDefaultHeight->value(); else return height; @@ -634,28 +625,31 @@ double ColorPlot::map(const QColor &col) const // gibt false zurueck, wenn es keine groessenverteilung ueber farbe gab bool ColorPlot::printDistribution() const { - QMap<double, int> dict; + QMap<double, int> dict; QMap<double, int>::const_iterator j; - Tracker *tr = mTrackerItem->getTracker(); - int i, anz=0; + Tracker * tr = mTrackerItem->getTracker(); + int i, anz = 0; - for (i = 0; i < tr->size(); ++i) + for(i = 0; i < tr->size(); ++i) { - if ((*tr)[i].color().isValid()) // insbesondere von hand eingefuegte trackpoint/persons haben keine farbe + if((*tr)[i].color().isValid()) // insbesondere von hand eingefuegte trackpoint/persons haben keine farbe { ++dict[map((*tr)[i].color())]; } } j = dict.constBegin(); - while (j != dict.constEnd()) { + while(j != dict.constEnd()) + { anz += j.value(); ++j; } - if (anz == 0) + if(anz == 0) return false; j = dict.constBegin(); - while (j != dict.constEnd()) { - debout << "height " << std::fixed << std::setprecision(1) << std::setw(5) << j.key() << " - number " << std::setw(3) << j.value() << " (" << std::setw(4) << (100.*j.value())/anz << "%)" << std::endl; + while(j != dict.constEnd()) + { + debout << "height " << std::fixed << std::setprecision(1) << std::setw(5) << j.key() << " - number " + << std::setw(3) << j.value() << " (" << std::setw(4) << (100. * j.value()) / anz << "%)" << std::endl; ++j; } return true; @@ -663,9 +657,8 @@ bool ColorPlot::printDistribution() const bool ColorPlot::isGrey(const QColor &col) const { - if (abs(col.red()-col.green()) < mGreyDiff && - abs(col.green()-col.blue()) < mGreyDiff && - abs(col.blue()-col.red()) < mGreyDiff) + if(abs(col.red() - col.green()) < mGreyDiff && abs(col.green() - col.blue()) < mGreyDiff && + abs(col.blue() - col.red()) < mGreyDiff) return true; else return false; @@ -694,31 +687,31 @@ QPoint ColorPlot::getPos(const QColor &col, int *z) const { QPoint p; - if (mControlWidget) + if(mControlWidget) { - int x = mControlWidget->recoColorX->currentIndex(); - int y = mControlWidget->recoColorY->currentIndex(); + int x = mControlWidget->recoColorX->currentIndex(); + int y = mControlWidget->recoColorY->currentIndex(); int ymax = (int) yMax(); - if (mControlWidget->recoColorModel->currentIndex() == 0) // HSV + if(mControlWidget->recoColorModel->currentIndex() == 0) // HSV { - if (x==0) // nicht setX und setY, weil das width und height anpasst + if(x == 0) // nicht setX und setY, weil das width und height anpasst p.setX(col.hue()); - else if (x==1) + else if(x == 1) p.setX(col.saturation()); else p.setX(col.value()); - if (y==0) - p.setY(ymax-col.hue()); - else if (y==1) - p.setY(ymax-col.saturation()); + if(y == 0) + p.setY(ymax - col.hue()); + else if(y == 1) + p.setY(ymax - col.saturation()); else - p.setY(ymax-col.value()); - if (z != nullptr) + p.setY(ymax - col.value()); + if(z != nullptr) { - if (x!=0 && y!=0) + if(x != 0 && y != 0) *z = col.hue(); - else if (x!=1 && y!=1) + else if(x != 1 && y != 1) *z = col.saturation(); else *z = col.value(); @@ -726,23 +719,23 @@ QPoint ColorPlot::getPos(const QColor &col, int *z) const } else // RGB { - if (x==0) + if(x == 0) p.setX(col.red()); - else if (x==1) + else if(x == 1) p.setX(col.green()); else p.setX(col.blue()); - if (y==0) - p.setY(ymax-col.red()); - else if (y==1) - p.setY(ymax-col.green()); + if(y == 0) + p.setY(ymax - col.red()); + else if(y == 1) + p.setY(ymax - col.green()); else - p.setY(ymax-col.blue()); - if (z != nullptr) + p.setY(ymax - col.blue()); + if(z != nullptr) { - if (x!=0 && y!=0) + if(x != 0 && y != 0) *z = col.red(); - else if (x!=1 && y!=1) + else if(x != 1 && y != 1) *z = col.green(); else *z = col.blue(); @@ -765,28 +758,29 @@ void ColorPlot::setTracker(Tracker *tracker) void ColorPlot::setScale() { - if (mControlWidget) + if(mControlWidget) { int model = mControlWidget->recoColorModel->currentIndex(); - int x = mControlWidget->recoColorX->currentIndex(); - int y = mControlWidget->recoColorY->currentIndex(); + int x = mControlWidget->recoColorX->currentIndex(); + int y = mControlWidget->recoColorY->currentIndex(); QwtDoubleRect base(0., 0., 255., 255.); - + mXMax = 255.; mYMax = 255.; - if (model == 0) // HSV + if(model == 0) // HSV { - if (x==0) + if(x == 0) mXMax = 359.; - if (y==0) + if(y == 0) mYMax = 359.; } setAxisScale(QwtPlot::xBottom, 0., mXMax); setAxisScale(QwtPlot::yLeft, 0., mYMax); - replot(); // why, see: file:///C:/Programme/qwt-5.0.1/doc/html/class_qwt_plot_zoomer.html#7a1711597f441223efdb7d9931fe19b9 + replot(); // why, see: + // file:///C:/Programme/qwt-5.0.1/doc/html/class_qwt_plot_zoomer.html#7a1711597f441223efdb7d9931fe19b9 base.setWidth(mXMax); base.setHeight(mYMax); @@ -796,22 +790,23 @@ void ColorPlot::setScale() void ColorPlot::generateImage() { - if (mControlWidget) + if(mControlWidget) { int model = mControlWidget->recoColorModel->currentIndex(); - int x = mControlWidget->recoColorX->currentIndex(); - int y = mControlWidget->recoColorY->currentIndex(); - int z = mControlWidget->recoColorZ->value(); - + int x = mControlWidget->recoColorX->currentIndex(); + int y = mControlWidget->recoColorY->currentIndex(); + int z = mControlWidget->recoColorZ->value(); + mImageItem->generateImage(model, x, y, z); // farbe anpassen, damit besser auf bild zu sehen // 255 immer genommen, da einfacher und es nicht so genau drauf ankommt - int midValue = (QColor(mImageItem->getImage()->pixel(0, 0)).value()+ - QColor(mImageItem->getImage()->pixel(255, 0)).value()+ - QColor(mImageItem->getImage()->pixel(0, 255)).value()+ - QColor(mImageItem->getImage()->pixel(255, 255)).value())/4; - if (midValue < 130) + int midValue = (QColor(mImageItem->getImage()->pixel(0, 0)).value() + + QColor(mImageItem->getImage()->pixel(255, 0)).value() + + QColor(mImageItem->getImage()->pixel(0, 255)).value() + + QColor(mImageItem->getImage()->pixel(255, 255)).value()) / + 4; + if(midValue < 130) { mZoomer->setTrackerPen(QColor(Qt::white)); mTrackerItem->setPen(QPen(Qt::white)); @@ -830,7 +825,7 @@ void ColorPlot::generateImage() int ColorPlot::zValue() const { - if (mControlWidget) + if(mControlWidget) return mControlWidget->recoColorZ->value(); else return 0; diff --git a/src/colorRangeWidget.cpp b/src/colorRangeWidget.cpp index e4b5641ca91d1f53fbf49f209aaef75130ea25bd..28844054409c1054af8c7417be17759ed6640d4c 100644 --- a/src/colorRangeWidget.cpp +++ b/src/colorRangeWidget.cpp @@ -19,20 +19,20 @@ */ #include "colorRangeWidget.h" + #include "control.h" -ColorRangeWidget::ColorRangeWidget(QWidget *parent) - : QWidget(parent) +ColorRangeWidget::ColorRangeWidget(QWidget *parent) : QWidget(parent) { - mMainWindow = (class Petrack*) parent; - mColorPlot = mMainWindow->getControlWidget()->getColorPlot(); + mMainWindow = (class Petrack *) parent; + mColorPlot = mMainWindow->getControlWidget()->getColorPlot(); mFromHue = 0; mFromSat = 0; mFromVal = 128; - mToHue = 359; - mToSat = 255; - mToVal = 255; + mToHue = 359; + mToSat = 255; + mToVal = 255; setupUi(this); @@ -52,8 +52,8 @@ ColorRangeWidget::ColorRangeWidget(QWidget *parent) void ColorRangeWidget::on_inversHue_stateChanged(int i) { mColorPlot->getMapItem()->changeActMapInvHue(i == Qt::Checked); - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); mColorPlot->replot(); } @@ -66,9 +66,8 @@ void ColorRangeWidget::on_inversHue_stateChanged(int i) */ void ColorRangeWidget::setControlWidget(int toHue, int fromHue, int toSat, int fromSat) { - int fH, tH, fS, tS; - if (toHue < fromHue) + if(toHue < fromHue) { fH = toHue; tH = fromHue; @@ -78,7 +77,7 @@ void ColorRangeWidget::setControlWidget(int toHue, int fromHue, int toSat, int f tH = toHue; fH = fromHue; } - if (toSat < fromSat) + if(toSat < fromSat) { fS = toSat; tS = fromSat; @@ -88,36 +87,40 @@ void ColorRangeWidget::setControlWidget(int toHue, int fromHue, int toSat, int f tS = toSat; fS = fromSat; } - mMainWindow->getControlWidget()->mapX->setValue(fH*2); - mMainWindow->getControlWidget()->mapW->setValue((tH-fH)); - mMainWindow->getControlWidget()->mapY->setValue(fS*2); - mMainWindow->getControlWidget()->mapH->setValue((tS-fS)); + mMainWindow->getControlWidget()->mapX->setValue(fH * 2); + mMainWindow->getControlWidget()->mapW->setValue((tH - fH)); + mMainWindow->getControlWidget()->mapY->setValue(fS * 2); + mMainWindow->getControlWidget()->mapH->setValue((tS - fS)); } void ColorRangeWidget::on_fromTriangle_colorChanged(const QColor &col) { - mFromHue = col.hue(); mFromSat = col.saturation(); mFromVal = col.value(); + mFromHue = col.hue(); + mFromSat = col.saturation(); + mFromVal = col.value(); QString styleString = QString("background-color: hsv(%1,%2,%3)").arg(mFromHue).arg(mFromSat).arg(mFromVal); fromColor->setStyleSheet(styleString); mColorPlot->getMapItem()->changeActMapFromColor(col); setControlWidget(mToHue, mFromHue, mToSat, mFromSat); - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void ColorRangeWidget::on_toTriangle_colorChanged(const QColor &col) { - mToHue = col.hue(); mToSat = col.saturation(); mToVal = col.value(); + mToHue = col.hue(); + mToSat = col.saturation(); + mToVal = col.value(); QString styleString = QString("background-color: hsv(%1,%2,%3)").arg(mToHue).arg(mToSat).arg(mToVal); toColor->setStyleSheet(styleString); mColorPlot->getMapItem()->changeActMapToColor(col); setControlWidget(mToHue, mFromHue, mToSat, mFromSat); - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } @@ -127,9 +130,10 @@ void ColorRangeWidget::on_fromColor_clicked() // ueber palette war der button ausser initial nicht zu aendern!!! QColor colBefore; - colBefore = QColor::fromHsv(mFromHue, mFromSat, mFromVal); - QColor col = (QColorDialog::getColor(colBefore, this, "Select color from which value a pixel belongs to marker")).convertTo(QColor::Hsv); - if (col.isValid() && col != colBefore) + colBefore = QColor::fromHsv(mFromHue, mFromSat, mFromVal); + QColor col = (QColorDialog::getColor(colBefore, this, "Select color from which value a pixel belongs to marker")) + .convertTo(QColor::Hsv); + if(col.isValid() && col != colBefore) { on_fromTriangle_colorChanged(col); fromTriangle->setColor(col); @@ -141,9 +145,10 @@ void ColorRangeWidget::on_toColor_clicked() // QWindowsXpStyle uses native theming engine which causes some palette modifications not to have any effect. // ueber palette war der button ausser initial nicht zu aendern!!! QColor colBefore; - colBefore = QColor::fromHsv(mToHue, mToSat, mToVal); - QColor col = (QColorDialog::getColor(colBefore, this, "Select color to which value a pixel belongs to marker")).convertTo(QColor::Hsv); - if (col.isValid() && col != colBefore) + colBefore = QColor::fromHsv(mToHue, mToSat, mToVal); + QColor col = (QColorDialog::getColor(colBefore, this, "Select color to which value a pixel belongs to marker")) + .convertTo(QColor::Hsv); + if(col.isValid() && col != colBefore) { on_toTriangle_colorChanged(col); toTriangle->setColor(col); @@ -157,9 +162,11 @@ void ColorRangeWidget::setInvHue(bool b) void ColorRangeWidget::setFromColor(const QColor &col) { - if (col.isValid()) + if(col.isValid()) { - mFromHue = col.hue(); mFromSat = col.saturation(); mFromVal = col.value(); + mFromHue = col.hue(); + mFromSat = col.saturation(); + mFromVal = col.value(); QString styleString = QString("background-color: hsv(%1,%2,%3)").arg(mFromHue).arg(mFromSat).arg(mFromVal); fromColor->setStyleSheet(styleString); fromTriangle->setColor(col); @@ -168,9 +175,11 @@ void ColorRangeWidget::setFromColor(const QColor &col) void ColorRangeWidget::setToColor(const QColor &col) { - if (col.isValid()) + if(col.isValid()) { - mToHue = col.hue(); mToSat = col.saturation(); mToVal = col.value(); + mToHue = col.hue(); + mToSat = col.saturation(); + mToVal = col.value(); QString styleString = QString("background-color: hsv(%1,%2,%3)").arg(mToHue).arg(mToSat).arg(mToVal); toColor->setStyleSheet(styleString); toTriangle->setColor(col); diff --git a/src/control.cpp b/src/control.cpp index 08025351e29ed10892b6b298895db3bbe2da40b7..39656aebcee7f18ee7a947a0bbe201b18235356f 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -18,58 +18,58 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QDomElement> -#include <iomanip> - #include "control.h" -#include "petrack.h" -#include "tracker.h" -#include "trackerItem.h" -#include "imageItem.h" + +#include "IO.h" +#include "analysePlot.h" #include "backgroundItem.h" -#include "moCapItem.h" +#include "calibFilter.h" +#include "codeMarkerWidget.h" +#include "colorMarkerWidget.h" #include "colorPlot.h" -#include "analysePlot.h" -#include "player.h" -#include "stereoWidget.h" #include "colorRangeWidget.h" -#include "colorMarkerWidget.h" -#include "codeMarkerWidget.h" +#include "imageItem.h" +#include "moCapItem.h" #include "multiColorMarkerWidget.h" -#include "view.h" -#include "IO.h" #include "pMessageBox.h" -#include "calibFilter.h" -#include "trackingRoiItem.h" +#include "petrack.h" +#include "player.h" #include "recognitionRoiItem.h" +#include "stereoWidget.h" +#include "tracker.h" +#include "trackerItem.h" +#include "trackingRoiItem.h" +#include "view.h" + +#include <QDomElement> +#include <iomanip> #define DEFAULT_HEIGHT 180.0 - -Control::Control(QWidget& parent, QGraphicsScene &scene, reco::Recognizer& recognizer) - : QWidget(&parent) + +Control::Control(QWidget &parent, QGraphicsScene &scene, reco::Recognizer &recognizer) : QWidget(&parent) { setAccessibleName("Control"); - mMainWindow = (class Petrack*) &parent; - mScene = &scene; - mLoading = false; - //beim erzeugen von new colorplot absturz!!!! + mMainWindow = (class Petrack *) &parent; + mScene = &scene; + mLoading = false; + // beim erzeugen von new colorplot absturz!!!! setupUi(this); // Observers for moCapShow, moCapSize and moCapColor in moCapController; // updates UI value when changed. - QObject::connect(&mMainWindow->getMoCapController(), &MoCapController::showMoCapChanged, - this, &Control::setMoCapShow); - QObject::connect(&mMainWindow->getMoCapController(), &MoCapController::thicknessChanged, - this, &Control::setMoCapSize); - QObject::connect(&mMainWindow->getMoCapController(), &MoCapController::colorChanged, - this, &Control::setMoCapColor); + QObject::connect( + &mMainWindow->getMoCapController(), &MoCapController::showMoCapChanged, this, &Control::setMoCapShow); + QObject::connect( + &mMainWindow->getMoCapController(), &MoCapController::thicknessChanged, this, &Control::setMoCapSize); + QObject::connect(&mMainWindow->getMoCapController(), &MoCapController::colorChanged, this, &Control::setMoCapColor); // Pulls all observable attributes mMainWindow->getMoCapController().notifyAllObserver(); - // Weitere Verzerrungsparameter werden vllt. spaeter mal gebraucht bisher von OpenCV nicht beruecksichtig. Muessen dann noch in die Oberflaeche eingebaut werden - // Deniz: OpenCV kann Sie mittlerweile benutzen, wenn man calibrateCamera die Flag CALIB_RATIONAL_MODEL übergibt; Ergibt eine genauere Kalibration - // Auch rechenintensiver, aber da wir das einmal machen und dann Speichern, ist das auch egal - // Diese Boxen müssten in die UI eingebaut und der entsprechende Aufruf in AutoCalib müsste angepasst werden + // Weitere Verzerrungsparameter werden vllt. spaeter mal gebraucht bisher von OpenCV nicht beruecksichtig. Muessen + // dann noch in die Oberflaeche eingebaut werden Deniz: OpenCV kann Sie mittlerweile benutzen, wenn man + // calibrateCamera die Flag CALIB_RATIONAL_MODEL übergibt; Ergibt eine genauere Kalibration Auch rechenintensiver, + // aber da wir das einmal machen und dann Speichern, ist das auch egal Diese Boxen müssten in die UI eingebaut und + // der entsprechende Aufruf in AutoCalib müsste angepasst werden k4 = new QDoubleSpinBox(this); k4->hide(); k5 = new QDoubleSpinBox(this); @@ -77,16 +77,17 @@ Control::Control(QWidget& parent, QGraphicsScene &scene, reco::Recognizer& recog k6 = new QDoubleSpinBox(this); k6->hide(); - filterBrightContrast->setCheckState(mMainWindow->getBrightContrastFilter()->getEnabled() ? Qt::Checked : Qt::Unchecked); -// filterContrast->setCheckState(mMainWindow->getContrastFilter()->getEnabled() ? Qt::Checked : Qt::Unchecked); -// filterBright->setCheckState(mMainWindow->getBrightFilter()->getEnabled() ? Qt::Checked : Qt::Unchecked); + filterBrightContrast->setCheckState( + mMainWindow->getBrightContrastFilter()->getEnabled() ? Qt::Checked : Qt::Unchecked); filterBorder->setCheckState(mMainWindow->getBorderFilter()->getEnabled() ? Qt::Checked : Qt::Unchecked); filterBg->setCheckState(mMainWindow->getBackgroundFilter()->getEnabled() ? Qt::Checked : Qt::Unchecked); apply->setCheckState(mMainWindow->getCalibFilter()->getEnabled() ? Qt::Checked : Qt::Unchecked); filterSwap->setCheckState(mMainWindow->getSwapFilter()->getEnabled() ? Qt::Checked : Qt::Unchecked); - filterSwapH->setCheckState((bool) mMainWindow->getSwapFilter()->getSwapHorizontally()->getValue() ? Qt::Checked : Qt::Unchecked); - filterSwapV->setCheckState((bool) mMainWindow->getSwapFilter()->getSwapVertically()->getValue() ? Qt::Checked : Qt::Unchecked); + filterSwapH->setCheckState( + (bool) mMainWindow->getSwapFilter()->getSwapHorizontally()->getValue() ? Qt::Checked : Qt::Unchecked); + filterSwapV->setCheckState( + (bool) mMainWindow->getSwapFilter()->getSwapVertically()->getValue() ? Qt::Checked : Qt::Unchecked); setCalibFxMin(mMainWindow->getCalibFilter()->getFx()->getMinimum()); setCalibFxMax(mMainWindow->getCalibFilter()->getFx()->getMaximum()); @@ -96,12 +97,8 @@ Control::Control(QWidget& parent, QGraphicsScene &scene, reco::Recognizer& recog setCalibFyMax(mMainWindow->getCalibFilter()->getFy()->getMaximum()); setCalibFyValue(mMainWindow->getCalibFilter()->getFy()->getValue()); -// setCalibCxMin(mMainWindow->getCalibFilter()->getCx()->getMinimum()); -// setCalibCxMax(mMainWindow->getCalibFilter()->getCx()->getMaximum()); setCalibCxValue(mMainWindow->getCalibFilter()->getCx()->getValue()); -// setCalibCyMin(mMainWindow->getCalibFilter()->getCy()->getMinimum()); -// setCalibCyMax(mMainWindow->getCalibFilter()->getCy()->getMaximum()); setCalibCyValue(mMainWindow->getCalibFilter()->getCy()->getValue()); setCalibR2Min(mMainWindow->getCalibFilter()->getR2()->getMinimum()); @@ -135,10 +132,6 @@ Control::Control(QWidget& parent, QGraphicsScene &scene, reco::Recognizer& recog setCalibK6Min(mMainWindow->getCalibFilter()->getK6()->getMinimum()); setCalibK6Max(mMainWindow->getCalibFilter()->getK6()->getMaximum()); setCalibK6Value(mMainWindow->getCalibFilter()->getK6()->getValue()); - //statt folgender Zeile kann zB on_cx_valueChanged einfach kodiert werden (su) - // connect(cx, SIGNAL(valueChanged(double cx)), this, SLOT(on_cx_valueChanged)); - - //wird vom designer erledigt: colorPlot->setParent(colorBox); // da nur ueber frame in designer integriert colorPlot->setControlWidget(this); @@ -164,7 +157,6 @@ Control::Control(QWidget& parent, QGraphicsScene &scene, reco::Recognizer& recog colorPlot->getMapItem()->addMap(); analysePlot->setControlWidget(this); - //analysePlot->setTrackerReal(mMainWindow->getTrackerReal()); mIndexChanging = true; @@ -181,33 +173,21 @@ Control::Control(QWidget& parent, QGraphicsScene &scene, reco::Recognizer& recog recoMethod->setCurrentIndex(recoMethod->findData(QVariant::fromValue(recognizer.getRecoMethod()))); scrollArea->setMinimumWidth( - scrollAreaWidgetContents->sizeHint().width() + - 2 * scrollArea->frameWidth() + - scrollArea->verticalScrollBar()->sizeHint().width() + - scrollAreaWidgetContents->layout()->margin() * 2 + - scrollAreaWidgetContents->layout()->spacing() * 2 - ); + scrollAreaWidgetContents->sizeHint().width() + 2 * scrollArea->frameWidth() + + scrollArea->verticalScrollBar()->sizeHint().width() + scrollAreaWidgetContents->layout()->margin() * 2 + + scrollAreaWidgetContents->layout()->spacing() * 2); scrollArea_2->setMinimumWidth( - scrollAreaWidgetContents_2->sizeHint().width() + - 2 * scrollArea_2->frameWidth() + - scrollArea_2->verticalScrollBar()->sizeHint().width()+ - scrollAreaWidgetContents_2->layout()->margin() * 2 + - scrollAreaWidgetContents_2->layout()->spacing() * 2 - ); + scrollAreaWidgetContents_2->sizeHint().width() + 2 * scrollArea_2->frameWidth() + + scrollArea_2->verticalScrollBar()->sizeHint().width() + scrollAreaWidgetContents_2->layout()->margin() * 2 + + scrollAreaWidgetContents_2->layout()->spacing() * 2); scrollArea_3->setMinimumWidth( - scrollAreaWidgetContents_3->sizeHint().width() + - 2 * scrollArea_3->frameWidth() + - scrollArea_3->verticalScrollBar()->sizeHint().width()+ - scrollAreaWidgetContents_3->layout()->margin() * 2 + - scrollAreaWidgetContents_3->layout()->spacing() * 2 - ); + scrollAreaWidgetContents_3->sizeHint().width() + 2 * scrollArea_3->frameWidth() + + scrollArea_3->verticalScrollBar()->sizeHint().width() + scrollAreaWidgetContents_3->layout()->margin() * 2 + + scrollAreaWidgetContents_3->layout()->spacing() * 2); scrollArea_4->setMinimumWidth( - scrollAreaWidgetContents_4->sizeHint().width() + - 2 * scrollArea_4->frameWidth() + - scrollArea_4->verticalScrollBar()->sizeHint().width()+ - scrollAreaWidgetContents_4->layout()->margin() * 2 + - scrollAreaWidgetContents_4->layout()->spacing() * 2 - ); + scrollAreaWidgetContents_4->sizeHint().width() + 2 * scrollArea_4->frameWidth() + + scrollArea_4->verticalScrollBar()->sizeHint().width() + scrollAreaWidgetContents_4->layout()->margin() * 2 + + scrollAreaWidgetContents_4->layout()->spacing() * 2); } void Control::setScene(QGraphicsScene *sc) @@ -215,8 +195,6 @@ void Control::setScene(QGraphicsScene *sc) mScene = sc; } -//--------------------------------------- - bool Control::getTrackShow() { return trackShow->isChecked(); @@ -239,26 +217,26 @@ QColor Control::getTrackPathColor() { return trackPathColorButton->palette().color(QPalette::Button); } + void Control::setTrackPathColor(QColor col) { QPalette pal = trackPathColorButton->palette(); pal.setColor(QPalette::Button, col); trackPathColorButton->setPalette(pal); - //trackPathColorButton->setAutoFillBackground(true); - //trackPathColorButton->update(); } + QColor Control::getTrackGroundPathColor() { return trackGroundPathColorButton->palette().color(QPalette::Button); } + void Control::setTrackGroundPathColor(QColor col) { QPalette pal = trackGroundPathColorButton->palette(); pal.setColor(QPalette::Button, col); trackGroundPathColorButton->setPalette(pal); - //trackPathColorButton->setAutoFillBackground(true); - //trackPathColorButton->update(); } + /** * @brief Getter for MoCapColor selection * @return the current selected color @@ -267,6 +245,7 @@ QColor Control::getMoCapColor() { return moCapColorButton->palette().color(QPalette::Button); } + /** * @brief Setter for MoCapShow * @@ -274,10 +253,12 @@ QColor Control::getMoCapColor() * */ void Control::setMoCapShow(bool visibility) { - if(showMoCap->isChecked() != visibility) { + if(showMoCap->isChecked() != visibility) + { showMoCap->toggle(); } } + /** * @brief Setter for MoCapColor palette and button * @@ -285,12 +266,14 @@ void Control::setMoCapShow(bool visibility) * */ void Control::setMoCapColor(QColor col) { - if(getMoCapColor() != col) { + if(getMoCapColor() != col) + { QPalette pal = moCapColorButton->palette(); pal.setColor(QPalette::Button, col); moCapColorButton->setPalette(pal); } } + /** * @brief Setter for MoCapSize * @@ -298,25 +281,27 @@ void Control::setMoCapColor(QColor col) * */ void Control::setMoCapSize(int size) { - if(moCapSize->value() != size) { + if(moCapSize->value() != size) + { moCapSize->setValue(size); } } -//--------------------------------------- - bool Control::getRecoRoiShow() { return roiShow->isChecked(); } + void Control::setRecoRoiShow(bool b) { roiShow->setChecked(b); } + bool Control::getRecoRoiFix() { return roiFix->isChecked(); } + void Control::setRecoRoiFix(bool b) { roiFix->setChecked(b); @@ -326,28 +311,27 @@ bool Control::getTrackRoiShow() { return trackRoiShow->isChecked(); } + void Control::setTrackRoiShow(bool b) { trackRoiShow->setChecked(b); } + bool Control::getTrackRoiFix() { return trackRoiFix->isChecked(); } + void Control::setTrackRoiFix(bool b) { trackRoiFix->setChecked(b); } -//--------------------------------------- - bool Control::getAdaptiveLevel() { return adaptiveLevel->isChecked(); } -//--------------------------------------- - int Control::getFilterBorderSize() { return filterBorderParamSize->value(); @@ -357,14 +341,17 @@ double Control::getCalibFxValue() { return fx->value(); } + void Control::setCalibFxValue(double d) { fx->setValue(d); } + void Control::setCalibFxMin(double d) { fx->setMinimum(d); } + void Control::setCalibFxMax(double d) { fx->setMaximum(d); @@ -374,14 +361,17 @@ double Control::getCalibFyValue() { return fy->value(); } + void Control::setCalibFyValue(double d) { fy->setValue(d); } + void Control::setCalibFyMin(double d) { fy->setMinimum(d); } + void Control::setCalibFyMax(double d) { fy->setMaximum(d); @@ -391,18 +381,17 @@ double Control::getCalibCxValue() { return cx->value(); } + void Control::setCalibCxValue(double d) { -// if( d > cx->maximum() ) -// cx->setMaximum(d); -// if( d < cx->minimum() ) -// cx->setMinimum(d); cx->setValue(d); } + void Control::setCalibCxMin(double d) { cx->setMinimum(d); } + void Control::setCalibCxMax(double d) { cx->setMaximum(d); @@ -412,18 +401,17 @@ double Control::getCalibCyValue() { return cy->value(); } + void Control::setCalibCyValue(double d) { -// if( d > cy->maximum() ) -// cy->setMaximum(d); -// if( d < cy->minimum() ) -// cy->setMinimum(d); cy->setValue(d); } + void Control::setCalibCyMin(double d) { cy->setMinimum(d); } + void Control::setCalibCyMax(double d) { cy->setMaximum(d); @@ -433,14 +421,17 @@ double Control::getCalibR2Value() { return r2->value(); } + void Control::setCalibR2Value(double d) { r2->setValue(d); } + void Control::setCalibR2Min(double d) { r2->setMinimum(d); } + void Control::setCalibR2Max(double d) { r2->setMaximum(d); @@ -450,14 +441,17 @@ double Control::getCalibR4Value() { return r4->value(); } + void Control::setCalibR4Value(double d) { r4->setValue(d); } + void Control::setCalibR4Min(double d) { r4->setMinimum(d); } + void Control::setCalibR4Max(double d) { r4->setMaximum(d); @@ -467,10 +461,12 @@ double Control::getCalibR6Value() { return r6->value(); } + void Control::setCalibR6Value(double d) { r6->setValue(d); } + void Control::setCalibR6Min(double d) { r6->setMinimum(d); @@ -484,46 +480,57 @@ double Control::getCalibExtrRot1() { return rot1->value(); } + void Control::setCalibExtrRot1(double d) { rot1->setValue(d); } + double Control::getCalibExtrRot2() { return rot2->value(); } + void Control::setCalibExtrRot2(double d) { rot2->setValue(d); } + double Control::getCalibExtrRot3() { return rot3->value(); } + void Control::setCalibExtrRot3(double d) { rot3->setValue(d); } + double Control::getCalibExtrTrans1() { return trans1->value(); } + void Control::setCalibExtrTrans1(double d) { trans1->setValue(d); } + double Control::getCalibExtrTrans2() { return trans2->value(); } + void Control::setCalibExtrTrans2(double d) { trans2->setValue(d); } + double Control::getCalibExtrTrans3() { return trans3->value(); } + void Control::setCalibExtrTrans3(double d) { trans3->setValue(d); @@ -533,14 +540,17 @@ double Control::getCalibTxValue() { return tx->value(); } + void Control::setCalibTxValue(double d) { tx->setValue(d); } + void Control::setCalibTxMin(double d) { tx->setMinimum(d); } + void Control::setCalibTxMax(double d) { tx->setMaximum(d); @@ -550,14 +560,17 @@ double Control::getCalibTyValue() { return ty->value(); } + void Control::setCalibTyValue(double d) { ty->setValue(d); } + void Control::setCalibTyMin(double d) { ty->setMinimum(d); } + void Control::setCalibTyMax(double d) { ty->setMaximum(d); @@ -567,14 +580,17 @@ double Control::getCalibK4Value() { return k4->value(); } + void Control::setCalibK4Value(double d) { k4->setValue(d); } + void Control::setCalibK4Min(double d) { k4->setMinimum(d); } + void Control::setCalibK4Max(double d) { k4->setMaximum(d); @@ -584,14 +600,17 @@ double Control::getCalibK5Value() { return k5->value(); } + void Control::setCalibK5Value(double d) { k5->setValue(d); } + void Control::setCalibK5Min(double d) { k5->setMinimum(d); } + void Control::setCalibK5Max(double d) { k5->setMaximum(d); @@ -601,29 +620,32 @@ double Control::getCalibK6Value() { return k6->value(); } + void Control::setCalibK6Value(double d) { k6->setValue(d); } + void Control::setCalibK6Min(double d) { k6->setMinimum(d); } + void Control::setCalibK6Max(double d) { k6->setMaximum(d); } -//--------------------------------------- - -int /*Petrack::Dimension*/ Control::getCalibGridDimension() +int Control::getCalibGridDimension() { return gridTab->currentIndex(); } + bool Control::getCalibGridShow() { return gridShow->isChecked(); } + void Control::setCalibGridShow(bool b) { gridShow->setChecked(b); @@ -633,6 +655,7 @@ bool Control::getCalibGridFix() { return gridFix->isChecked(); } + void Control::setCalibGridFix(bool b) { gridFix->setChecked(b); @@ -642,6 +665,7 @@ int Control::getCalibGridRotate() { return gridRotate->value(); } + void Control::setCalibGridRotate(int i) { gridRotate->setValue(i); @@ -651,6 +675,7 @@ int Control::getCalibGridTransX() { return gridTransX->value(); } + void Control::setCalibGridTransX(int i) { gridTransX->setValue(i); @@ -660,6 +685,7 @@ int Control::getCalibGridTransY() { return gridTransY->value(); } + void Control::setCalibGridTransY(int i) { gridTransY->setValue(i); @@ -669,12 +695,14 @@ int Control::getCalibGridScale() { return gridScale->value(); } + void Control::setCalibGridScale(int i) { gridScale->setValue(i); } -void Control::setEnabledExtrParams(bool enable){ +void Control::setEnabledExtrParams(bool enable) +{ rot1->setEnabled(enable); rot2->setEnabled(enable); rot3->setEnabled(enable); @@ -695,54 +723,60 @@ void Control::setGridMinMaxTranslation(int minx, int maxx, int miny, int maxy) grid3DTransY_spin->setMaximum(maxy); grid3DTransZ->setMinimum(-200); grid3DTransZ_spin->setMinimum(-200); - grid3DTransZ->setMaximum( 500); - grid3DTransZ_spin->setMaximum( 500); + grid3DTransZ->setMaximum(500); + grid3DTransZ_spin->setMaximum(500); } int Control::getCalibGrid3DTransX() { return grid3DTransX->value(); } + void Control::setCalibGrid3DTransX(int i) { grid3DTransX->setValue(i); } + int Control::getCalibGrid3DTransY() { return grid3DTransY->value(); } + void Control::setCalibGrid3DTransY(int i) { grid3DTransY->setValue(i); } + int Control::getCalibGrid3DTransZ() { return grid3DTransZ->value(); } + void Control::setCalibGrid3DTransZ(int i) { grid3DTransZ->setValue(i); } + int Control::getCalibGrid3DResolution() { return grid3DResolution->value(); } + void Control::setCalibGrid3DResolution(int i) { grid3DResolution->setValue(i); } - -//--------------------------------------- - -int/*Petrack::Dimension*/ Control::getCalibCoordDimension() +int Control::getCalibCoordDimension() { return coordTab->currentIndex(); } + bool Control::getCalibExtrCalibPointsShow() { return extCalibPointsShow->isChecked(); } + bool Control::getCalibExtrVanishPointsShow() { return extVanishPointsShow->isChecked(); @@ -752,6 +786,7 @@ bool Control::getCalibCoordShow() { return coordShow->isChecked(); } + void Control::setCalibCoordShow(bool b) { coordShow->setChecked(b); @@ -761,22 +796,27 @@ bool Control::getCalibCoordFix() { return coordFix->isChecked(); } + void Control::setCalibCoordFix(bool b) { coordFix->setChecked(b); } + int Control::getCalibCoordRotate() { return coordRotate->value(); } + void Control::setCalibCoordRotate(int i) { coordRotate->setValue(i); } + int Control::getCalibCoordTransX() { return coordTransX->value(); } + void Control::setCalibCoordTransX(int i) { coordTransX->setValue(i); @@ -786,6 +826,7 @@ int Control::getCalibCoordTransXMax() { return coordTransX->maximum(); } + void Control::setCalibCoordTransXMax(int i) { coordTransX->setMaximum(i); @@ -796,6 +837,7 @@ int Control::getCalibCoordTransXMin() { return coordTransX->minimum(); } + void Control::setCalibCoordTransXMin(int i) { coordTransX->setMinimum(i); @@ -806,6 +848,7 @@ int Control::getCalibCoordTransY() { return coordTransY->value(); } + void Control::setCalibCoordTransY(int i) { coordTransY->setValue(i); @@ -815,6 +858,7 @@ int Control::getCalibCoordTransYMax() { return coordTransY->maximum(); } + void Control::setCalibCoordTransYMax(int i) { coordTransY->setMaximum(i); @@ -825,6 +869,7 @@ int Control::getCalibCoordTransYMin() { return coordTransY->minimum(); } + void Control::setCalibCoordTransYMin(int i) { coordTransY->setMinimum(i); @@ -835,6 +880,7 @@ int Control::getCalibCoordScale() { return coordScale->value(); } + void Control::setCalibCoordScale(int i) { coordScale->setValue(i); @@ -844,6 +890,7 @@ double Control::getCalibCoordUnit() { return coordUnit->value(); } + void Control::setCalibCoordUnit(double d) { coordUnit->setValue(d); @@ -853,123 +900,96 @@ int Control::getCalibCoord3DTransX() { return coord3DTransX->value(); } + void Control::setCalibCoord3DTransX(int i) { coord3DTransX->setValue(i); } + int Control::getCalibCoord3DTransY() { return coord3DTransY->value(); } + void Control::setCalibCoord3DTransY(int i) { coord3DTransY->setValue(i); } + int Control::getCalibCoord3DTransZ() { return coord3DTransZ->value(); } + void Control::setCalibCoord3DTransZ(int i) { coord3DTransZ->setValue(i); } + int Control::getCalibCoord3DAxeLen() { return coord3DAxeLen->value(); } + void Control::setCalibCoord3DAxeLen(int i) { coord3DAxeLen->setValue(i); } + bool Control::getCalibCoord3DSwapX() { return coord3DSwapX->isChecked(); } + void Control::setCalibCoord3DSwapX(bool b) { coord3DSwapX->setChecked(b); } + bool Control::getCalibCoord3DSwapY() { return coord3DSwapY->isChecked(); } + void Control::setCalibCoord3DSwapY(bool b) { coord3DSwapY->setChecked(b); } + bool Control::getCalibCoord3DSwapZ() { return coord3DSwapZ->isChecked(); } + void Control::setCalibCoord3DSwapZ(bool b) { coord3DSwapZ->setChecked(b); } -//--------------------------------------- automatic generated slots ----------------------- - -// void Control::on_temp1_valueChanged(int i) -// { -// debout << i <<endl; -// mMainWindow->getBorderFilter()->setChanged(true);// just to flag changes -// mMainWindow->updateImage(); -// } - -// void Control::on_temp2_valueChanged(int i) -// { -// debout << i <<endl; -// mMainWindow->getBorderFilter()->setChanged(true);// just to flag changes -// mMainWindow->updateImage(); -// } - -// void Control::on_temp3_valueChanged(int i) -// { -// debout << i <<endl; -// mMainWindow->getBorderFilter()->setChanged(true);// just to flag changes -// mMainWindow->updateImage(); -// } - -// void Control::on_temp4_valueChanged(int i) -// { -// debout << i <<endl; -// mMainWindow->getBorderFilter()->setChanged(true);// just to flag changes -// mMainWindow->updateImage(); -// } - -// void Control::on_temp5_valueChanged(int i) -// { -// debout << i <<endl; -// mMainWindow->getBorderFilter()->setChanged(true);// just to flag changes -// mMainWindow->updateImage(); -// } - -//-------------------- analysation - +//-------------------- analysis void Control::on_anaCalculate_clicked() { mMainWindow->calculateRealTracker(); analysePlot->setScale(); - if (!isLoading()) + if(!isLoading()) analysePlot->replot(); -// getTrackerItem()->show(); -// mapNr->setMaximum(mapNr->maximum()+1); -// colorPlot->getMapItem()->addMap(); -// mapNr->setValue(mapNr->maximum()); } void Control::on_anaStep_valueChanged(int /*i*/) { - if (!isLoading()) + if(!isLoading()) analysePlot->replot(); } + void Control::on_anaMarkAct_stateChanged(int /*i*/) { - if (!isLoading()) + if(!isLoading()) analysePlot->replot(); } + void Control::on_anaConsiderX_stateChanged(int i) { - if ((i == Qt::Checked) && (anaConsiderY->isChecked())) + if((i == Qt::Checked) && (anaConsiderY->isChecked())) { anaConsiderAbs->setEnabled(false); anaConsiderRev->setEnabled(false); @@ -979,17 +999,18 @@ void Control::on_anaConsiderX_stateChanged(int i) anaConsiderAbs->setEnabled(true); anaConsiderRev->setEnabled(true); } - if ((i == Qt::Unchecked) && (!anaConsiderY->isChecked())) + if((i == Qt::Unchecked) && (!anaConsiderY->isChecked())) anaConsiderX->setCheckState(Qt::Checked); else { - if (!isLoading()) + if(!isLoading()) analysePlot->replot(); } } + void Control::on_anaConsiderY_stateChanged(int i) { - if ((i == Qt::Checked) && (anaConsiderX->isChecked())) + if((i == Qt::Checked) && (anaConsiderX->isChecked())) { anaConsiderAbs->setEnabled(false); anaConsiderRev->setEnabled(false); @@ -999,114 +1020,112 @@ void Control::on_anaConsiderY_stateChanged(int i) anaConsiderAbs->setEnabled(true); anaConsiderRev->setEnabled(true); } - if ((i == Qt::Unchecked) && (!anaConsiderX->isChecked())) + if((i == Qt::Unchecked) && (!anaConsiderX->isChecked())) anaConsiderY->setCheckState(Qt::Checked); else { - if (!isLoading()) + if(!isLoading()) analysePlot->replot(); } } + void Control::on_anaConsiderAbs_stateChanged(int /*i*/) { - if (!isLoading()) + if(!isLoading()) analysePlot->replot(); } + void Control::on_anaConsiderRev_stateChanged(int /*i*/) { - if (!isLoading()) + if(!isLoading()) analysePlot->replot(); } + void Control::on_showVoronoiCells_stateChanged(int /*arg1*/) { - if (!isLoading()) + if(!isLoading()) mMainWindow->getScene()->update(); } - //------------------- tracking - void Control::on_trackShow_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getTrackerItem()->show(); - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getTrackerItem()->hide(); } + void Control::on_trackFix_stateChanged(int /*i*/) { - // erst sinnvoll, wenn einzelne Punkte verschiebbar sind -// if (i == Qt::Checked) -// { -// //mMainWindow->getRecoRoiItem()->setAcceptsHoverEvents(false); wird in item gemacht -// mMainWindow->getRecoRoiItem()->setFlags(!QGraphicsItem::ItemIsMovable); -// } -// else if (i == Qt::Unchecked) -// { -// mMainWindow->getRecoRoiItem()->setAcceptsHoverEvents(true); -// mMainWindow->getRecoRoiItem()->setFlags(QGraphicsItem::ItemIsMovable); -// } + // TODO only make sense if single points are draggable } void Control::on_trackOnlineCalc_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) { - mMainWindow->setTrackChanged(true);// flag changes of track parameters + mMainWindow->setTrackChanged(true); // flag changes of track parameters mMainWindow->getTracker()->reset(); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } } + void Control::on_trackCalc_clicked() { - // mMainWindow->getTracker()->init(); // wenn vorherige Daten weggenommen werden sollen mMainWindow->trackAll(); } + void Control::on_trackReset_clicked() { - if (mMainWindow->getImage()) + if(mMainWindow->getImage()) { cv::Size size; - size.width = mMainWindow->getTrackRoiItem()->rect().width(); + size.width = mMainWindow->getTrackRoiItem()->rect().width(); size.height = mMainWindow->getTrackRoiItem()->rect().height(); - mMainWindow->setTrackChanged(true);// flag changes of track parameters - mMainWindow->setRecognitionChanged(true);// flag changes of recognition parameters + mMainWindow->setTrackChanged(true); // flag changes of track parameters + mMainWindow->setRecognitionChanged(true); // flag changes of recognition parameters mMainWindow->getTracker()->init(size); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } } + void Control::on_trackExport_clicked() { mMainWindow->exportTracker(); } + void Control::on_trackImport_clicked() { mMainWindow->importTracker(); } + void Control::on_trackTest_clicked() { mMainWindow->testTracker(); } + void Control::on_trackPathColorButton_clicked() { QColor col = QColorDialog::getColor(getTrackPathColor(), this); - if( col.isValid() ) + if(col.isValid()) { setTrackPathColor(col); } - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_trackGroundPathColorButton_clicked() { QColor col = QColorDialog::getColor(getTrackGroundPathColor(), this); - if( col.isValid() ) + if(col.isValid()) { setTrackGroundPathColor(col); } - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } @@ -1118,184 +1137,156 @@ void Control::on_moCapColorButton_clicked() mMainWindow->getMoCapController().setColor(col); } mScene->update(); - if(!mMainWindow->isLoading()) { + if(!mMainWindow->isLoading()) + { mMainWindow->updateImage(); } } void Control::on_trackRegionScale_valueChanged(int /*i*/) -{ - mMainWindow->setTrackChanged(true); - mMainWindow->getTracker()->reset(); - if( !mMainWindow->isLoading() ) +{ + mMainWindow->setTrackChanged(true); + mMainWindow->getTracker()->reset(); + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_trackRegionLevels_valueChanged(int /*i*/) -{ - mMainWindow->setTrackChanged(true); - mMainWindow->getTracker()->reset(); - if( !mMainWindow->isLoading() ) +{ + mMainWindow->setTrackChanged(true); + mMainWindow->getTracker()->reset(); + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_trackShowSearchSize_stateChanged(int /*i*/) -{ - mScene->update(); +{ + mScene->update(); } void Control::on_trackShowOnly_stateChanged(int i) { - if( i > 0 && trackShowOnlyList->checkState() == Qt::Checked) + if(i > 0 && trackShowOnlyList->checkState() == Qt::Checked) trackShowOnlyList->setChecked(false); - if (!isLoading()) mScene->update(); + if(!isLoading()) + mScene->update(); } + void Control::on_trackShowOnlyList_stateChanged(int i) { - if( i > 0 && trackShowOnly->checkState() == Qt::Checked) + if(i > 0 && trackShowOnly->checkState() == Qt::Checked) trackShowOnly->setChecked(false); trackShowOnlyListButton->setEnabled(i); trackShowOnlyNrList->setEnabled(i); - if (!isLoading()) mScene->update(); + if(!isLoading()) + mScene->update(); } void Control::on_trackShowOnlyNr_valueChanged(int /*i*/) { - if (!mMainWindow->isLoading()) + if(!mMainWindow->isLoading()) mScene->update(); -// mMainWindow->updateImage(); } -void Control::on_trackShowOnlyNrList_textChanged(const QString &/*arg1*/) +void Control::on_trackShowOnlyNrList_textChanged(const QString & /*arg1*/) { - if (!mMainWindow->isLoading()) + if(!mMainWindow->isLoading()) mScene->update(); -// mMainWindow->updateImage(); } + void Control::on_trackGotoNr_clicked() { - if (mMainWindow->getTracker()->size() >= trackShowOnlyNr->value()) - { -// int firstMin = mMainWindow->getAnimation()->getMaxFrames(), lastMax = 0; -// foreach(int onlyVisible, mMainWindow->getPedestriansToTrack() ) -// { -// if(mMainWindow->getTracker()->at(onlyVisible).firstFrame() < firstMin) -// firstMin = mMainWindow->getTracker()->at(onlyVisible).firstFrame(); -// if(mMainWindow->getTracker()->at(onlyVisible).lastFrame() > lastMax) -// lastMax = mMainWindow->getTracker()->at(onlyVisible).lastFrame(); -// } - int idx = trackShowOnlyNr->value()-1; + if(mMainWindow->getTracker()->size() >= trackShowOnlyNr->value()) + { + int idx = trackShowOnlyNr->value() - 1; int firstFrame = mMainWindow->getTracker()->at(idx).firstFrame(); - int lastFrame = mMainWindow->getTracker()->at(idx).lastFrame(); - mMainWindow->getPlayer()->skipToFrame((lastFrame+firstFrame)/2); + int lastFrame = mMainWindow->getTracker()->at(idx).lastFrame(); + mMainWindow->getPlayer()->skipToFrame((lastFrame + firstFrame) / 2); } } + void Control::on_trackGotoStartNr_clicked() { - if (mMainWindow->getTracker()->size() >= trackShowOnlyNr->value()) + if(mMainWindow->getTracker()->size() >= trackShowOnlyNr->value()) { -// int start = mMainWindow->getAnimation()->getMaxFrames(); -// foreach(int onlyVisible, mMainWindow->getPedestriansToTrack() ) -// { -// if(mMainWindow->getTracker()->at(onlyVisible).firstFrame() < start) -// start = mMainWindow->getTracker()->at(onlyVisible).firstFrame(); -// } - int idx = trackShowOnlyNr->value()-1; + int idx = trackShowOnlyNr->value() - 1; mMainWindow->getPlayer()->skipToFrame(mMainWindow->getTracker()->at(idx).firstFrame()); } } + void Control::on_trackGotoEndNr_clicked() { - if (mMainWindow->getTracker()->size() >= trackShowOnlyNr->value()) + if(mMainWindow->getTracker()->size() >= trackShowOnlyNr->value()) { -// int end = 0; -// foreach(int onlyVisible, mMainWindow->getPedestriansToTrack() ) -// { -// if(mMainWindow->getTracker()->at(onlyVisible).lastFrame() > end) -// end = mMainWindow->getTracker()->at(onlyVisible).lastFrame(); -// } - int idx = trackShowOnlyNr->value()-1; + int idx = trackShowOnlyNr->value() - 1; mMainWindow->getPlayer()->skipToFrame(mMainWindow->getTracker()->at(idx).lastFrame()); } } void Control::on_trackShowOnlyListButton_clicked() { + QMessageBox nrListBox(mMainWindow); - QMessageBox nrListBox(mMainWindow); - - nrListBox.setWindowTitle(Petrack::tr("PeTrack")); - nrListBox.setIcon(QMessageBox::NoIcon); - nrListBox.setText(Petrack::tr("Select visible pedestrians:")); - - QGridLayout* layout = (QGridLayout*) nrListBox.layout(); -// QVBoxLayout* layout = (QVBoxLayout*) nrListBox.layout(); - QVector<QCheckBox*> checkBox; + nrListBox.setWindowTitle(Petrack::tr("PeTrack")); + nrListBox.setIcon(QMessageBox::NoIcon); + nrListBox.setText(Petrack::tr("Select visible pedestrians:")); - for(int i = 0; i < mMainWindow->getTracker()->size(); i++) - { - /// ToDo: parse from lineEdit - checkBox.push_back(new QCheckBox(QString::number(i+1))); - checkBox.at(i)->setChecked( - mMainWindow->getPedestriansToTrack().contains(i)); -// layout->addWidget(checkBox.at(i)); - layout->addWidget(checkBox.at(i),3+i/5,i%5,1,1); - } + QGridLayout * layout = (QGridLayout *) nrListBox.layout(); + QVector<QCheckBox *> checkBox; + for(int i = 0; i < mMainWindow->getTracker()->size(); i++) + { + /// ToDo: parse from lineEdit + checkBox.push_back(new QCheckBox(QString::number(i + 1))); + checkBox.at(i)->setChecked(mMainWindow->getPedestriansToTrack().contains(i)); + layout->addWidget(checkBox.at(i), 3 + i / 5, i % 5, 1, 1); + } - QPushButton *ok = new QPushButton(tr("Ok")); - QPushButton *cancel = new QPushButton(tr("Cancel")); - -// layout->addWidget(ok,5,1,1,1); -// layout->addWidget(cancel,5,2,1,1); + QPushButton *ok = new QPushButton(tr("Ok")); + QPushButton *cancel = new QPushButton(tr("Cancel")); - nrListBox.addButton(cancel,QMessageBox::RejectRole); - nrListBox.addButton(ok,QMessageBox::AcceptRole); -// nrListBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); -// nrListBox.setDefaultButton(QMessageBox::Ok); + nrListBox.addButton(cancel, QMessageBox::RejectRole); + nrListBox.addButton(ok, QMessageBox::AcceptRole); - int res = nrListBox.exec(); + int res = nrListBox.exec(); - if (res == QMessageBox::Accepted) + if(res == QMessageBox::Accepted) + { + QStringList list; + int first = -1, last = -1; + for(int i = 0; i < mMainWindow->getTracker()->size(); i++) { -// debout << "ok" << endl; - QStringList list; - int first = -1, last = -1; - for(int i = 0; i < mMainWindow->getTracker()->size(); i++) + if(checkBox.at(i)->isChecked()) + { + if(first == -1) + first = i + 1; + } + else // not checked { - if (checkBox.at(i)->isChecked()){ - if (first == -1) - first = i+1; -// list.append(QString::number(i+1)); -// debout << (i+1) << ": " << checkBox.at(i)->isChecked() << endl; - }else // not checked + if(first != -1) { - if(first != -1) - { - last = i; - if(first == last) - list.append(QString::number(first)); - else - list.append(QString("%1-%2").arg(first).arg(last)); - last = -1; - first = -1; - } + last = i; + if(first == last) + list.append(QString::number(first)); + else + list.append(QString("%1-%2").arg(first).arg(last)); + last = -1; + first = -1; } - /// ToDo: lists } - trackShowOnlyNrList->setText(list.join(",")); - - }/*else if (res == QMessageBox::Rejected) - { - debout << "cancel" << endl; - }*/ - + /// ToDo: lists + } + trackShowOnlyNrList->setText(list.join(",")); + } } -void Control::on_trackHeadSized_stateChanged(int i) -{ + +void Control::on_trackHeadSized_stateChanged(int i) +{ static int oldHeadSize = 60; - if (i == Qt::Checked) + if(i == Qt::Checked) { oldHeadSize = trackCurrentPointSize->value(); trackCurrentPointSize->setValue((int) mMainWindow->getHeadSize()); @@ -1306,56 +1297,57 @@ void Control::on_trackHeadSized_stateChanged(int i) trackCurrentPointSize->setValue(oldHeadSize); trackCurrentPointSize->setEnabled(true); } - mScene->update(); + mScene->update(); } -void Control::on_showMoCap_stateChanged(int i) { +void Control::on_showMoCap_stateChanged(int i) +{ mMainWindow->getMoCapController().setShowMoCap(i == Qt::Checked); mScene->update(); } -void Control::on_moCapSize_valueChanged(int i) { +void Control::on_moCapSize_valueChanged(int i) +{ mMainWindow->getMoCapController().setThickness(i); mScene->update(); } - //------------------- recognition - void Control::on_recoShowColor_stateChanged(int i) { colorPlot->getTrackerItem()->setVisible(i == Qt::Checked); - if (!isLoading()) + if(!isLoading()) colorPlot->replot(); } + void Control::on_recoOptimizeColor_clicked() { mMainWindow->getTracker()->optimizeColor(); colorPlot->replot(); mScene->update(); // damit mgl angezeige farbpunkte geaendert/weggenommen werden } + void Control::on_recoColorModel_currentIndexChanged(int index) { static int xHsvIndex = 0; // H static int yHsvIndex = 1; // S static int xRgbIndex = 0; // R static int yRgbIndex = 1; // G - //static bool firstTime = true; - if (mColorChanging == false) // damit nicht vom constructor mehrmals bei additem durchlaufen wird + if(mColorChanging == false) // damit nicht vom constructor mehrmals bei additem durchlaufen wird { mColorChanging = true; - if (index == 0) // HSV + if(index == 0) // HSV { recoColorX->setItemText(0, "H"); recoColorX->setItemText(1, "S"); recoColorX->setItemText(2, "V"); - + recoColorY->setItemText(0, "H"); recoColorY->setItemText(1, "S"); recoColorY->setItemText(2, "V"); - if (mIndexChanging) // !firstTime + if(mIndexChanging) { xRgbIndex = recoColorX->currentIndex(); yRgbIndex = recoColorY->currentIndex(); @@ -1363,17 +1355,17 @@ void Control::on_recoColorModel_currentIndexChanged(int index) recoColorY->setCurrentIndex(yHsvIndex); } } - else //index == 1 == RGB + else // index == 1 == RGB { recoColorX->setItemText(0, "R"); recoColorX->setItemText(1, "G"); recoColorX->setItemText(2, "B"); - + recoColorY->setItemText(0, "R"); recoColorY->setItemText(1, "G"); recoColorY->setItemText(2, "B"); - if (mIndexChanging) // !firstTime + if(mIndexChanging) { xHsvIndex = recoColorX->currentIndex(); yHsvIndex = recoColorY->currentIndex(); @@ -1384,78 +1376,71 @@ void Control::on_recoColorModel_currentIndexChanged(int index) mIndexChanging = true; // firstTime = false mColorChanging = false; - //recoColorModel->currentIndex(), recoColorX->currentIndex(), recoColorY->currentIndex(), recoColorZ->value() colorPlot->setScale(); colorPlot->generateImage(); -// colorPlot->updateTracker(); - if (!isLoading()) + if(!isLoading()) colorPlot->replot(); } } void Control::on_recoColorX_currentIndexChanged(int /*index*/) { - if (mColorChanging == false) + if(mColorChanging == false) { colorPlot->setScale(); colorPlot->generateImage(); -// colorPlot->updateTracker(); - if (!isLoading()) + if(!isLoading()) colorPlot->replot(); } - // schoen waere hier das gegenstueck bei y zu disablen, aber combobox bietet dies nicht auf einfachem weg -// recoColorY->setItemText(0, "R"); -// recoColorY->setItemText(1, "G"); -// recoColorY->setItemText(2, "B"); + // TODO schoen waere hier das gegenstueck bei y zu disablen, aber combobox bietet dies nicht auf einfachem weg } void Control::on_recoColorY_currentIndexChanged(int /*index*/) { - if (mColorChanging == false) + if(mColorChanging == false) { colorPlot->setScale(); colorPlot->generateImage(); -// colorPlot->updateTracker(); - if (!isLoading()) + if(!isLoading()) colorPlot->replot(); } } void Control::on_recoColorZ_valueChanged(int /*index*/) { - if (mColorChanging == false) + if(mColorChanging == false) { colorPlot->generateImage(); - if (!isLoading()) + if(!isLoading()) colorPlot->replot(); } } void Control::on_recoGreyLevel_valueChanged(int index) { - colorPlot->setGreyDiff(index); //getTrackerItem()-> - if (!isLoading()) + colorPlot->setGreyDiff(index); + if(!isLoading()) colorPlot->replot(); } void Control::on_recoSymbolSize_valueChanged(int index) { - colorPlot->setSymbolSize(index); //getTrackerItem()-> - if (!isLoading()) + colorPlot->setSymbolSize(index); + if(!isLoading()) colorPlot->replot(); } void Control::on_recoStereoShow_clicked() { auto selectedRecognitionMethod = getRecoMethod(); - if ( selectedRecognitionMethod == reco::RecognitionMethod::MultiColor) + if(selectedRecognitionMethod == reco::RecognitionMethod::MultiColor) { mMainWindow->getMultiColorMarkerWidget()->show(); } - else if (selectedRecognitionMethod == reco::RecognitionMethod::Color) + else if(selectedRecognitionMethod == reco::RecognitionMethod::Color) { mMainWindow->getColorMarkerWidget()->show(); } - else if (selectedRecognitionMethod == reco::RecognitionMethod::Code) + else if(selectedRecognitionMethod == reco::RecognitionMethod::Code) { mMainWindow->getCodeMarkerWidget()->show(); } @@ -1467,108 +1452,146 @@ void Control::on_recoStereoShow_clicked() void Control::on_mapColorRange_clicked() { - //if (recoMethod->currentIndex() == 3) - // mMainWindow->getColorMarkerWidget()->show(); - //else mMainWindow->getColorRangeWidget()->show(); } void Control::on_mapNr_valueChanged(int i) { -// bool isloading = mMainWindow->isLoading(); -// mMainWindow->setLoading(true); -// debout << "i=" << i << endl; RectMap map = colorPlot->getMapItem()->getMap(i); - mapX->setValue(myRound(2.*map.x())); - mapY->setValue(myRound(2.*map.y())); + mapX->setValue(myRound(2. * map.x())); + mapY->setValue(myRound(2. * map.y())); mapW->setValue(myRound(map.width())); mapH->setValue(myRound(map.height())); mapColor->setCheckState(map.colored() ? Qt::Checked : Qt::Unchecked); - mapHeight->setValue(map.mapHeight()); - colorPlot->getMapItem()->changeMap(mapNr->value(), mapX->value()/2., mapY->value()/2., mapW->value(), mapH->value(), - mapColor->isChecked(), mapHeight->value()); // nur, um aktivenindex anzugeben - mMainWindow->getColorRangeWidget()->setToColor(map.toColor()); //on_toColor_clicked();on_toTriangle_colorChanged - mMainWindow->getColorRangeWidget()->setFromColor(map.fromColor()); //on_fromColor_clicked();on_fromTriangle_colorChanged - mMainWindow->getColorRangeWidget()->setInvHue(map.invHue()); //on_fromColor_clicked();on_fromTriangle_colorChanged -// mMainWindow->setLoading(false); - if (!isLoading()) + mapHeight->setValue(map.mapHeight()); + colorPlot->getMapItem()->changeMap( + mapNr->value(), + mapX->value() / 2., + mapY->value() / 2., + mapW->value(), + mapH->value(), + mapColor->isChecked(), + mapHeight->value()); // nur, um aktivenindex anzugeben + mMainWindow->getColorRangeWidget()->setToColor(map.toColor()); + mMainWindow->getColorRangeWidget()->setFromColor(map.fromColor()); + mMainWindow->getColorRangeWidget()->setInvHue(map.invHue()); + + if(!isLoading()) { colorPlot->replot(); // um aktiven gruen anzuzeigen mMainWindow->updateImage(); } -// mMainWindow->setLoading(isloading); } + void Control::on_mapX_valueChanged(int /*i*/) { - colorPlot->getMapItem()->changeMap(mapNr->value(), mapX->value()/2., mapY->value()/2., mapW->value(), mapH->value(), - mapColor->isChecked(), mapHeight->value()); - if (!isLoading()) + colorPlot->getMapItem()->changeMap( + mapNr->value(), + mapX->value() / 2., + mapY->value() / 2., + mapW->value(), + mapH->value(), + mapColor->isChecked(), + mapHeight->value()); + if(!isLoading()) colorPlot->replot(); } void Control::on_mapY_valueChanged(int /*i*/) { - colorPlot->getMapItem()->changeMap(mapNr->value(), mapX->value()/2., mapY->value()/2., mapW->value(), mapH->value(), - mapColor->isChecked(), mapHeight->value()); - if (!isLoading()) + colorPlot->getMapItem()->changeMap( + mapNr->value(), + mapX->value() / 2., + mapY->value() / 2., + mapW->value(), + mapH->value(), + mapColor->isChecked(), + mapHeight->value()); + if(!isLoading()) colorPlot->replot(); } void Control::on_mapW_valueChanged(int /*i*/) { - colorPlot->getMapItem()->changeMap(mapNr->value(), mapX->value()/2., mapY->value()/2., mapW->value(), mapH->value(), - mapColor->isChecked(), mapHeight->value()); - if (!isLoading()) + colorPlot->getMapItem()->changeMap( + mapNr->value(), + mapX->value() / 2., + mapY->value() / 2., + mapW->value(), + mapH->value(), + mapColor->isChecked(), + mapHeight->value()); + if(!isLoading()) colorPlot->replot(); } void Control::on_mapH_valueChanged(int /*i*/) { - colorPlot->getMapItem()->changeMap(mapNr->value(), mapX->value()/2., mapY->value()/2., mapW->value(), mapH->value(), - mapColor->isChecked(), mapHeight->value()); - if (!isLoading()) + colorPlot->getMapItem()->changeMap( + mapNr->value(), + mapX->value() / 2., + mapY->value() / 2., + mapW->value(), + mapH->value(), + mapColor->isChecked(), + mapHeight->value()); + if(!isLoading()) colorPlot->replot(); } void Control::on_mapColor_stateChanged(int /*i*/) { - colorPlot->getMapItem()->changeMap(mapNr->value(), mapX->value()/2., mapY->value()/2., mapW->value(), mapH->value(), - mapColor->isChecked(), mapHeight->value()); - if (!isLoading()) + colorPlot->getMapItem()->changeMap( + mapNr->value(), + mapX->value() / 2., + mapY->value() / 2., + mapW->value(), + mapH->value(), + mapColor->isChecked(), + mapHeight->value()); + if(!isLoading()) colorPlot->replot(); } void Control::on_mapHeight_valueChanged(double /*d*/) { - colorPlot->getMapItem()->changeMap(mapNr->value(), mapX->value()/2., mapY->value()/2., mapW->value(), mapH->value(), - mapColor->isChecked(), mapHeight->value()); - //colorPlot->replot(); Anzeige aendert sich nichts + colorPlot->getMapItem()->changeMap( + mapNr->value(), + mapX->value() / 2., + mapY->value() / 2., + mapW->value(), + mapH->value(), + mapColor->isChecked(), + mapHeight->value()); } void Control::on_mapHeight_editingFinished() { if(mapHeight->value() < 100) { - PInformation(this, "Height is in cm, not m!","You put in a low value for height.\n Gentle reminder that height is in cm, not m."); + PInformation( + this, + "Height is in cm, not m!", + "You put in a low value for height.\n Gentle reminder that height is in cm, not m."); } } void Control::on_mapAdd_clicked() { - mapNr->setMaximum(mapNr->maximum()+1); + mapNr->setMaximum(mapNr->maximum() + 1); colorPlot->getMapItem()->addMap(); mapNr->setValue(mapNr->maximum()); } void Control::on_mapDel_clicked() { colorPlot->getMapItem()->delMap(mapNr->value()); - if (mapNr->value() == mapNr->maximum()) - mapNr->setValue(mapNr->value()>0 ? mapNr->maximum()-1 : 0); + if(mapNr->value() == mapNr->maximum()) + mapNr->setValue(mapNr->value() > 0 ? mapNr->maximum() - 1 : 0); - mapNr->setMaximum(mapNr->maximum()>0 ? mapNr->maximum()-1 : 0); + mapNr->setMaximum(mapNr->maximum() > 0 ? mapNr->maximum() - 1 : 0); - if (!isLoading()) + if(!isLoading()) colorPlot->replot(); } void Control::on_mapDistribution_clicked() { - if (!colorPlot->printDistribution()) + if(!colorPlot->printDistribution()) mMainWindow->getTracker()->printHeightDistribution(); } void Control::on_mapResetHeight_clicked() @@ -1589,21 +1612,23 @@ void Control::on_mapDefaultHeight_valueChanged(double d) void Control::on_mapReadHeights_clicked() { - QString heightFile = QFileDialog::getOpenFileName(mMainWindow, Petrack::tr("Select text file with height information"), mMainWindow->getHeightFileName(), - Petrack::tr("Height File (*.txt);;All files (*.*)")); + QString heightFile = QFileDialog::getOpenFileName( + mMainWindow, + Petrack::tr("Select text file with height information"), + mMainWindow->getHeightFileName(), + Petrack::tr("Height File (*.txt);;All files (*.*)")); auto heights = IO::readHeightFile(heightFile); - if (std::holds_alternative<std::unordered_map<int, float>>(heights)) // heights contains the height map + if(std::holds_alternative<std::unordered_map<int, float>>(heights)) // heights contains the height map { mMainWindow->getTracker()->resetHeight(); mMainWindow->getTracker()->setMarkerHeights(std::get<std::unordered_map<int, float>>(heights)); mMainWindow->setHeightFileName(heightFile); } - else //heights contains an error string + else // heights contains an error string { - PCritical(mMainWindow, Petrack::tr("PeTrack"), - Petrack::tr(std::get<std::string>(heights).c_str())); + PCritical(mMainWindow, Petrack::tr("PeTrack"), Petrack::tr(std::get<std::string>(heights).c_str())); } mMainWindow->getTracker()->printHeightDistribution(); @@ -1612,30 +1637,33 @@ void Control::on_mapReadHeights_clicked() void Control::on_mapReadMarkerID_clicked() { - QString markerFile = QFileDialog::getOpenFileName(mMainWindow, Petrack::tr("Select text file with marker information"), mMainWindow->getHeightFileName(), - Petrack::tr("Marker File (*.txt);;All files (*.*)")); + QString markerFile = QFileDialog::getOpenFileName( + mMainWindow, + Petrack::tr("Select text file with marker information"), + mMainWindow->getHeightFileName(), + Petrack::tr("Marker File (*.txt);;All files (*.*)")); - auto markerIDs = IO::readMarkerIDFile(markerFile); + auto markerIDs = IO::readMarkerIDFile(markerFile); - if (std::holds_alternative<std::unordered_map<int, int>>(markerIDs)) // markerIDs contains the marker information - { - mMainWindow->getTracker()->setMarkerIDs(std::get<std::unordered_map<int, int>>(markerIDs)); - mMainWindow->setMarkerIDFileName(markerFile); - } - else //heights contains an error string - { - QMessageBox::critical(mMainWindow, Petrack::tr("PeTrack"), - Petrack::tr(std::get<std::string>(markerIDs).c_str())); - } + if(std::holds_alternative<std::unordered_map<int, int>>(markerIDs)) // markerIDs contains the marker information + { + mMainWindow->getTracker()->setMarkerIDs(std::get<std::unordered_map<int, int>>(markerIDs)); + mMainWindow->setMarkerIDFileName(markerFile); + } + else // heights contains an error string + { + QMessageBox::critical( + mMainWindow, Petrack::tr("PeTrack"), Petrack::tr(std::get<std::string>(markerIDs).c_str())); + } - mMainWindow->getTracker()->printHeightDistribution(); - mScene->update(); + mMainWindow->getTracker()->printHeightDistribution(); + mScene->update(); } void Control::on_performRecognition_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag changes of recognition parameters - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag changes of recognition parameters + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } @@ -1652,201 +1680,164 @@ void Control::onRecoMethodChanged(reco::RecognitionMethod method) void Control::on_markerBrightness_valueChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag changes of recognition parameters - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag changes of recognition parameters + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void Control::on_markerIgnoreWithout_stateChanged(int /*i*/) { - mMainWindow->setRecognitionChanged(true);// flag changes of recognition parameters - if( !mMainWindow->isLoading() ) + mMainWindow->setRecognitionChanged(true); // flag changes of recognition parameters + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void Control::on_roiShow_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getRecoRoiItem()->show(); // setVisible - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getRecoRoiItem()->hide(); // setVisible - //mScene->update(); } void Control::on_roiFix_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) { - //mMainWindow->getRecoRoiItem()->setAcceptsHoverEvents(false); wird in item gemacht - //mMainWindow->getRecoRoiItem()->setFlags(!QGraphicsItem::ItemIsMovable); mMainWindow->getRecoRoiItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) { mMainWindow->getRecoRoiItem()->setAcceptHoverEvents(true); - //mMainWindow->getRecoRoiItem()->setFlags(QGraphicsItem::ItemIsMovable); mMainWindow->getRecoRoiItem()->setFlag(QGraphicsItem::ItemIsMovable); } - //mScene->update(); } void Control::on_trackRoiShow_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getTrackRoiItem()->show(); // setVisible - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getTrackRoiItem()->hide(); // setVisible - //mScene->update(); } void Control::on_trackRoiFix_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) { - //mMainWindow->getRecoRoiItem()->setAcceptsHoverEvents(false); wird in item gemacht - //mMainWindow->getRecoRoiItem()->setFlags(!QGraphicsItem::ItemIsMovable); mMainWindow->getTrackRoiItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) { mMainWindow->getTrackRoiItem()->setAcceptHoverEvents(true); - //mMainWindow->getRecoRoiItem()->setFlags(QGraphicsItem::ItemIsMovable); mMainWindow->getTrackRoiItem()->setFlag(QGraphicsItem::ItemIsMovable); } - //mScene->update(); } //---------------------- calibration - void Control::on_filterBrightContrast_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getBrightContrastFilter()->enable(); - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getBrightContrastFilter()->disable(); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } -// void Control::on_filterContrast_stateChanged(int i) -// { -// if (i == Qt::Checked) -// mMainWindow->getContrastFilter()->enable(); -// else if (i == Qt::Unchecked) -// mMainWindow->getContrastFilter()->disable(); -// mMainWindow->updateImage(); -// } void Control::on_filterContrastParam_valueChanged(int i) { mMainWindow->getBrightContrastFilter()->getContrast()->setValue(i); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } -// void Control::on_filterBright_stateChanged(int i) -// { -// if (i == Qt::Checked) -// mMainWindow->getBrightFilter()->enable(); -// else if (i == Qt::Unchecked) -// mMainWindow->getBrightFilter()->disable(); -// mMainWindow->updateImage(); -// } + void Control::on_filterBrightParam_valueChanged(int i) { - //debout << "test i: "<< i << " isLoading: " << mMainWindow->isLoading() << endl; mMainWindow->getBrightContrastFilter()->getBrightness()->setValue(i); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_filterBorder_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getBorderFilter()->enable(); - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getBorderFilter()->disable(); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_filterBorderParamSize_valueChanged(int i) { -// debout << "test: " << i << endl; - mMainWindow->setImageBorderSize(2*i); // 2* because undistored has problem with sizes not dividable of 4 - if( !mMainWindow->isLoading() ) + mMainWindow->setImageBorderSize(2 * i); // 2* because undistored has problem with sizes not dividable of 4 + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); -// debout << "test: out" << endl; } + void Control::on_filterBorderParamCol_clicked() { - BorderFilter *bf = mMainWindow->getBorderFilter(); - QColor color = QColorDialog::getColor(QColor((int)bf->getBorderColR()->getValue(), (int)bf->getBorderColG()->getValue(), (int)bf->getBorderColB()->getValue()), this); + BorderFilter *bf = mMainWindow->getBorderFilter(); + QColor color = QColorDialog::getColor( + QColor( + (int) bf->getBorderColR()->getValue(), + (int) bf->getBorderColG()->getValue(), + (int) bf->getBorderColB()->getValue()), + this); bf->getBorderColR()->setValue(color.red()); bf->getBorderColG()->setValue(color.green()); bf->getBorderColB()->setValue(color.blue()); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_filterSwap_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getSwapFilter()->enable(); - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getSwapFilter()->disable(); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_filterSwapH_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getSwapFilter()->getSwapHorizontally()->setValue(1); - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getSwapFilter()->getSwapHorizontally()->setValue(0); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_filterSwapV_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getSwapFilter()->getSwapVertically()->setValue(1); - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getSwapFilter()->getSwapVertically()->setValue(0); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } -//void Control::on_filterBgCalc_clicked() -//{ -// mMainWindow->calcBackground(); -// //BorderFilter *bf = mMainWindow->getBorderFilter(); -// //mMainWindow->updateImage(); -//} + void Control::on_filterBg_stateChanged(int i) { - - //////// - // Bei der Umstellung auf die aktuellste OpenCV Version 3 haben sich die - // Funktionsaufrufe/Interfaces stark geaendert. Da eine Anpassung viel Zeit kosten wuerde, - // jedoch der Filter sehr selten genutzt wird, wird er bis auf weiteres nicht verfuegbar sein. -// if (i == Qt::Checked) -// { -// debout << "The BackgroundFilter is temporary not available!" << endl; -// QMessageBox::warning(mMainWindow, Petrack::tr("Petrack"), Petrack::tr("BackgroundFilter is temporary not available!")); -// filterBg->setCheckState(Qt::Unchecked); -// } -// if(false){ /// temporary disabled backgroundfilter - //////// static int showCheckState = filterBgShow->checkState(); - - if (i == Qt::Checked) + if(i == Qt::Checked) { filterBgShow->setEnabled(true); filterBgUpdate->setEnabled(true); filterBgReset->setEnabled(true); filterBgSave->setEnabled(true); filterBgLoad->setEnabled(true); - if (showCheckState == Qt::Checked) + if(showCheckState == Qt::Checked) filterBgShow->setCheckState(Qt::Checked); filterBgDeleteNumber->setEnabled(true); filterBgDeleteTrj->setEnabled(true); mMainWindow->getBackgroundFilter()->enable(); } - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) { filterBgShow->setEnabled(false); filterBgUpdate->setEnabled(false); @@ -1859,118 +1850,124 @@ void Control::on_filterBg_stateChanged(int i) filterBgDeleteTrj->setEnabled(false); mMainWindow->getBackgroundFilter()->disable(); } - if( !mMainWindow->isLoading() ) - mMainWindow->updateImage(true); // true, da auch bei stehendem bild neue berechnungen durchgefuehrt werden sollen -// }/// temporary disabled backgroundfilter + if(!mMainWindow->isLoading()) + mMainWindow->updateImage( + true); // true, da auch bei stehendem bild neue berechnungen durchgefuehrt werden sollen } + void Control::on_filterBgUpdate_stateChanged(int i) { - if (i == Qt::Checked) - mMainWindow->getBackgroundFilter()->setUpdate(true);// enable(); - else if (i == Qt::Unchecked) - mMainWindow->getBackgroundFilter()->setUpdate(false);//->disable(); - //mMainWindow->updateImage(); + if(i == Qt::Checked) + mMainWindow->getBackgroundFilter()->setUpdate(true); // enable(); + else if(i == Qt::Unchecked) + mMainWindow->getBackgroundFilter()->setUpdate(false); //->disable(); } + void Control::on_filterBgReset_clicked() { mMainWindow->getBackgroundFilter()->reset(); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_filterBgShow_stateChanged(int i) { mMainWindow->getBackgroundItem()->setVisible(i); - //mMainWindow->getScene()->update(); mScene->update(); - //mMainWindow->updateImage(); } + void Control::on_filterBgSave_clicked() { mMainWindow->getBackgroundFilter()->save(); } + void Control::on_filterBgLoad_clicked() { mMainWindow->getBackgroundFilter()->load(); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } void Control::on_apply_stateChanged(int i) { - if (i == Qt::Checked) + if(i == Qt::Checked) mMainWindow->getCalibFilter()->enable(); - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) mMainWindow->getCalibFilter()->disable(); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_fx_valueChanged(double d) { - //cout << (mMainWindow->accessibleName()).toStdString() <<endl; - //cout << accessibleName().toStdString() <<endl; - //mMainWindow->statusBar()->showMessage((new QString)->setNum(d)); // mMainWindow->getCalibFilter()->getFx()->setValue(d); - if (quadAspectRatio->isChecked()) + if(quadAspectRatio->isChecked()) fy->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); setMeasuredAltitude(); } + void Control::on_fy_valueChanged(double d) { mMainWindow->getCalibFilter()->getFy()->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); setMeasuredAltitude(); } + void Control::on_cx_valueChanged(double d) { mMainWindow->setStatusPosReal(); mMainWindow->getCalibFilter()->getCx()->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) { mMainWindow->updateCoord(); - //mMainWindow->updateImage(); } } + void Control::on_cy_valueChanged(double d) { mMainWindow->setStatusPosReal(); mMainWindow->getCalibFilter()->getCy()->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) { mMainWindow->updateCoord(); - //mMainWindow->updateImage(); } } + void Control::on_r2_valueChanged(double d) { mMainWindow->getCalibFilter()->getR2()->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_r4_valueChanged(double d) { mMainWindow->getCalibFilter()->getR4()->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_r6_valueChanged(double d) { mMainWindow->getCalibFilter()->getR6()->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_tx_valueChanged(double d) { mMainWindow->getCalibFilter()->getTx()->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } + void Control::on_ty_valueChanged(double d) { mMainWindow->getCalibFilter()->getTy()->setValue(d); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } @@ -1978,36 +1975,37 @@ void Control::on_quadAspectRatio_stateChanged(int i) { static double oldFyValue = 0; - if (i == Qt::Checked) + if(i == Qt::Checked) { oldFyValue = fy->value(); fy->setValue(fx->value()); fy->setDisabled(true); } - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) { fy->setEnabled(true); fy->setValue(oldFyValue); } } + void Control::on_fixCenter_stateChanged(int i) { static double oldCxValue = 0; static double oldCyValue = 0; - if (i == Qt::Checked) + if(i == Qt::Checked) { oldCxValue = cx->value(); oldCyValue = cy->value(); - if (mMainWindow->getImage()) + if(mMainWindow->getImage()) { - cx->setValue((mMainWindow->getImage()->width()-1)/2.); // mgl auch iplimg,wenn bild vergroessert wird - cy->setValue((mMainWindow->getImage()->height()-1)/2.); + cx->setValue((mMainWindow->getImage()->width() - 1) / 2.); // mgl auch iplimg,wenn bild vergroessert wird + cy->setValue((mMainWindow->getImage()->height() - 1) / 2.); } cx->setDisabled(true); cy->setDisabled(true); } - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) { cx->setEnabled(true); cy->setEnabled(true); @@ -2015,19 +2013,20 @@ void Control::on_fixCenter_stateChanged(int i) cy->setValue(oldCyValue); } } + void Control::on_tangDist_stateChanged(int i) { static double oldTxValue = 0; static double oldTyValue = 0; - if (i == Qt::Checked) + if(i == Qt::Checked) { tx->setEnabled(true); ty->setEnabled(true); tx->setValue(oldTxValue); ty->setValue(oldTyValue); } - else if (i == Qt::Unchecked) + else if(i == Qt::Unchecked) { oldTxValue = tx->value(); oldTyValue = ty->value(); @@ -2044,83 +2043,94 @@ void Control::on_autoCalib_clicked() } void Control::on_calibFiles_clicked() { - if (mMainWindow->getAutoCalib()->openCalibFiles()) + if(mMainWindow->getAutoCalib()->openCalibFiles()) autoCalib->setEnabled(true); } -//--------------------------------------- +//--------------------------------------- void Control::on_rot1_valueChanged(double /*arg1*/) { - if (!isLoading()) + if(!isLoading()) mMainWindow->updateCoord(); } + void Control::on_rot2_valueChanged(double /*arg1*/) { - if (!isLoading()) - mMainWindow->updateCoord(); + if(!isLoading()) + mMainWindow->updateCoord(); } + void Control::on_rot3_valueChanged(double /*arg1*/) { - if (!isLoading()) + if(!isLoading()) mMainWindow->updateCoord(); } + void Control::on_trans1_valueChanged(double /*arg1*/) { - if (!isLoading()) - mMainWindow->updateCoord(); + if(!isLoading()) + mMainWindow->updateCoord(); } + void Control::on_trans2_valueChanged(double /*arg1*/) { - if (!isLoading()) + if(!isLoading()) mMainWindow->updateCoord(); } + void Control::on_trans3_valueChanged(double /*arg1*/) { - if (!isLoading()) + if(!isLoading()) mMainWindow->updateCoord(); } + void Control::on_extCalibPointsShow_stateChanged(int /*arg1*/) { - if (!isLoading()) - mScene->update(); + if(!isLoading()) + mScene->update(); } void Control::on_extrCalibShowError_clicked() { - - QString out; - QDialog msgBox; - QGridLayout* layout = new QGridLayout(); + QString out; + QDialog msgBox; + QGridLayout *layout = new QGridLayout(); msgBox.setLayout(layout); - QLabel* tableView = new QLabel(&msgBox); + QLabel *tableView = new QLabel(&msgBox); layout->addWidget(tableView, 1, 1); - QLabel* titel = new QLabel(&msgBox); + QLabel *titel = new QLabel(&msgBox); titel->setText("<b>Reprojection error for extrinsic calibration:</b>"); - layout->addWidget(titel, 0,1); + layout->addWidget(titel, 0, 1); - if( !mMainWindow->getExtrCalibration()->getReprojectionError().isValid() ) + if(!mMainWindow->getExtrCalibration()->getReprojectionError().isValid()) { out = QString("No File for extrinsic calibration found!"); tableView->setText(out); } else { - - out = QString("<table>" + out = QString("<table>" "<tr><th></th>" "<th>average </th>" "<th>std. deviation </th>" "<th>variance </th>" "<th>max </th></tr>" - "<tr><td>Point height: </td><td> %0 cm</td><td> %1 cm</td><td> %2 cm</td><td> %3 cm</td></tr>" - "<tr><td>Default height: <small>[%12 cm]</small> </td><td> %4 cm</td><td> %5 cm</td><td> %6 cm</td><td> %7 cm</td></tr>" - "<tr><td>Pixel error: </td><td> %8 px</td><td> %9 px</td><td> %10 px</td><td> %11 px</td></tr>" + "<tr><td>Point height: </td><td> %0 cm</td><td> %1 cm</td><td> %2 " + "cm</td><td> %3 cm</td></tr>" + "<tr><td>Default height: <small>[%12 cm]</small> </td><td> %4 cm</td><td> %5 cm</td><td> %6 " + "cm</td><td> %7 cm</td></tr>" + "<tr><td>Pixel error: </td><td> %8 px</td><td> %9 px</td><td> %10 " + "px</td><td> %11 px</td></tr>" "</table>"); - const auto& reproError = mMainWindow->getExtrCalibration()->getReprojectionError().getData(); - for(double value : reproError){ - if(value < 0){ + const auto &reproError = mMainWindow->getExtrCalibration()->getReprojectionError().getData(); + for(double value : reproError) + { + if(value < 0) + { out = out.arg("-"); - }else{ + } + else + { out = out.arg(value); } } @@ -2128,9 +2138,9 @@ void Control::on_extrCalibShowError_clicked() } msgBox.setWindowTitle("PeTrack"); - QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); - QLabel* infoIcon = new QLabel(&msgBox); - int iconSize = msgBox.style()->pixelMetric(QStyle::PM_MessageBoxIconSize, nullptr, &msgBox); + QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); + QLabel *infoIcon = new QLabel(&msgBox); + int iconSize = msgBox.style()->pixelMetric(QStyle::PM_MessageBoxIconSize, nullptr, &msgBox); infoIcon->setPixmap(icon.pixmap(iconSize, iconSize)); layout->addWidget(infoIcon, 0, 0); QDialogButtonBox *ok = new QDialogButtonBox(QDialogButtonBox::Ok); @@ -2142,17 +2152,17 @@ void Control::on_extrCalibShowError_clicked() void Control::on_extVanishPointsShow_stateChanged(int /*arg1*/) { - if (!isLoading()) + if(!isLoading()) mScene->update(); } void Control::on_coordLoad3DCalibPoints_clicked() { - //debout << "On_load3DCalibPoints clicked!" << endl; mMainWindow->getExtrCalibration()->openExtrCalibFile(); mMainWindow->updateCoord(); mScene->update(); } + void Control::on_extrCalibSave_clicked() { mMainWindow->getExtrCalibration()->saveExtrCalibPoints(); @@ -2165,7 +2175,7 @@ void Control::on_extrCalibFetch_clicked() void Control::on_extrCalibShowPoints_clicked() { - QString out_str; + QString out_str; QTextStream out(&out_str); unsigned int i; @@ -2173,28 +2183,33 @@ void Control::on_extrCalibShowPoints_clicked() out << "<table><tr><th>Nr.</th><th>3D.x</th><th>3D.y</th><th>3D.z</th><th>2D.x</th><th>2D.y</th></tr>" << Qt::endl; - for (i = 0; i < std::max(mMainWindow->getExtrCalibration()->get3DList().size(),mMainWindow->getExtrCalibration()->get2DList().size()); ++i) + for(i = 0; i < std::max( + mMainWindow->getExtrCalibration()->get3DList().size(), + mMainWindow->getExtrCalibration()->get2DList().size()); + ++i) { out << "<tr>"; - if( i < mMainWindow->getExtrCalibration()->get3DList().size() ) + if(i < mMainWindow->getExtrCalibration()->get3DList().size()) { - out << "<td>[" << QString::number(i+1,'i',0) << "]: </td><td>" - << QString::number(mMainWindow->getExtrCalibration()->get3DList().at(i).x,'f',1) << "</td><td>" - << QString::number(mMainWindow->getExtrCalibration()->get3DList().at(i).y,'f',1) << "</td><td>" - << QString::number(mMainWindow->getExtrCalibration()->get3DList().at(i).z,'f',1) << "</td><td>"; - }else + out << "<td>[" << QString::number(i + 1, 'i', 0) << "]: </td><td>" + << QString::number(mMainWindow->getExtrCalibration()->get3DList().at(i).x, 'f', 1) << "</td><td>" + << QString::number(mMainWindow->getExtrCalibration()->get3DList().at(i).y, 'f', 1) << "</td><td>" + << QString::number(mMainWindow->getExtrCalibration()->get3DList().at(i).z, 'f', 1) << "</td><td>"; + } + else { out << "<td>-</td><td>-</td><td>-</td>"; } - if( i < mMainWindow->getExtrCalibration()->get2DList().size() ) + if(i < mMainWindow->getExtrCalibration()->get2DList().size()) { - out << QString::number(mMainWindow->getExtrCalibration()->get2DList().at(i).x,'f',3) << "</td><td>" - << QString::number(mMainWindow->getExtrCalibration()->get2DList().at(i).y,'f',3) << "</td>"; - }else + out << QString::number(mMainWindow->getExtrCalibration()->get2DList().at(i).x, 'f', 3) << "</td><td>" + << QString::number(mMainWindow->getExtrCalibration()->get2DList().at(i).y, 'f', 3) << "</td>"; + } + else { out << "<td>-</td><td>-</td>"; } - out << "</tr>" << Qt::endl; + out << "</tr>" << Qt::endl; } out << "</table>" << Qt::endl; @@ -2202,117 +2217,139 @@ void Control::on_extrCalibShowPoints_clicked() msgBox.setWindowTitle("PeTrack"); msgBox.setIcon(QMessageBox::Information); msgBox.setText("Currently loaded point correspondences<br />for extrinsic calibration:"); - msgBox.setInformativeText( out_str ); + msgBox.setInformativeText(out_str); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); - } + //--------------------------------------- void Control::on_gridTab_currentChanged(int /*index*/) { - //cout << "on_gridTabView_currentchanged: index=" << index << endl; mScene->update(); } + void Control::on_gridShow_stateChanged(int /*i*/) { mScene->update(); -// mMainWindow->getImageWidget()->update(); // repaint() zeichnet sofort - schneller aber mgl flicker } + void Control::on_gridFix_stateChanged(int /*i*/) { mScene->update(); } + void Control::on_gridRotate_valueChanged(int /*i*/) { mScene->update(); } + void Control::on_gridTransX_valueChanged(int /*i*/) { mScene->update(); } + void Control::on_gridTransY_valueChanged(int /*i*/) { mScene->update(); } + void Control::on_gridScale_valueChanged(int /*i*/) { mScene->update(); } + void Control::on_grid3DTransX_valueChanged(int /*value*/) { - if (!isLoading()) - mScene->update(); + if(!isLoading()) + mScene->update(); } + void Control::on_grid3DTransY_valueChanged(int /*value*/) { - if (!isLoading()) - mScene->update(); + if(!isLoading()) + mScene->update(); } void Control::on_grid3DTransZ_valueChanged(int /*value*/) { - if (!isLoading()) - mScene->update(); + if(!isLoading()) + mScene->update(); } void Control::on_grid3DResolution_valueChanged(int /*value*/) { - if (!isLoading()) - mScene->update(); + if(!isLoading()) + mScene->update(); } + //--------------------------------------- void Control::on_coordTab_currentChanged(int index) { - //debout << "on_coordTabView_currentchanged: index=" << index << endl; - if( index == 1 ){ + if(index == 1) + { setEnabledExtrParams(false); trackShowGroundPosition->setEnabled(false); trackShowGroundPath->setEnabled(false); - }else{ + } + else + { setEnabledExtrParams(true); trackShowGroundPosition->setEnabled(true); trackShowGroundPath->setEnabled(true); } - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); mScene->update(); - } + } } + void Control::on_coordShow_stateChanged(int /*i*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); mScene->update(); - setMeasuredAltitude(); // da measured nicht aktualisiert wird, waehrend scale verschoben und show deaktiviert und beim aktivieren sonst ein falscher wert zum angezeigten koord waere + setMeasuredAltitude(); // da measured nicht aktualisiert wird, waehrend scale verschoben und show deaktiviert + // und beim aktivieren sonst ein falscher wert zum angezeigten koord waere } -// mScene->update(); //mScene->sceneRect() // ging auch, aber dann wurde zu oft matrix berechnet etc -// mMainWindow->getImageWidget()->update(); // repaint() zeichnet sofort - schneller aber mgl flicker + // mScene->update(); //mScene->sceneRect() // ging auch, aber dann wurde zu oft matrix berechnet etc + // mMainWindow->getImageWidget()->update(); // repaint() zeichnet sofort - schneller aber mgl flicker } + void Control::on_coordFix_stateChanged(int /*i*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } + void Control::on_coordRotate_valueChanged(int /*i*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } + void Control::on_coordTransX_valueChanged(int /*i*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } + void Control::on_coordTransY_valueChanged(int /*i*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } + void Control::on_coordScale_valueChanged(int /*i*/) { mMainWindow->updateCoord(); @@ -2325,12 +2362,14 @@ void Control::on_coordAltitude_valueChanged(double /*d*/) mMainWindow->setHeadSize(); mScene->update(); // fuer kreis um kopf, der mgl der realen kopfgroesse angepasst wird } + void Control::on_coordUnit_valueChanged(double /*d*/) { setMeasuredAltitude(); mMainWindow->setHeadSize(); mScene->update(); // fuer kreis um kopf, der mgl der realen kopfgroesse angepasst wird } + void Control::on_coordUseIntrinsic_stateChanged(int /*i*/) { mMainWindow->setStatusPosReal(); @@ -2338,448 +2377,459 @@ void Control::on_coordUseIntrinsic_stateChanged(int /*i*/) void Control::on_coord3DTransX_valueChanged(int /*value*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } void Control::on_coord3DTransY_valueChanged(int /*value*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } void Control::on_coord3DTransZ_valueChanged(int /*value*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } void Control::on_coord3DAxeLen_valueChanged(int /*value*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } void Control::on_coord3DSwapX_stateChanged(int /*arg1*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } void Control::on_coord3DSwapY_stateChanged(int /*arg1*/) { - if (!isLoading()){ -// bool hans = isLoading(); + if(!isLoading()) + { mMainWindow->updateCoord(); } } void Control::on_coord3DSwapZ_stateChanged(int /*arg1*/) { - if (!isLoading()){ + if(!isLoading()) + { mMainWindow->updateCoord(); } } + void Control::setMeasuredAltitude() { - if (mMainWindow->getImageItem()) - coordAltitudeMeasured->setText(QString("(measured: %1)").arg((getCalibFxValue()+getCalibFyValue())/2.*mMainWindow->getImageItem()->getCmPerPixel(), 6, 'f', 1)); - + if(mMainWindow->getImageItem()) + coordAltitudeMeasured->setText( + QString("(measured: %1)") + .arg( + (getCalibFxValue() + getCalibFyValue()) / 2. * mMainWindow->getImageItem()->getCmPerPixel(), + 6, + 'f', + 1)); } - //--------------------------------------- - // store data in xml node void Control::setXml(QDomElement &elem) { - QDomElement subElem; - QDomElement subSubElem; - QDomElement subSubSubElem; - QString fn; - QString heightFile; - QString markerFile; - - elem.setAttribute("TAB", tabs->currentIndex()); - - // - - - - - - - - - - - - - - - - - - - - subElem = (elem.ownerDocument()).createElement("CALIBRATION"); - elem.appendChild(subElem); - - subSubElem = (elem.ownerDocument()).createElement("BRIGHTNESS"); - subSubElem.setAttribute("ENABLED", filterBrightContrast->isChecked()); - subSubElem.setAttribute("VALUE", filterBrightParam->value()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("CONTRAST"); - subSubElem.setAttribute("ENABLED", filterBrightContrast->isChecked()); - subSubElem.setAttribute("VALUE", filterContrastParam->value()); - subElem.appendChild(subSubElem); - - BorderFilter *bf = mMainWindow->getBorderFilter(); - QColor col((int)bf->getBorderColR()->getValue(), (int)bf->getBorderColG()->getValue(), (int)bf->getBorderColB()->getValue()); - subSubElem = (elem.ownerDocument()).createElement("BORDER"); - subSubElem.setAttribute("ENABLED", filterBorder->isChecked()); - subSubElem.setAttribute("VALUE", filterBorderParamSize->value()); - subSubElem.setAttribute("COLOR", col.name()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("SWAP"); - subSubElem.setAttribute("ENABLED", filterSwap->isChecked()); - subSubElem.setAttribute("HORIZONTALLY", filterSwapH->isChecked()); - subSubElem.setAttribute("VERTICALLY", filterSwapV->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("BG_SUB"); - subSubElem.setAttribute("ENABLED", filterBg->isChecked()); - subSubElem.setAttribute("UPDATE", filterBgUpdate->isChecked()); - subSubElem.setAttribute("SHOW", filterBgShow->isChecked()); - fn = mMainWindow->getBackgroundFilter()->getFilename(); - if (fn != "") - fn = getFileList(fn, mMainWindow->getProFileName()); - subSubElem.setAttribute("FILE", fn); - subSubElem.setAttribute("DELETE", filterBgDeleteTrj->isChecked()); - subSubElem.setAttribute("DELETE_NUMBER", filterBgDeleteNumber->value()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("PATTERN"); - subSubElem.setAttribute("BOARD_SIZE_X", mMainWindow->getAutoCalib()->getBoardSizeX()); // 6 - subSubElem.setAttribute("BOARD_SIZE_Y", mMainWindow->getAutoCalib()->getBoardSizeY()); // 8 oder 9 - subSubElem.setAttribute("SQUARE_SIZE", mMainWindow->getAutoCalib()->getSquareSize()); // in cm - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("INTRINSIC_PARAMETERS"); - subSubElem.setAttribute("ENABLED", apply->isChecked()); - subSubElem.setAttribute("FX", fx->value()); - subSubElem.setAttribute("FY", fy->value()); - subSubElem.setAttribute("CX", cx->value()); - subSubElem.setAttribute("CY", cy->value()); - subSubElem.setAttribute("R2", r2->value()); - subSubElem.setAttribute("R4", r4->value()); - subSubElem.setAttribute("R6", r6->value()); - subSubElem.setAttribute("TX", tx->value()); - subSubElem.setAttribute("TY", ty->value()); - subSubElem.setAttribute("K4", k4->value()); - subSubElem.setAttribute("K5", k5->value()); - subSubElem.setAttribute("K6", k6->value()); - subSubElem.setAttribute("QUAD_ASPECT_RATIO", quadAspectRatio->isChecked()); - subSubElem.setAttribute("FIX_CENTER", fixCenter->isChecked()); - subSubElem.setAttribute("TANG_DIST", tangDist->isChecked()); - // in dateiname darf kein , vorkommen - das blank ", " zur uebersich - beim einlesen wird nur "," - // genommen und blanks rundherum abgeschnitten, falls von hand editiert wurde - QStringList fl = mMainWindow->getAutoCalib()->getCalibFiles(); - for (int i = 0; i < fl.size(); ++i) - if (QFileInfo(fl.at(i)).isRelative()) - fl.replace(i, fl.at(i)+";"+QFileInfo(fl.at(i)).absoluteFilePath()); - subSubElem.setAttribute("CALIB_FILES", fl.join(", ")); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXTRINSIC_PARAMETERS"); - - subSubElem.setAttribute("EXTR_ROT_1", rot1->value()); - subSubElem.setAttribute("EXTR_ROT_2", rot2->value()); - subSubElem.setAttribute("EXTR_ROT_3", rot3->value()); - subSubElem.setAttribute("EXTR_TRANS_1", trans1->value()); - subSubElem.setAttribute("EXTR_TRANS_2", trans2->value()); - subSubElem.setAttribute("EXTR_TRANS_3", trans3->value()); - - subSubElem.setAttribute("SHOW_CALIB_POINTS", extCalibPointsShow->isChecked()); - - QString ef = mMainWindow->getExtrCalibration()->getExtrCalibFile(); - if (ef != "") - ef = getFileList(ef, mMainWindow->getProFileName()); - subSubElem.setAttribute("EXTERNAL_CALIB_FILE",ef); - - subSubElem.setAttribute("COORD_DIMENSION", coordTab->currentIndex()); - - subSubElem.setAttribute("SHOW", coordShow->isChecked()); - subSubElem.setAttribute("FIX", coordFix->isChecked()); - subSubElem.setAttribute("ROTATE", coordRotate->value()); - subSubElem.setAttribute("TRANS_X", coordTransX->value()); - subSubElem.setAttribute("TRANS_Y", coordTransY->value()); - subSubElem.setAttribute("SCALE", coordScale->value()); - subSubElem.setAttribute("ALTITUDE", coordAltitude->value()); - //subSubElem.setAttribute("ALTITUDE_MEASURED", coordAltitudeMeasured->text()); - subSubElem.setAttribute("UNIT", coordUnit->value()); - subSubElem.setAttribute("USE_INTRINSIC_CENTER", coordUseIntrinsic->isChecked()); - subSubElem.setAttribute("COORD3D_TRANS_X", coord3DTransX->value()); - subSubElem.setAttribute("COORD3D_TRANS_Y", coord3DTransY->value()); - subSubElem.setAttribute("COORD3D_TRANS_Z", coord3DTransZ->value()); - //cout << "x: " << coord3DTransX->value() << " y: " << coord3DTransY->value() << " z: " << coord3DTransZ->value() << endl; - subSubElem.setAttribute("COORD3D_AXIS_LEN", coord3DAxeLen->value()); - subSubElem.setAttribute("COORD3D_SWAP_X", coord3DSwapX->isChecked()); - subSubElem.setAttribute("COORD3D_SWAP_Y", coord3DSwapY->isChecked()); - subSubElem.setAttribute("COORD3D_SWAP_Z", coord3DSwapZ->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("ALIGNMENT_GRID"); - subSubElem.setAttribute("GRID_DIMENSION", gridTab->currentIndex()); - subSubElem.setAttribute("SHOW", gridShow->isChecked()); - subSubElem.setAttribute("FIX", gridFix->isChecked()); - subSubElem.setAttribute("ROTATE", gridRotate->value()); - subSubElem.setAttribute("TRANS_X", gridTransX->value()); - subSubElem.setAttribute("TRANS_Y", gridTransY->value()); - subSubElem.setAttribute("SCALE", gridScale->value()); - subSubElem.setAttribute("GRID3D_TRANS_X", grid3DTransX->value()); - subSubElem.setAttribute("GRID3D_TRANS_Y", grid3DTransY->value()); - subSubElem.setAttribute("GRID3D_TRANS_Z", grid3DTransZ->value()); - subSubElem.setAttribute("GRID3D_RESOLUTION", grid3DResolution->value()); - subElem.appendChild(subSubElem); - - // - - - - - - - - - - - - - - - - - - - - subElem = (elem.ownerDocument()).createElement("RECOGNITION"); - elem.appendChild(subElem); - - subSubElem = (elem.ownerDocument()).createElement("PERFORM"); - subSubElem.setAttribute("ENABLED", performRecognition->isChecked()); - subSubElem.setAttribute("METHOD", - static_cast<int>(recoMethod->itemData(recoMethod->currentIndex()).value<reco::RecognitionMethod>())); - subSubElem.setAttribute("STEP", recoStep->value()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("REGION_OF_INTEREST"); - subSubElem.setAttribute("SHOW", roiShow->isChecked()); - subSubElem.setAttribute("FIX", roiFix->isChecked()); - subSubElem.setAttribute("X", mMainWindow->getRecoRoiItem()->rect().x()); - subSubElem.setAttribute("Y", mMainWindow->getRecoRoiItem()->rect().y()); - subSubElem.setAttribute("WIDTH", mMainWindow->getRecoRoiItem()->rect().width()); - subSubElem.setAttribute("HEIGHT", mMainWindow->getRecoRoiItem()->rect().height()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("MARKER"); - subSubElem.setAttribute("BRIGHTNESS", markerBrightness->value()); - subSubElem.setAttribute("IGNORE_WITHOUT", markerIgnoreWithout->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("SIZE_COLOR"); - subSubElem.setAttribute("SHOW", recoShowColor->isChecked()); - subSubElem.setAttribute("MODEL", recoColorModel->currentIndex()); - subSubElem.setAttribute("AUTO_WB", recoAutoWB->isChecked()); - subSubElem.setAttribute("X", recoColorX->currentIndex()); - subSubElem.setAttribute("Y", recoColorY->currentIndex()); - subSubElem.setAttribute("Z", recoColorZ->value()); - subSubElem.setAttribute("GREY_LEVEL", recoGreyLevel->value()); - subSubElem.setAttribute("SYMBOL_SIZE", recoSymbolSize->value()); - - subSubElem.setAttribute("MAP_NUMBER", mapNr->value()); // MAP_MAX noetig ?: mapNr->maximum()+1 - for (int i = 0; i <= mapNr->maximum(); ++i) - { - subSubSubElem = (elem.ownerDocument()).createElement("MAP"); //QString("MAP %1").arg(i) - RectMap map = colorPlot->getMapItem()->getMap(i); - subSubSubElem.setAttribute("X", map.x()); - subSubSubElem.setAttribute("Y", map.y()); - subSubSubElem.setAttribute("WIDTH", map.width()); - subSubSubElem.setAttribute("HEIGHT", map.height()); - subSubSubElem.setAttribute("COLORED", map.colored()); - subSubSubElem.setAttribute("MAP_HEIGHT", map.mapHeight()); - subSubSubElem.setAttribute("FROM_HUE", map.fromColor().hue()); - subSubSubElem.setAttribute("FROM_SAT", map.fromColor().saturation()); - subSubSubElem.setAttribute("FROM_VAL", map.fromColor().value()); - subSubSubElem.setAttribute("TO_HUE", map.toColor().hue()); - subSubSubElem.setAttribute("TO_SAT", map.toColor().saturation()); - subSubSubElem.setAttribute("TO_VAL", map.toColor().value()); - subSubSubElem.setAttribute("INV_HUE", map.invHue()); - subSubElem.appendChild(subSubSubElem); - } - subSubElem.setAttribute("DEFAULT_HEIGHT", mapDefaultHeight->value()); + QDomElement subElem; + QDomElement subSubElem; + QDomElement subSubSubElem; + QString fn; + QString heightFile; + QString markerFile; - subElem.appendChild(subSubElem); + elem.setAttribute("TAB", tabs->currentIndex()); - subSubElem = (elem.ownerDocument()).createElement("READ_HEIGHTS"); + // - - - - - - - - - - - - - - - - - - - + subElem = (elem.ownerDocument()).createElement("CALIBRATION"); + elem.appendChild(subElem); - heightFile = mMainWindow->getHeightFileName(); - if (!heightFile.isEmpty()) { - heightFile = getFileList(heightFile, mMainWindow->getProFileName()); - } - subSubElem.setAttribute("HEIGHT_FILE", heightFile); - subElem.appendChild(subSubElem); + subSubElem = (elem.ownerDocument()).createElement("BRIGHTNESS"); + subSubElem.setAttribute("ENABLED", filterBrightContrast->isChecked()); + subSubElem.setAttribute("VALUE", filterBrightParam->value()); + subElem.appendChild(subSubElem); - subSubElem = (elem.ownerDocument()).createElement("READ_MARKER_IDS"); - markerFile = mMainWindow->getMarkerIDFileName(); - if (!markerFile.isEmpty()) { - markerFile = getFileList(markerFile, mMainWindow->getProFileName()); - } - subSubElem.setAttribute("MARKER_FILE", markerFile); - subElem.appendChild(subSubElem); + subSubElem = (elem.ownerDocument()).createElement("CONTRAST"); + subSubElem.setAttribute("ENABLED", filterBrightContrast->isChecked()); + subSubElem.setAttribute("VALUE", filterContrastParam->value()); + subElem.appendChild(subSubElem); + + BorderFilter *bf = mMainWindow->getBorderFilter(); + QColor col( + (int) bf->getBorderColR()->getValue(), + (int) bf->getBorderColG()->getValue(), + (int) bf->getBorderColB()->getValue()); + subSubElem = (elem.ownerDocument()).createElement("BORDER"); + subSubElem.setAttribute("ENABLED", filterBorder->isChecked()); + subSubElem.setAttribute("VALUE", filterBorderParamSize->value()); + subSubElem.setAttribute("COLOR", col.name()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("SWAP"); + subSubElem.setAttribute("ENABLED", filterSwap->isChecked()); + subSubElem.setAttribute("HORIZONTALLY", filterSwapH->isChecked()); + subSubElem.setAttribute("VERTICALLY", filterSwapV->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("BG_SUB"); + subSubElem.setAttribute("ENABLED", filterBg->isChecked()); + subSubElem.setAttribute("UPDATE", filterBgUpdate->isChecked()); + subSubElem.setAttribute("SHOW", filterBgShow->isChecked()); + fn = mMainWindow->getBackgroundFilter()->getFilename(); + if(fn != "") + fn = getFileList(fn, mMainWindow->getProFileName()); + subSubElem.setAttribute("FILE", fn); + subSubElem.setAttribute("DELETE", filterBgDeleteTrj->isChecked()); + subSubElem.setAttribute("DELETE_NUMBER", filterBgDeleteNumber->value()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("PATTERN"); + subSubElem.setAttribute("BOARD_SIZE_X", mMainWindow->getAutoCalib()->getBoardSizeX()); // 6 + subSubElem.setAttribute("BOARD_SIZE_Y", mMainWindow->getAutoCalib()->getBoardSizeY()); // 8 oder 9 + subSubElem.setAttribute("SQUARE_SIZE", mMainWindow->getAutoCalib()->getSquareSize()); // in cm + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("INTRINSIC_PARAMETERS"); + subSubElem.setAttribute("ENABLED", apply->isChecked()); + subSubElem.setAttribute("FX", fx->value()); + subSubElem.setAttribute("FY", fy->value()); + subSubElem.setAttribute("CX", cx->value()); + subSubElem.setAttribute("CY", cy->value()); + subSubElem.setAttribute("R2", r2->value()); + subSubElem.setAttribute("R4", r4->value()); + subSubElem.setAttribute("R6", r6->value()); + subSubElem.setAttribute("TX", tx->value()); + subSubElem.setAttribute("TY", ty->value()); + subSubElem.setAttribute("K4", k4->value()); + subSubElem.setAttribute("K5", k5->value()); + subSubElem.setAttribute("K6", k6->value()); + subSubElem.setAttribute("QUAD_ASPECT_RATIO", quadAspectRatio->isChecked()); + subSubElem.setAttribute("FIX_CENTER", fixCenter->isChecked()); + subSubElem.setAttribute("TANG_DIST", tangDist->isChecked()); + // in dateiname darf kein , vorkommen - das blank ", " zur uebersich - beim einlesen wird nur "," + // genommen und blanks rundherum abgeschnitten, falls von hand editiert wurde + QStringList fl = mMainWindow->getAutoCalib()->getCalibFiles(); + for(int i = 0; i < fl.size(); ++i) + if(QFileInfo(fl.at(i)).isRelative()) + fl.replace(i, fl.at(i) + ";" + QFileInfo(fl.at(i)).absoluteFilePath()); + subSubElem.setAttribute("CALIB_FILES", fl.join(", ")); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXTRINSIC_PARAMETERS"); + + subSubElem.setAttribute("EXTR_ROT_1", rot1->value()); + subSubElem.setAttribute("EXTR_ROT_2", rot2->value()); + subSubElem.setAttribute("EXTR_ROT_3", rot3->value()); + subSubElem.setAttribute("EXTR_TRANS_1", trans1->value()); + subSubElem.setAttribute("EXTR_TRANS_2", trans2->value()); + subSubElem.setAttribute("EXTR_TRANS_3", trans3->value()); + + subSubElem.setAttribute("SHOW_CALIB_POINTS", extCalibPointsShow->isChecked()); + + QString ef = mMainWindow->getExtrCalibration()->getExtrCalibFile(); + if(ef != "") + ef = getFileList(ef, mMainWindow->getProFileName()); + subSubElem.setAttribute("EXTERNAL_CALIB_FILE", ef); + + subSubElem.setAttribute("COORD_DIMENSION", coordTab->currentIndex()); + + subSubElem.setAttribute("SHOW", coordShow->isChecked()); + subSubElem.setAttribute("FIX", coordFix->isChecked()); + subSubElem.setAttribute("ROTATE", coordRotate->value()); + subSubElem.setAttribute("TRANS_X", coordTransX->value()); + subSubElem.setAttribute("TRANS_Y", coordTransY->value()); + subSubElem.setAttribute("SCALE", coordScale->value()); + subSubElem.setAttribute("ALTITUDE", coordAltitude->value()); + subSubElem.setAttribute("UNIT", coordUnit->value()); + subSubElem.setAttribute("USE_INTRINSIC_CENTER", coordUseIntrinsic->isChecked()); + subSubElem.setAttribute("COORD3D_TRANS_X", coord3DTransX->value()); + subSubElem.setAttribute("COORD3D_TRANS_Y", coord3DTransY->value()); + subSubElem.setAttribute("COORD3D_TRANS_Z", coord3DTransZ->value()); + subSubElem.setAttribute("COORD3D_AXIS_LEN", coord3DAxeLen->value()); + subSubElem.setAttribute("COORD3D_SWAP_X", coord3DSwapX->isChecked()); + subSubElem.setAttribute("COORD3D_SWAP_Y", coord3DSwapY->isChecked()); + subSubElem.setAttribute("COORD3D_SWAP_Z", coord3DSwapZ->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("ALIGNMENT_GRID"); + subSubElem.setAttribute("GRID_DIMENSION", gridTab->currentIndex()); + subSubElem.setAttribute("SHOW", gridShow->isChecked()); + subSubElem.setAttribute("FIX", gridFix->isChecked()); + subSubElem.setAttribute("ROTATE", gridRotate->value()); + subSubElem.setAttribute("TRANS_X", gridTransX->value()); + subSubElem.setAttribute("TRANS_Y", gridTransY->value()); + subSubElem.setAttribute("SCALE", gridScale->value()); + subSubElem.setAttribute("GRID3D_TRANS_X", grid3DTransX->value()); + subSubElem.setAttribute("GRID3D_TRANS_Y", grid3DTransY->value()); + subSubElem.setAttribute("GRID3D_TRANS_Z", grid3DTransZ->value()); + subSubElem.setAttribute("GRID3D_RESOLUTION", grid3DResolution->value()); + subElem.appendChild(subSubElem); + + // - - - - - - - - - - - - - - - - - - - + subElem = (elem.ownerDocument()).createElement("RECOGNITION"); + elem.appendChild(subElem); + + subSubElem = (elem.ownerDocument()).createElement("PERFORM"); + subSubElem.setAttribute("ENABLED", performRecognition->isChecked()); + subSubElem.setAttribute( + "METHOD", static_cast<int>(recoMethod->itemData(recoMethod->currentIndex()).value<reco::RecognitionMethod>())); + subSubElem.setAttribute("STEP", recoStep->value()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("REGION_OF_INTEREST"); + subSubElem.setAttribute("SHOW", roiShow->isChecked()); + subSubElem.setAttribute("FIX", roiFix->isChecked()); + subSubElem.setAttribute("X", mMainWindow->getRecoRoiItem()->rect().x()); + subSubElem.setAttribute("Y", mMainWindow->getRecoRoiItem()->rect().y()); + subSubElem.setAttribute("WIDTH", mMainWindow->getRecoRoiItem()->rect().width()); + subSubElem.setAttribute("HEIGHT", mMainWindow->getRecoRoiItem()->rect().height()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("MARKER"); + subSubElem.setAttribute("BRIGHTNESS", markerBrightness->value()); + subSubElem.setAttribute("IGNORE_WITHOUT", markerIgnoreWithout->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("SIZE_COLOR"); + subSubElem.setAttribute("SHOW", recoShowColor->isChecked()); + subSubElem.setAttribute("MODEL", recoColorModel->currentIndex()); + subSubElem.setAttribute("AUTO_WB", recoAutoWB->isChecked()); + subSubElem.setAttribute("X", recoColorX->currentIndex()); + subSubElem.setAttribute("Y", recoColorY->currentIndex()); + subSubElem.setAttribute("Z", recoColorZ->value()); + subSubElem.setAttribute("GREY_LEVEL", recoGreyLevel->value()); + subSubElem.setAttribute("SYMBOL_SIZE", recoSymbolSize->value()); + + subSubElem.setAttribute("MAP_NUMBER", mapNr->value()); // MAP_MAX noetig ?: mapNr->maximum()+1 + for(int i = 0; i <= mapNr->maximum(); ++i) + { + subSubSubElem = (elem.ownerDocument()).createElement("MAP"); // QString("MAP %1").arg(i) + RectMap map = colorPlot->getMapItem()->getMap(i); + subSubSubElem.setAttribute("X", map.x()); + subSubSubElem.setAttribute("Y", map.y()); + subSubSubElem.setAttribute("WIDTH", map.width()); + subSubSubElem.setAttribute("HEIGHT", map.height()); + subSubSubElem.setAttribute("COLORED", map.colored()); + subSubSubElem.setAttribute("MAP_HEIGHT", map.mapHeight()); + subSubSubElem.setAttribute("FROM_HUE", map.fromColor().hue()); + subSubSubElem.setAttribute("FROM_SAT", map.fromColor().saturation()); + subSubSubElem.setAttribute("FROM_VAL", map.fromColor().value()); + subSubSubElem.setAttribute("TO_HUE", map.toColor().hue()); + subSubSubElem.setAttribute("TO_SAT", map.toColor().saturation()); + subSubSubElem.setAttribute("TO_VAL", map.toColor().value()); + subSubSubElem.setAttribute("INV_HUE", map.invHue()); + subSubElem.appendChild(subSubSubElem); + } + subSubElem.setAttribute("DEFAULT_HEIGHT", mapDefaultHeight->value()); + + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("READ_HEIGHTS"); + + heightFile = mMainWindow->getHeightFileName(); + if(!heightFile.isEmpty()) + { + heightFile = getFileList(heightFile, mMainWindow->getProFileName()); + } + subSubElem.setAttribute("HEIGHT_FILE", heightFile); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("READ_MARKER_IDS"); + markerFile = mMainWindow->getMarkerIDFileName(); + if(!markerFile.isEmpty()) + { + markerFile = getFileList(markerFile, mMainWindow->getProFileName()); + } + subSubElem.setAttribute("MARKER_FILE", markerFile); + subElem.appendChild(subSubElem); + + // - - - - - - - - - - - - - - - - - - - + subElem = (elem.ownerDocument()).createElement("TRACKING"); + elem.appendChild(subElem); + + subSubElem = (elem.ownerDocument()).createElement("ONLINE_CALCULATION"); + subSubElem.setAttribute("ENABLED", trackOnlineCalc->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("REPEAT_BELOW"); + subSubElem.setAttribute("ENABLED", trackRepeat->isChecked()); + subSubElem.setAttribute("QUALITY", trackRepeatQual->value()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXTRAPOLATION"); + subSubElem.setAttribute("ENABLED", trackExtrapolation->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("MERGE"); + subSubElem.setAttribute("ENABLED", trackMerge->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("ONLY_VISIBLE"); + subSubElem.setAttribute("ENABLED", trackOnlySelected->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("REGION_OF_INTEREST"); + subSubElem.setAttribute("SHOW", trackRoiShow->isChecked()); + subSubElem.setAttribute("FIX", trackRoiFix->isChecked()); + subSubElem.setAttribute("X", mMainWindow->getTrackRoiItem()->rect().x()); + subSubElem.setAttribute("Y", mMainWindow->getTrackRoiItem()->rect().y()); + subSubElem.setAttribute("WIDTH", mMainWindow->getTrackRoiItem()->rect().width()); + subSubElem.setAttribute("HEIGHT", mMainWindow->getTrackRoiItem()->rect().height()); + subElem.appendChild(subSubElem); + + // export options + subSubElem = (elem.ownerDocument()).createElement("SEARCH_MISSING_FRAMES"); + subSubElem.setAttribute("ENABLED", trackMissingFrames->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("RECALCULATE_MEDIAN_HEIGHT"); + subSubElem.setAttribute("ENABLED", trackRecalcHeight->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("ALLOW_ALTERNATE_HEIGHT"); + subSubElem.setAttribute("ENABLED", trackAlternateHeight->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXPORT_ELIMINATE_TRACKPOINT_WITHOUT_HEIGHT"); + subSubElem.setAttribute("ENABLED", exportElimTp->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXPORT_ELIMINATE_TRAJECTORY_WITHOUT_HEIGHT"); + subSubElem.setAttribute("ENABLED", exportElimTrj->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXPORT_SMOOTH"); + subSubElem.setAttribute("ENABLED", exportSmooth->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXPORT_VIEWING_DIRECTION"); + subSubElem.setAttribute("ENABLED", exportViewDir->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXPORT_ANGLE_OF_VIEW"); + subSubElem.setAttribute("ENABLED", exportAngleOfView->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXPORT_USE_METER"); + subSubElem.setAttribute("ENABLED", exportUseM->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXPORT_COMMENT"); + subSubElem.setAttribute("ENABLED", exportComment->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("EXPORT_MARKERID"); + subSubElem.setAttribute("ENABLED", exportMarkerID->isChecked()); + subElem.appendChild(subSubElem); + + + subSubElem = (elem.ownerDocument()).createElement("TEST_EQUAL"); + subSubElem.setAttribute("ENABLED", testEqual->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("TEST_VELOCITY"); + subSubElem.setAttribute("ENABLED", testVelocity->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("TEST_INSIDE"); + subSubElem.setAttribute("ENABLED", testInside->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("TEST_LENGTH"); + subSubElem.setAttribute("ENABLED", testLength->isChecked()); + subElem.appendChild(subSubElem); + + + subSubElem = (elem.ownerDocument()).createElement("TRACK_FILE"); + fn = mMainWindow->getTrackFileName(); + if(fn != "") + fn = getFileList(fn, mMainWindow->getProFileName()); + subSubElem.setAttribute("FILENAME", fn); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("SEARCH_REGION"); + subSubElem.setAttribute("SCALE", trackRegionScale->value()); + subSubElem.setAttribute("LEVELS", trackRegionLevels->value()); + subSubElem.setAttribute("MAX_ERROR", trackErrorExponent->value()); + subSubElem.setAttribute("SHOW", trackShowSearchSize->isChecked()); + subSubElem.setAttribute("ADAPTIVE", adaptiveLevel->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("PATH"); + subSubElem.setAttribute("SHOW", trackShow->isChecked()); + subSubElem.setAttribute("FIX", trackFix->isChecked()); + + subSubElem.setAttribute("ONLY_VISIBLE", trackShowOnlyVisible->isChecked()); + subSubElem.setAttribute("ONLY_PEOPLE", trackShowOnly->isChecked()); + subSubElem.setAttribute("ONLY_PEOPLE_LIST", trackShowOnlyList->isChecked()); + subSubElem.setAttribute("ONLY_PEOPLE_NR", trackShowOnlyNr->value()); + subSubElem.setAttribute("ONLY_PEOPLE_NR_LIST", trackShowOnlyNr->text()); + + subSubElem.setAttribute("SHOW_CURRENT_POINT", trackShowCurrentPoint->isChecked()); + subSubElem.setAttribute("SHOW_POINTS", trackShowPoints->isChecked()); + subSubElem.setAttribute("SHOW_PATH", trackShowPath->isChecked()); + subSubElem.setAttribute("SHOW_COLLECTIVE_COLOR", trackShowColColor->isChecked()); + subSubElem.setAttribute("SHOW_COLOR_MARKER", trackShowColorMarker->isChecked()); + subSubElem.setAttribute("SHOW_NUMBER", trackShowNumber->isChecked()); + subSubElem.setAttribute("SHOW_GROUND_POSITION", trackShowGroundPosition->isChecked()); + subSubElem.setAttribute("SHOW_GROUND_PATH", trackShowGroundPath->isChecked()); + + subSubElem.setAttribute("TRACK_GROUND_PATH_COLOR", getTrackGroundPathColor().name()); + subSubElem.setAttribute("TRACK_PATH_COLOR", getTrackPathColor().name()); + subSubElem.setAttribute("CURRENT_POINT_SIZE", trackCurrentPointSize->value()); + subSubElem.setAttribute("POINTS_SIZE", trackPointSize->value()); + subSubElem.setAttribute("PATH_SIZE", trackPathWidth->value()); + subSubElem.setAttribute("COLLECTIVE_COLOR_SIZE", trackColColorSize->value()); + subSubElem.setAttribute("COLOR_MARKER_SIZE", trackColorMarkerSize->value()); + subSubElem.setAttribute("NUMBER_SIZE", trackNumberSize->value()); + subSubElem.setAttribute("GROUND_POSITION_SIZE", trackGroundPositionSize->value()); + subSubElem.setAttribute("GROUND_PATH_SIZE", trackGroundPathSize->value()); + + subSubElem.setAttribute("HEAD_SIZE", trackHeadSized->isChecked()); + subSubElem.setAttribute("POINTS_COLORED", trackShowPointsColored->isChecked()); + subSubElem.setAttribute("NUMBER_BOLD", trackNumberBold->isChecked()); + + subSubElem.setAttribute("BEFORE", trackShowBefore->value()); + subSubElem.setAttribute("AFTER", trackShowAfter->value()); + + subElem.appendChild(subSubElem); // - - - - - - - - - - - - - - - - - - - - subElem = (elem.ownerDocument()).createElement("TRACKING"); - elem.appendChild(subElem); - - subSubElem = (elem.ownerDocument()).createElement("ONLINE_CALCULATION"); - subSubElem.setAttribute("ENABLED", trackOnlineCalc->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("REPEAT_BELOW"); - subSubElem.setAttribute("ENABLED", trackRepeat->isChecked()); - subSubElem.setAttribute("QUALITY", trackRepeatQual->value()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXTRAPOLATION"); - subSubElem.setAttribute("ENABLED", trackExtrapolation->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("MERGE"); - subSubElem.setAttribute("ENABLED", trackMerge->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("ONLY_VISIBLE"); - subSubElem.setAttribute("ENABLED", trackOnlySelected->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("REGION_OF_INTEREST"); - subSubElem.setAttribute("SHOW", trackRoiShow->isChecked()); - subSubElem.setAttribute("FIX", trackRoiFix->isChecked()); - subSubElem.setAttribute("X", mMainWindow->getTrackRoiItem()->rect().x()); - subSubElem.setAttribute("Y", mMainWindow->getTrackRoiItem()->rect().y()); - subSubElem.setAttribute("WIDTH", mMainWindow->getTrackRoiItem()->rect().width()); - subSubElem.setAttribute("HEIGHT", mMainWindow->getTrackRoiItem()->rect().height()); - subElem.appendChild(subSubElem); - - // export options - subSubElem = (elem.ownerDocument()).createElement("SEARCH_MISSING_FRAMES"); - subSubElem.setAttribute("ENABLED", trackMissingFrames->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("RECALCULATE_MEDIAN_HEIGHT"); - subSubElem.setAttribute("ENABLED", trackRecalcHeight->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("ALLOW_ALTERNATE_HEIGHT"); - subSubElem.setAttribute("ENABLED", trackAlternateHeight->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXPORT_ELIMINATE_TRACKPOINT_WITHOUT_HEIGHT"); - subSubElem.setAttribute("ENABLED", exportElimTp->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXPORT_ELIMINATE_TRAJECTORY_WITHOUT_HEIGHT"); - subSubElem.setAttribute("ENABLED", exportElimTrj->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXPORT_SMOOTH"); - subSubElem.setAttribute("ENABLED", exportSmooth->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXPORT_VIEWING_DIRECTION"); - subSubElem.setAttribute("ENABLED", exportViewDir->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXPORT_ANGLE_OF_VIEW"); - subSubElem.setAttribute("ENABLED", exportAngleOfView->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXPORT_USE_METER"); - subSubElem.setAttribute("ENABLED", exportUseM->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXPORT_COMMENT"); - subSubElem.setAttribute("ENABLED", exportComment->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("EXPORT_MARKERID"); - subSubElem.setAttribute("ENABLED", exportMarkerID->isChecked()); - subElem.appendChild(subSubElem); - - - subSubElem = (elem.ownerDocument()).createElement("TEST_EQUAL"); - subSubElem.setAttribute("ENABLED", testEqual->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("TEST_VELOCITY"); - subSubElem.setAttribute("ENABLED", testVelocity->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("TEST_INSIDE"); - subSubElem.setAttribute("ENABLED", testInside->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("TEST_LENGTH"); - subSubElem.setAttribute("ENABLED", testLength->isChecked()); - subElem.appendChild(subSubElem); - - - subSubElem = (elem.ownerDocument()).createElement("TRACK_FILE"); - fn = mMainWindow->getTrackFileName(); - if (fn != "") - fn = getFileList(fn, mMainWindow->getProFileName()); -// if ((fn != "") && (QFileInfo(fn).isRelative())) -// fn = fn+";"+QFileInfo(fn).absoluteFilePath(); - subSubElem.setAttribute("FILENAME", fn); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("SEARCH_REGION"); - subSubElem.setAttribute("SCALE", trackRegionScale->value()); - subSubElem.setAttribute("LEVELS", trackRegionLevels->value()); - subSubElem.setAttribute("MAX_ERROR", trackErrorExponent->value()); - subSubElem.setAttribute("SHOW", trackShowSearchSize->isChecked()); - subSubElem.setAttribute("ADAPTIVE", adaptiveLevel->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("PATH"); - subSubElem.setAttribute("SHOW", trackShow->isChecked()); - subSubElem.setAttribute("FIX", trackFix->isChecked()); - - subSubElem.setAttribute("ONLY_VISIBLE", trackShowOnlyVisible->isChecked()); - subSubElem.setAttribute("ONLY_PEOPLE", trackShowOnly->isChecked()); - subSubElem.setAttribute("ONLY_PEOPLE_LIST", trackShowOnlyList->isChecked()); - subSubElem.setAttribute("ONLY_PEOPLE_NR", trackShowOnlyNr->value()); - subSubElem.setAttribute("ONLY_PEOPLE_NR_LIST", trackShowOnlyNr->text()); - - subSubElem.setAttribute("SHOW_CURRENT_POINT", trackShowCurrentPoint->isChecked()); - subSubElem.setAttribute("SHOW_POINTS", trackShowPoints->isChecked()); - subSubElem.setAttribute("SHOW_PATH", trackShowPath->isChecked()); - subSubElem.setAttribute("SHOW_COLLECTIVE_COLOR", trackShowColColor->isChecked()); - subSubElem.setAttribute("SHOW_COLOR_MARKER", trackShowColorMarker->isChecked()); - subSubElem.setAttribute("SHOW_NUMBER", trackShowNumber->isChecked()); - subSubElem.setAttribute("SHOW_GROUND_POSITION", trackShowGroundPosition->isChecked()); - subSubElem.setAttribute("SHOW_GROUND_PATH", trackShowGroundPath->isChecked()); - - subSubElem.setAttribute("TRACK_GROUND_PATH_COLOR", getTrackGroundPathColor().name()); - subSubElem.setAttribute("TRACK_PATH_COLOR", getTrackPathColor().name()); - subSubElem.setAttribute("CURRENT_POINT_SIZE", trackCurrentPointSize->value()); - subSubElem.setAttribute("POINTS_SIZE", trackPointSize->value()); - subSubElem.setAttribute("PATH_SIZE", trackPathWidth->value()); - subSubElem.setAttribute("COLLECTIVE_COLOR_SIZE", trackColColorSize->value()); - subSubElem.setAttribute("COLOR_MARKER_SIZE", trackColorMarkerSize->value()); - subSubElem.setAttribute("NUMBER_SIZE", trackNumberSize->value()); - subSubElem.setAttribute("GROUND_POSITION_SIZE", trackGroundPositionSize->value()); - subSubElem.setAttribute("GROUND_PATH_SIZE", trackGroundPathSize->value()); - - subSubElem.setAttribute("HEAD_SIZE", trackHeadSized->isChecked()); - subSubElem.setAttribute("POINTS_COLORED", trackShowPointsColored->isChecked()); - subSubElem.setAttribute("NUMBER_BOLD", trackNumberBold->isChecked()); - - subSubElem.setAttribute("BEFORE", trackShowBefore->value()); - subSubElem.setAttribute("AFTER", trackShowAfter->value()); - - subElem.appendChild(subSubElem); - - // - - - - - - - - - - - - - - - - - - - - subElem = (elem.ownerDocument()).createElement("ANALYSIS"); - elem.appendChild(subElem); - - subSubElem = (elem.ownerDocument()).createElement("SEARCH_MISSING_FRAMES"); - subSubElem.setAttribute("ENABLED", anaMissingFrames->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("MARK_ACTUAL"); - subSubElem.setAttribute("ENABLED", anaMarkAct->isChecked()); - subElem.appendChild(subSubElem); - - subSubElem = (elem.ownerDocument()).createElement("CALCULATION"); - subSubElem.setAttribute("STEP_SIZE", anaStep->value()); - subSubElem.setAttribute("CONSIDER_X", anaConsiderX->isChecked()); - subSubElem.setAttribute("CONSIDER_Y", anaConsiderY->isChecked()); - subSubElem.setAttribute("ABSOLUTE", anaConsiderAbs->isChecked()); - subSubElem.setAttribute("REVERSE", anaConsiderRev->isChecked()); - subSubElem.setAttribute("SHOW_VORONOI", showVoronoiCells->isChecked()); - subElem.appendChild(subSubElem); + subElem = (elem.ownerDocument()).createElement("ANALYSIS"); + elem.appendChild(subElem); + + subSubElem = (elem.ownerDocument()).createElement("SEARCH_MISSING_FRAMES"); + subSubElem.setAttribute("ENABLED", anaMissingFrames->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("MARK_ACTUAL"); + subSubElem.setAttribute("ENABLED", anaMarkAct->isChecked()); + subElem.appendChild(subSubElem); + + subSubElem = (elem.ownerDocument()).createElement("CALCULATION"); + subSubElem.setAttribute("STEP_SIZE", anaStep->value()); + subSubElem.setAttribute("CONSIDER_X", anaConsiderX->isChecked()); + subSubElem.setAttribute("CONSIDER_Y", anaConsiderY->isChecked()); + subSubElem.setAttribute("ABSOLUTE", anaConsiderAbs->isChecked()); + subSubElem.setAttribute("REVERSE", anaConsiderRev->isChecked()); + subSubElem.setAttribute("SHOW_VORONOI", showVoronoiCells->isChecked()); + subElem.appendChild(subSubElem); } // read data from xml node @@ -2787,342 +2837,362 @@ void Control::getXml(QDomElement &elem) { QDomElement subElem, subSubElem, subSubSubElem; - if (elem.hasAttribute("TAB")) + if(elem.hasAttribute("TAB")) tabs->setCurrentIndex(elem.attribute("TAB").toInt()); for(subElem = elem.firstChildElement(); !subElem.isNull(); subElem = subElem.nextSiblingElement()) - if (subElem.tagName() == "CALIBRATION") + if(subElem.tagName() == "CALIBRATION") { - for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); subSubElem = subSubElem.nextSiblingElement()) - if (subSubElem.tagName() == "BRIGHTNESS") + for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); + subSubElem = subSubElem.nextSiblingElement()) + if(subSubElem.tagName() == "BRIGHTNESS") { - if (subSubElem.hasAttribute("ENABLED")) - filterBrightContrast->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("VALUE")) + if(subSubElem.hasAttribute("ENABLED")) + filterBrightContrast->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("VALUE")) filterBrightParam->setValue(subSubElem.attribute("VALUE").toInt()); } - else if (subSubElem.tagName() == "CONTRAST") + else if(subSubElem.tagName() == "CONTRAST") { - if (subSubElem.hasAttribute("ENABLED")) - filterBrightContrast->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + filterBrightContrast->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); //,mMainWindow->getContrastFilter()->getEnabled() ? "1" : "0" //Qt::Unchecked - if (subSubElem.hasAttribute("VALUE")) + if(subSubElem.hasAttribute("VALUE")) filterContrastParam->setValue(subSubElem.attribute("VALUE").toInt()); } - else if (subSubElem.tagName() == "BORDER") + else if(subSubElem.tagName() == "BORDER") { - if (subSubElem.hasAttribute("ENABLED")) - filterBorder->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("VALUE")) + if(subSubElem.hasAttribute("ENABLED")) + filterBorder->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("VALUE")) filterBorderParamSize->setValue(subSubElem.attribute("VALUE").toInt()); - if (subSubElem.hasAttribute("COLOR")) + if(subSubElem.hasAttribute("COLOR")) { QColor color(subSubElem.attribute("COLOR")); mMainWindow->getBorderFilter()->getBorderColR()->setValue(color.red()); mMainWindow->getBorderFilter()->getBorderColG()->setValue(color.green()); mMainWindow->getBorderFilter()->getBorderColB()->setValue(color.blue()); - // mMainWindow->updateImage(); auskommentiert, da noch andere werte sehr wahrscheinlich mitgeladen werden } } - else if (subSubElem.tagName() == "SWAP") + else if(subSubElem.tagName() == "SWAP") { - if (subSubElem.hasAttribute("ENABLED")) - filterSwap->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("HORIZONTALLY")) - filterSwapH->setCheckState(subSubElem.attribute("HORIZONTALLY").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("VERTICALLY")) - filterSwapV->setCheckState(subSubElem.attribute("VERTICALLY").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + filterSwap->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("HORIZONTALLY")) + filterSwapH->setCheckState( + subSubElem.attribute("HORIZONTALLY").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("VERTICALLY")) + filterSwapV->setCheckState( + subSubElem.attribute("VERTICALLY").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "BG_SUB") + else if(subSubElem.tagName() == "BG_SUB") { - if (subSubElem.hasAttribute("ENABLED")) + if(subSubElem.hasAttribute("ENABLED")) filterBg->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("UPDATE")) - filterBgUpdate->setCheckState(subSubElem.attribute("UPDATE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW")) + if(subSubElem.hasAttribute("UPDATE")) + filterBgUpdate->setCheckState( + subSubElem.attribute("UPDATE").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW")) filterBgShow->setCheckState(subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("FILE")) + if(subSubElem.hasAttribute("FILE")) { QString f = subSubElem.attribute("FILE"); - if (f != "") + if(f != "") { - if (getExistingFile(f, mMainWindow->getProFileName()) != "") + if(getExistingFile(f, mMainWindow->getProFileName()) != "") { -// if (!(mMainWindow->getBackgroundFilter()->load(getExistingFile(subSubElem.attribute("FILE"))))); -// debout << "Warning: Background subtracting file import error!" << endl; - mMainWindow->getBackgroundFilter()->setFilename(getExistingFile(subSubElem.attribute("FILE"), mMainWindow->getProFileName())); + mMainWindow->getBackgroundFilter()->setFilename( + getExistingFile(subSubElem.attribute("FILE"), mMainWindow->getProFileName())); } else debout << "Warning: Background subtracting file not readable!" << std::endl; } } - if (subSubElem.hasAttribute("DELETE")) - filterBgDeleteTrj->setCheckState(subSubElem.attribute("DELETE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("DELETE_NUMBER")) + if(subSubElem.hasAttribute("DELETE")) + filterBgDeleteTrj->setCheckState( + subSubElem.attribute("DELETE").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("DELETE_NUMBER")) filterBgDeleteNumber->setValue(subSubElem.attribute("DELETE_NUMBER").toInt()); } - else if (subSubElem.tagName() == "PATTERN") + else if(subSubElem.tagName() == "PATTERN") { - if (subSubElem.hasAttribute("BOARD_SIZE_X")) - mMainWindow->getAutoCalib()->setBoardSizeX(subSubElem.attribute("BOARD_SIZE_X").toInt());// 6 - if (subSubElem.hasAttribute("BOARD_SIZE_Y")) - mMainWindow->getAutoCalib()->setBoardSizeY(subSubElem.attribute("BOARD_SIZE_Y").toInt()); // 8 oder 9 - if (subSubElem.hasAttribute("SQUARE_SIZE")) - mMainWindow->getAutoCalib()->setSquareSize(subSubElem.attribute("SQUARE_SIZE").toDouble()); // in cm + if(subSubElem.hasAttribute("BOARD_SIZE_X")) + mMainWindow->getAutoCalib()->setBoardSizeX(subSubElem.attribute("BOARD_SIZE_X").toInt()); // 6 + if(subSubElem.hasAttribute("BOARD_SIZE_Y")) + mMainWindow->getAutoCalib()->setBoardSizeY( + subSubElem.attribute("BOARD_SIZE_Y").toInt()); // 8 oder 9 + if(subSubElem.hasAttribute("SQUARE_SIZE")) + mMainWindow->getAutoCalib()->setSquareSize( + subSubElem.attribute("SQUARE_SIZE").toDouble()); // in cm } - else if (subSubElem.tagName() == "INTRINSIC_PARAMETERS") + else if(subSubElem.tagName() == "INTRINSIC_PARAMETERS") { - if (subSubElem.hasAttribute("ENABLED")) + if(subSubElem.hasAttribute("ENABLED")) apply->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("FX")) + if(subSubElem.hasAttribute("FX")) fx->setValue(subSubElem.attribute("FX").toDouble()); - if (subSubElem.hasAttribute("FY")) + if(subSubElem.hasAttribute("FY")) fy->setValue(subSubElem.attribute("FY").toDouble()); - if (subSubElem.hasAttribute("CX")) + if(subSubElem.hasAttribute("CX")) { double cx_val = subSubElem.attribute("CX").toDouble(); - if( cx_val < cx->minimum() ) - cx->setMinimum(cx_val-50); - if( cx_val > cx->maximum() ) - cx->setMaximum(cx_val+50); + if(cx_val < cx->minimum()) + cx->setMinimum(cx_val - 50); + if(cx_val > cx->maximum()) + cx->setMaximum(cx_val + 50); cx->setValue(cx_val); } - if (subSubElem.hasAttribute("CY")) + if(subSubElem.hasAttribute("CY")) { double cy_val = subSubElem.attribute("CY").toDouble(); - if( cy_val < cy->minimum() ) - cy->setMinimum(cy_val-50); - if( cy_val > cy->maximum() ) - cy->setMaximum(cy_val+50); + if(cy_val < cy->minimum()) + cy->setMinimum(cy_val - 50); + if(cy_val > cy->maximum()) + cy->setMaximum(cy_val + 50); cy->setValue(cy_val); } - if (subSubElem.hasAttribute("R2")) + if(subSubElem.hasAttribute("R2")) r2->setValue(subSubElem.attribute("R2").toDouble()); - if (subSubElem.hasAttribute("R4")) + if(subSubElem.hasAttribute("R4")) r4->setValue(subSubElem.attribute("R4").toDouble()); - if (subSubElem.hasAttribute("R6")) + if(subSubElem.hasAttribute("R6")) r6->setValue(subSubElem.attribute("R6").toDouble()); - if (subSubElem.hasAttribute("TX")) + if(subSubElem.hasAttribute("TX")) tx->setValue(subSubElem.attribute("TX").toDouble()); - if (subSubElem.hasAttribute("TY")) + if(subSubElem.hasAttribute("TY")) ty->setValue(subSubElem.attribute("TY").toDouble()); - if (subSubElem.hasAttribute("K4")) + if(subSubElem.hasAttribute("K4")) k4->setValue(subSubElem.attribute("K4").toDouble()); - if (subSubElem.hasAttribute("K5")) + if(subSubElem.hasAttribute("K5")) k5->setValue(subSubElem.attribute("K5").toDouble()); - if (subSubElem.hasAttribute("K6")) + if(subSubElem.hasAttribute("K6")) k6->setValue(subSubElem.attribute("K6").toDouble()); - if (subSubElem.hasAttribute("QUAD_ASPECT_RATIO")) - quadAspectRatio->setCheckState(subSubElem.attribute("QUAD_ASPECT_RATIO").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("FIX_CENTER")) - fixCenter->setCheckState(subSubElem.attribute("FIX_CENTER").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("TANG_DIST")) - tangDist->setCheckState(subSubElem.attribute("TANG_DIST").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("CALIB_FILES")) + if(subSubElem.hasAttribute("QUAD_ASPECT_RATIO")) + quadAspectRatio->setCheckState( + subSubElem.attribute("QUAD_ASPECT_RATIO").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("FIX_CENTER")) + fixCenter->setCheckState( + subSubElem.attribute("FIX_CENTER").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("TANG_DIST")) + tangDist->setCheckState( + subSubElem.attribute("TANG_DIST").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("CALIB_FILES")) { QStringList fl = (subSubElem.attribute("CALIB_FILES")).split(","); - QString tmpStr; - for (int i = 0; i < fl.size(); ++i) - if ((fl[i] = fl[i].trimmed()) == "") + QString tmpStr; + for(int i = 0; i < fl.size(); ++i) + if((fl[i] = fl[i].trimmed()) == "") fl.removeAt(i); else { tmpStr = getExistingFile(fl[i], mMainWindow->getProFileName()); - if (tmpStr != "") + if(tmpStr != "") fl[i] = tmpStr; } -// foreach (QString f, fl) { //new keyword from QT, but must be slower!!! -// if (str.contains("Bill")) -// result += str; -// } // auch setzen, wenn leer, vielleicht ist das ja gewuenscht mMainWindow->getAutoCalib()->setCalibFiles(fl); - if (!fl.isEmpty()) + if(!fl.isEmpty()) autoCalib->setEnabled(true); } } - else if (subSubElem.tagName() == "EXTRINSIC_PARAMETERS") + else if(subSubElem.tagName() == "EXTRINSIC_PARAMETERS") { - if (subSubElem.hasAttribute("EXTR_ROT_1")) + if(subSubElem.hasAttribute("EXTR_ROT_1")) rot1->setValue(subSubElem.attribute("EXTR_ROT_1").toDouble()); - if (subSubElem.hasAttribute("EXTR_ROT_2")) + if(subSubElem.hasAttribute("EXTR_ROT_2")) rot2->setValue(subSubElem.attribute("EXTR_ROT_2").toDouble()); - if (subSubElem.hasAttribute("EXTR_ROT_3")) + if(subSubElem.hasAttribute("EXTR_ROT_3")) rot3->setValue(subSubElem.attribute("EXTR_ROT_3").toDouble()); - if (subSubElem.hasAttribute("EXTR_TRANS_1")) + if(subSubElem.hasAttribute("EXTR_TRANS_1")) trans1->setValue(subSubElem.attribute("EXTR_TRANS_1").toDouble()); - if (subSubElem.hasAttribute("EXTR_TRANS_2")) + if(subSubElem.hasAttribute("EXTR_TRANS_2")) trans2->setValue(subSubElem.attribute("EXTR_TRANS_2").toDouble()); - if (subSubElem.hasAttribute("EXTR_TRANS_3")) + if(subSubElem.hasAttribute("EXTR_TRANS_3")) trans3->setValue(subSubElem.attribute("EXTR_TRANS_3").toDouble()); - if (subSubElem.hasAttribute("SHOW_CALIB_POINTS")) - extCalibPointsShow->setCheckState(subSubElem.attribute("SHOW_CALIB_POINTS").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_CALIB_POINTS")) + extCalibPointsShow->setCheckState( + subSubElem.attribute("SHOW_CALIB_POINTS").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("COORD_DIMENSION")) + if(subSubElem.hasAttribute("COORD_DIMENSION")) { coordTab->setCurrentIndex(subSubElem.attribute("COORD_DIMENSION").toInt()); - }else + } + else { - coordTab->setCurrentIndex(1);// = 2D + coordTab->setCurrentIndex(1); // = 2D setEnabledExtrParams(false); } - if (subSubElem.hasAttribute("EXTERNAL_CALIB_FILE")) + if(subSubElem.hasAttribute("EXTERNAL_CALIB_FILE")) { - if( getExistingFile(QString::fromStdString(subSubElem.attribute("EXTERNAL_CALIB_FILE").toStdString()), mMainWindow->getProFileName()) != "" ) + if(getExistingFile( + QString::fromStdString(subSubElem.attribute("EXTERNAL_CALIB_FILE").toStdString()), + mMainWindow->getProFileName()) != "") { - mMainWindow->getExtrCalibration()->setExtrCalibFile(getExistingFile(QString::fromStdString(subSubElem.attribute("EXTERNAL_CALIB_FILE").toStdString()), mMainWindow->getProFileName())); + mMainWindow->getExtrCalibration()->setExtrCalibFile(getExistingFile( + QString::fromStdString(subSubElem.attribute("EXTERNAL_CALIB_FILE").toStdString()), + mMainWindow->getProFileName())); mMainWindow->getExtrCalibration()->loadExtrCalibFile(); } } - if (subSubElem.hasAttribute("SHOW")) + if(subSubElem.hasAttribute("SHOW")) coordShow->setCheckState(subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("FIX")) + if(subSubElem.hasAttribute("FIX")) coordFix->setCheckState(subSubElem.attribute("FIX").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("ROTATE")) + if(subSubElem.hasAttribute("ROTATE")) coordRotate->setValue(subSubElem.attribute("ROTATE").toInt()); - //debout << "coordTransX_max: " << coordTransX->maximum() << " coordTransX: " << subSubElem.attribute("TRANS_X").toInt() << endl; - if (subSubElem.hasAttribute("TRANS_X")){ -// coordTransX->setValue(subSubElem.attribute("TRANS_X").toInt()); + if(subSubElem.hasAttribute("TRANS_X")) + { int trans_x = subSubElem.attribute("TRANS_X").toInt(); - if( trans_x > coordTransX->maximum() ) + if(trans_x > coordTransX->maximum()) setCalibCoordTransXMax(trans_x); - //debout << "trans_x aus pet-datei: " << subSubElem.attribute("TRANS_X").toInt() << endl; coordTransX->setValue(trans_x); - //debout << "trans_x in slider: " << coordTransX->value() << endl; } - if (subSubElem.hasAttribute("TRANS_Y")){ -// coordTransX->setValue(subSubElem.attribute("TRANS_Y").toInt()); + if(subSubElem.hasAttribute("TRANS_Y")) + { int trans_y = subSubElem.attribute("TRANS_Y").toInt(); - if( trans_y > coord3DTransY->maximum() ) + if(trans_y > coord3DTransY->maximum()) setCalibCoordTransYMax(trans_y); - //debout << "trans_y aus pet-datei: " << subSubElem.attribute("TRANS_Y").toInt() << endl; coordTransY->setValue(trans_y); - //debout << "trans_y in slider: " << coordTransY->value() << endl; } - coordTransY->setValue(subSubElem.attribute("TRANS_Y").toInt()); - if (subSubElem.hasAttribute("SCALE")) + coordTransY->setValue(subSubElem.attribute("TRANS_Y").toInt()); + if(subSubElem.hasAttribute("SCALE")) coordScale->setValue(subSubElem.attribute("SCALE").toInt()); - if (subSubElem.hasAttribute("ALTITUDE")) + if(subSubElem.hasAttribute("ALTITUDE")) coordAltitude->setValue(subSubElem.attribute("ALTITUDE").toDouble()); - if (subSubElem.hasAttribute("UNIT")) + if(subSubElem.hasAttribute("UNIT")) coordUnit->setValue(subSubElem.attribute("UNIT").toDouble()); - if (subSubElem.hasAttribute("USE_INTRINSIC_CENTER")) - coordUseIntrinsic->setCheckState(subSubElem.attribute("USE_INTRINSIC_CENTER").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("COORD3D_TRANS_X")) + if(subSubElem.hasAttribute("USE_INTRINSIC_CENTER")) + coordUseIntrinsic->setCheckState( + subSubElem.attribute("USE_INTRINSIC_CENTER").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("COORD3D_TRANS_X")) coord3DTransX->setValue(subSubElem.attribute("COORD3D_TRANS_X").toInt()); - if (subSubElem.hasAttribute("COORD3D_TRANS_Y")) + if(subSubElem.hasAttribute("COORD3D_TRANS_Y")) coord3DTransY->setValue(subSubElem.attribute("COORD3D_TRANS_Y").toInt()); - if (subSubElem.hasAttribute("COORD3D_TRANS_Z")) + if(subSubElem.hasAttribute("COORD3D_TRANS_Z")) coord3DTransZ->setValue(subSubElem.attribute("COORD3D_TRANS_Z").toInt()); - if (subSubElem.hasAttribute("COORD3D_AXIS_LEN")) + if(subSubElem.hasAttribute("COORD3D_AXIS_LEN")) coord3DAxeLen->setValue(subSubElem.attribute("COORD3D_AXIS_LEN").toInt()); - if (subSubElem.hasAttribute("COORD3D_SWAP_X")) - coord3DSwapX->setCheckState(subSubElem.attribute("COORD3D_SWAP_X").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("COORD3D_SWAP_Y")) - coord3DSwapY->setCheckState(subSubElem.attribute("COORD3D_SWAP_Y").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("COORD3D_SWAP_Z")) - coord3DSwapZ->setCheckState(subSubElem.attribute("COORD3D_SWAP_Z").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("COORD3D_SWAP_X")) + coord3DSwapX->setCheckState( + subSubElem.attribute("COORD3D_SWAP_X").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("COORD3D_SWAP_Y")) + coord3DSwapY->setCheckState( + subSubElem.attribute("COORD3D_SWAP_Y").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("COORD3D_SWAP_Z")) + coord3DSwapZ->setCheckState( + subSubElem.attribute("COORD3D_SWAP_Z").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "ALIGNMENT_GRID") + else if(subSubElem.tagName() == "ALIGNMENT_GRID") { - if (subSubElem.hasAttribute("GRID_DIMENSION")) + if(subSubElem.hasAttribute("GRID_DIMENSION")) { gridTab->setCurrentIndex(subSubElem.attribute("GRID_DIMENSION").toInt()); - }else + } + else { - gridTab->setCurrentIndex(1);// = 2D + gridTab->setCurrentIndex(1); // = 2D } - if (subSubElem.hasAttribute("SHOW")) + if(subSubElem.hasAttribute("SHOW")) gridShow->setCheckState(subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("FIX")) + if(subSubElem.hasAttribute("FIX")) gridFix->setCheckState(subSubElem.attribute("FIX").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("ROTATE")) + if(subSubElem.hasAttribute("ROTATE")) gridRotate->setValue(subSubElem.attribute("ROTATE").toInt()); - if (subSubElem.hasAttribute("TRANS_X")) + if(subSubElem.hasAttribute("TRANS_X")) gridTransX->setValue(subSubElem.attribute("TRANS_X").toInt()); - if (subSubElem.hasAttribute("TRANS_Y")) + if(subSubElem.hasAttribute("TRANS_Y")) gridTransY->setValue(subSubElem.attribute("TRANS_Y").toInt()); - if (subSubElem.hasAttribute("SCALE")) + if(subSubElem.hasAttribute("SCALE")) gridScale->setValue(subSubElem.attribute("SCALE").toInt()); - if (subSubElem.hasAttribute("GRID3D_TRANS_X")) + if(subSubElem.hasAttribute("GRID3D_TRANS_X")) grid3DTransX->setValue(subSubElem.attribute("GRID3D_TRANS_X").toInt()); - if (subSubElem.hasAttribute("GRID3D_TRANS_Y")) + if(subSubElem.hasAttribute("GRID3D_TRANS_Y")) grid3DTransY->setValue(subSubElem.attribute("GRID3D_TRANS_Y").toInt()); - if (subSubElem.hasAttribute("GRID3D_TRANS_Z")) + if(subSubElem.hasAttribute("GRID3D_TRANS_Z")) grid3DTransZ->setValue(subSubElem.attribute("GRID3D_TRANS_Z").toInt()); - if (subSubElem.hasAttribute("GRID3D_RESOLUTION")) + if(subSubElem.hasAttribute("GRID3D_RESOLUTION")) grid3DResolution->setValue(subSubElem.attribute("GRID3D_RESOLUTION").toInt()); } else debout << "Unknown CALIBRATION tag " << subSubElem.tagName() << std::endl; - } - else if (subElem.tagName() == "RECOGNITION") + else if(subElem.tagName() == "RECOGNITION") { - for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); subSubElem = subSubElem.nextSiblingElement()) - if (subSubElem.tagName() == "PERFORM") + for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); + subSubElem = subSubElem.nextSiblingElement()) + if(subSubElem.tagName() == "PERFORM") { - if (subSubElem.hasAttribute("ENABLED")) - performRecognition->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("METHOD")) + if(subSubElem.hasAttribute("ENABLED")) + performRecognition->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("METHOD")) { - auto recognitionMethod = static_cast<reco::RecognitionMethod>(subSubElem.attribute("METHOD").toInt()); + auto recognitionMethod = + static_cast<reco::RecognitionMethod>(subSubElem.attribute("METHOD").toInt()); auto foundIndex = recoMethod->findData(QVariant::fromValue(recognitionMethod)); - if (foundIndex == -1) + if(foundIndex == -1) { - throw std::invalid_argument("Recognition Method could not be found, please check your input"); + throw std::invalid_argument( + "Recognition Method could not be found, please check your input"); } recoMethod->setCurrentIndex(foundIndex); } - if (subSubElem.hasAttribute("STEP")) + if(subSubElem.hasAttribute("STEP")) recoStep->setValue(subSubElem.attribute("STEP").toInt()); } - else if (subSubElem.tagName() == "REGION_OF_INTEREST") + else if(subSubElem.tagName() == "REGION_OF_INTEREST") { - double x=0, y=0, w=0, h=0; - if (subSubElem.hasAttribute("SHOW")) + double x = 0, y = 0, w = 0, h = 0; + if(subSubElem.hasAttribute("SHOW")) roiShow->setCheckState(subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("FIX")) + if(subSubElem.hasAttribute("FIX")) roiFix->setCheckState(subSubElem.attribute("FIX").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("X")) + if(subSubElem.hasAttribute("X")) x = subSubElem.attribute("X").toDouble(); - if (subSubElem.hasAttribute("Y")) + if(subSubElem.hasAttribute("Y")) y = subSubElem.attribute("Y").toDouble(); - if (subSubElem.hasAttribute("WIDTH")) + if(subSubElem.hasAttribute("WIDTH")) w = subSubElem.attribute("WIDTH").toDouble(); - if (subSubElem.hasAttribute("HEIGHT")) + if(subSubElem.hasAttribute("HEIGHT")) h = subSubElem.attribute("HEIGHT").toDouble(); mMainWindow->getRecoRoiItem()->setRect(x, y, w, h); } - else if (subSubElem.tagName() == "MARKER") + else if(subSubElem.tagName() == "MARKER") { - if (subSubElem.hasAttribute("BRIGHTNESS")) + if(subSubElem.hasAttribute("BRIGHTNESS")) markerBrightness->setValue(subSubElem.attribute("BRIGHTNESS").toInt()); - if (subSubElem.hasAttribute("IGNORE_WITHOUT")) - markerIgnoreWithout->setCheckState(subSubElem.attribute("IGNORE_WITHOUT").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("IGNORE_WITHOUT")) + markerIgnoreWithout->setCheckState( + subSubElem.attribute("IGNORE_WITHOUT").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "SIZE_COLOR") + else if(subSubElem.tagName() == "SIZE_COLOR") { mColorChanging = true; // damit bei Anpassungen Farbbild nicht immer wieder neu bestimmt wird - if (subSubElem.hasAttribute("SHOW")) - recoShowColor->setCheckState(subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("AUTO_WB")) - recoAutoWB->setCheckState(subSubElem.attribute("AUTO_WB").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("X")) + if(subSubElem.hasAttribute("SHOW")) + recoShowColor->setCheckState( + subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("AUTO_WB")) + recoAutoWB->setCheckState( + subSubElem.attribute("AUTO_WB").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("X")) recoColorX->setCurrentIndex(subSubElem.attribute("X").toInt()); - if (subSubElem.hasAttribute("Y")) + if(subSubElem.hasAttribute("Y")) recoColorY->setCurrentIndex(subSubElem.attribute("Y").toInt()); - if (subSubElem.hasAttribute("Z")) + if(subSubElem.hasAttribute("Z")) recoColorZ->setValue(subSubElem.attribute("Z").toInt()); - if (subSubElem.hasAttribute("GREY_LEVEL")) + if(subSubElem.hasAttribute("GREY_LEVEL")) recoGreyLevel->setValue(subSubElem.attribute("GREY_LEVEL").toInt()); - if (subSubElem.hasAttribute("SYMBOL_SIZE")) + if(subSubElem.hasAttribute("SYMBOL_SIZE")) recoSymbolSize->setValue(subSubElem.attribute("SYMBOL_SIZE").toInt()); mColorChanging = false; // MODEL setzen erzeugt Bild neu - if (subSubElem.hasAttribute("MODEL")) + if(subSubElem.hasAttribute("MODEL")) { // damit auch bild neu erzeugt wird, wenn sich index nicht aendert: - if (recoColorModel->currentIndex() == subSubElem.attribute("MODEL").toInt()) + if(recoColorModel->currentIndex() == subSubElem.attribute("MODEL").toInt()) { mIndexChanging = false; on_recoColorModel_currentIndexChanged(recoColorModel->currentIndex()); @@ -3131,87 +3201,93 @@ void Control::getXml(QDomElement &elem) recoColorModel->setCurrentIndex(subSubElem.attribute("MODEL").toInt()); } - double x=0., y=0., width=0., height=0., mapHeightValue=DEFAULT_HEIGHT; - bool colored=true, invHue=false; + double x = 0., y = 0., width = 0., height = 0., mapHeightValue = DEFAULT_HEIGHT; + bool colored = true, invHue = false; QColor fromCol, toCol; - int h=-1, s=-1, v=-1; + int h = -1, s = -1, v = -1; fromCol = fromCol.toHsv(); - toCol = toCol.toHsv(); + toCol = toCol.toHsv(); colorPlot->getMapItem()->delMaps(); - for(subSubSubElem = subSubElem.firstChildElement(); !subSubSubElem.isNull(); subSubSubElem = subSubSubElem.nextSiblingElement()) - if (subSubSubElem.tagName() == "MAP") + for(subSubSubElem = subSubElem.firstChildElement(); !subSubSubElem.isNull(); + subSubSubElem = subSubSubElem.nextSiblingElement()) + if(subSubSubElem.tagName() == "MAP") { - if (subSubSubElem.hasAttribute("X")) + if(subSubSubElem.hasAttribute("X")) x = subSubSubElem.attribute("X").toDouble(); - if (subSubSubElem.hasAttribute("Y")) + if(subSubSubElem.hasAttribute("Y")) y = subSubSubElem.attribute("Y").toDouble(); - if (subSubSubElem.hasAttribute("WIDTH")) + if(subSubSubElem.hasAttribute("WIDTH")) width = subSubSubElem.attribute("WIDTH").toDouble(); - if (subSubSubElem.hasAttribute("HEIGHT")) + if(subSubSubElem.hasAttribute("HEIGHT")) height = subSubSubElem.attribute("HEIGHT").toDouble(); - if (subSubSubElem.hasAttribute("COLORED")) + if(subSubSubElem.hasAttribute("COLORED")) colored = subSubSubElem.attribute("COLORED").toInt(); - if (subSubSubElem.hasAttribute("MAP_HEIGHT")) + if(subSubSubElem.hasAttribute("MAP_HEIGHT")) mapHeightValue = subSubSubElem.attribute("MAP_HEIGHT").toDouble(); - if (subSubSubElem.hasAttribute("FROM_HUE")) + if(subSubSubElem.hasAttribute("FROM_HUE")) h = subSubSubElem.attribute("FROM_HUE").toInt(); - if (subSubSubElem.hasAttribute("FROM_SAT")) + if(subSubSubElem.hasAttribute("FROM_SAT")) s = subSubSubElem.attribute("FROM_SAT").toInt(); - if (subSubSubElem.hasAttribute("FROM_VAL")) + if(subSubSubElem.hasAttribute("FROM_VAL")) v = subSubSubElem.attribute("FROM_VAL").toInt(); - if (h >= 0) + if(h >= 0) fromCol.setHsv(h, s, v); - if (subSubSubElem.hasAttribute("TO_HUE")) + if(subSubSubElem.hasAttribute("TO_HUE")) h = subSubSubElem.attribute("TO_HUE").toInt(); - if (subSubSubElem.hasAttribute("TO_SAT")) + if(subSubSubElem.hasAttribute("TO_SAT")) s = subSubSubElem.attribute("TO_SAT").toInt(); - if (subSubSubElem.hasAttribute("TO_VAL")) + if(subSubSubElem.hasAttribute("TO_VAL")) v = subSubSubElem.attribute("TO_VAL").toInt(); - if (h >= 0) + if(h >= 0) toCol.setHsv(h, s, v); - if (subSubSubElem.hasAttribute("INV_HUE")) + if(subSubSubElem.hasAttribute("INV_HUE")) invHue = subSubSubElem.attribute("INV_HUE").toInt(); - colorPlot->getMapItem()->addMap(x, y, width, height, colored, mapHeightValue, fromCol, toCol, invHue); - + colorPlot->getMapItem()->addMap( + x, y, width, height, colored, mapHeightValue, fromCol, toCol, invHue); } else debout << "Unknown RECOGNITION MAP tag " << subSubElem.tagName() << std::endl; - mapNr->setMaximum(colorPlot->getMapItem()->mapNum()-1); - if (subSubElem.hasAttribute("MAP_NUMBER")) // hiermit werden aus map-datenstruktur richtige map angezeigt, daher am ende + mapNr->setMaximum(colorPlot->getMapItem()->mapNum() - 1); + if(subSubElem.hasAttribute( + "MAP_NUMBER")) // hiermit werden aus map-datenstruktur richtige map angezeigt, daher am ende { mapNr->setValue(subSubElem.attribute("MAP_NUMBER").toInt()); - on_mapNr_valueChanged(subSubElem.attribute("MAP_NUMBER").toInt()); // nochmal explizit aufrufen, falls 0, dann wuerde valueChanged nicht on_... durchlaufen + on_mapNr_valueChanged( + subSubElem.attribute("MAP_NUMBER").toInt()); // nochmal explizit aufrufen, falls 0, dann + // wuerde valueChanged nicht on_... durchlaufen } - if (subSubElem.hasAttribute("DEFAULT_HEIGHT")) + if(subSubElem.hasAttribute("DEFAULT_HEIGHT")) mapDefaultHeight->setValue(subSubElem.attribute("DEFAULT_HEIGHT").toDouble()); } - else if (subSubElem.tagName() == "READ_HEIGHTS") + else if(subSubElem.tagName() == "READ_HEIGHTS") { - if (subSubElem.hasAttribute("HEIGHT_FILE")) + if(subSubElem.hasAttribute("HEIGHT_FILE")) { QString heightFileName = (subSubElem.attribute("HEIGHT_FILE")); - if (!getExistingFile(heightFileName, mMainWindow->getProFileName()).isEmpty()) + if(!getExistingFile(heightFileName, mMainWindow->getProFileName()).isEmpty()) { - mMainWindow->setHeightFileName(getExistingFile(heightFileName, mMainWindow->getProFileName())); - } else + mMainWindow->setHeightFileName( + getExistingFile(heightFileName, mMainWindow->getProFileName())); + } + else { mMainWindow->setHeightFileName(heightFileName); } } } - else if (subSubElem.tagName() == "READ_MARKER_IDS") + else if(subSubElem.tagName() == "READ_MARKER_IDS") { - if (subSubElem.hasAttribute("MARKER_FILE")) + if(subSubElem.hasAttribute("MARKER_FILE")) { QString fm = subSubElem.attribute("MARKER_FILE"); - if (getExistingFile(fm, mMainWindow->getProFileName()) != "") + if(getExistingFile(fm, mMainWindow->getProFileName()) != "") mMainWindow->setMarkerIDFileName(getExistingFile(fm, mMainWindow->getProFileName())); else mMainWindow->setMarkerIDFileName(fm); @@ -3221,250 +3297,297 @@ void Control::getXml(QDomElement &elem) else debout << "Unknown RECOGNITION tag " << subSubElem.tagName() << std::endl; } - else if (subElem.tagName() == "TRACKING") + else if(subElem.tagName() == "TRACKING") { - for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); subSubElem = subSubElem.nextSiblingElement()) - if (subSubElem.tagName() == "ONLINE_CALCULATION") + for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); + subSubElem = subSubElem.nextSiblingElement()) + if(subSubElem.tagName() == "ONLINE_CALCULATION") { - if (subSubElem.hasAttribute("ENABLED")) - trackOnlineCalc->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + trackOnlineCalc->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "REPEAT_BELOW") + else if(subSubElem.tagName() == "REPEAT_BELOW") { - if (subSubElem.hasAttribute("ENABLED")) - trackRepeat->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("QUALITY")) + if(subSubElem.hasAttribute("ENABLED")) + trackRepeat->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("QUALITY")) trackRepeatQual->setValue(subSubElem.attribute("QUALITY").toInt()); } - else if (subSubElem.tagName() == "EXTRAPOLATION") + else if(subSubElem.tagName() == "EXTRAPOLATION") { - if (subSubElem.hasAttribute("ENABLED")) - trackExtrapolation->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + trackExtrapolation->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "MERGE") + else if(subSubElem.tagName() == "MERGE") { - if (subSubElem.hasAttribute("ENABLED")) - trackMerge->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + trackMerge->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "ONLY_VISIBLE") + else if(subSubElem.tagName() == "ONLY_VISIBLE") { - if (subSubElem.hasAttribute("ENABLED")) - trackOnlySelected->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + trackOnlySelected->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "SEARCH_MISSING_FRAMES") + else if(subSubElem.tagName() == "SEARCH_MISSING_FRAMES") { - if (subSubElem.hasAttribute("ENABLED")) - trackMissingFrames->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + trackMissingFrames->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "RECALCULATE_MEDIAN_HEIGHT") + else if(subSubElem.tagName() == "RECALCULATE_MEDIAN_HEIGHT") { - if (subSubElem.hasAttribute("ENABLED")) - trackRecalcHeight->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + trackRecalcHeight->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "REGION_OF_INTEREST") + else if(subSubElem.tagName() == "REGION_OF_INTEREST") { - double x=0, y=0, w=0, h=0; - if (subSubElem.hasAttribute("SHOW")) + double x = 0, y = 0, w = 0, h = 0; + if(subSubElem.hasAttribute("SHOW")) trackRoiShow->setCheckState(subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("FIX")) + if(subSubElem.hasAttribute("FIX")) trackRoiFix->setCheckState(subSubElem.attribute("FIX").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("X")) + if(subSubElem.hasAttribute("X")) x = subSubElem.attribute("X").toDouble(); - if (subSubElem.hasAttribute("Y")) + if(subSubElem.hasAttribute("Y")) y = subSubElem.attribute("Y").toDouble(); - if (subSubElem.hasAttribute("WIDTH")) + if(subSubElem.hasAttribute("WIDTH")) w = subSubElem.attribute("WIDTH").toDouble(); - if (subSubElem.hasAttribute("HEIGHT")) + if(subSubElem.hasAttribute("HEIGHT")) h = subSubElem.attribute("HEIGHT").toDouble(); mMainWindow->getTrackRoiItem()->setRect(x, y, w, h); } - else if (subSubElem.tagName() == "ALLOW_ALTERNATE_HEIGHT") + else if(subSubElem.tagName() == "ALLOW_ALTERNATE_HEIGHT") { - if (subSubElem.hasAttribute("ENABLED")) - trackAlternateHeight->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + trackAlternateHeight->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "EXPORT_ELIMINATE_TRACKPOINT_WITHOUT_HEIGHT") + else if(subSubElem.tagName() == "EXPORT_ELIMINATE_TRACKPOINT_WITHOUT_HEIGHT") { - if (subSubElem.hasAttribute("ENABLED")) - exportElimTp->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + exportElimTp->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "EXPORT_ELIMINATE_TRAJECTORY_WITHOUT_HEIGHT") + else if(subSubElem.tagName() == "EXPORT_ELIMINATE_TRAJECTORY_WITHOUT_HEIGHT") { - if (subSubElem.hasAttribute("ENABLED")) - exportElimTrj->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + exportElimTrj->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "EXPORT_SMOOTH") + else if(subSubElem.tagName() == "EXPORT_SMOOTH") { - if (subSubElem.hasAttribute("ENABLED")) - exportSmooth->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + exportSmooth->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "EXPORT_VIEWING_DIRECTION") + else if(subSubElem.tagName() == "EXPORT_VIEWING_DIRECTION") { - if (subSubElem.hasAttribute("ENABLED")) - exportViewDir->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + exportViewDir->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "EXPORT_ANGLE_OF_VIEW") + else if(subSubElem.tagName() == "EXPORT_ANGLE_OF_VIEW") { - if (subSubElem.hasAttribute("ENABLED")) - exportAngleOfView->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + exportAngleOfView->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "EXPORT_USE_METER") + else if(subSubElem.tagName() == "EXPORT_USE_METER") { - if (subSubElem.hasAttribute("ENABLED")) - exportUseM->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + exportUseM->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "EXPORT_COMMENT") + else if(subSubElem.tagName() == "EXPORT_COMMENT") { - if (subSubElem.hasAttribute("ENABLED")) - exportComment->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + exportComment->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "EXPORT_MARKERID") + else if(subSubElem.tagName() == "EXPORT_MARKERID") { - if (subSubElem.hasAttribute("ENABLED")) - exportMarkerID->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + exportMarkerID->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "TEST_EQUAL") + else if(subSubElem.tagName() == "TEST_EQUAL") { - if (subSubElem.hasAttribute("ENABLED")) + if(subSubElem.hasAttribute("ENABLED")) testEqual->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "TEST_VELOCITY") + else if(subSubElem.tagName() == "TEST_VELOCITY") { - if (subSubElem.hasAttribute("ENABLED")) - testVelocity->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + testVelocity->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "TEST_INSIDE") + else if(subSubElem.tagName() == "TEST_INSIDE") { - if (subSubElem.hasAttribute("ENABLED")) - testInside->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + testInside->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "TEST_LENGTH") + else if(subSubElem.tagName() == "TEST_LENGTH") { - if (subSubElem.hasAttribute("ENABLED")) - testLength->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + testLength->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "TRACK_FILE") + else if(subSubElem.tagName() == "TRACK_FILE") { - if (subSubElem.hasAttribute("FILENAME")) + if(subSubElem.hasAttribute("FILENAME")) { - if (getExistingFile(subSubElem.attribute("FILENAME"), mMainWindow->getProFileName()) != "") - mMainWindow->setTrackFileName(getExistingFile(subSubElem.attribute("FILENAME"), mMainWindow->getProFileName())); - else // eigentlich nicht lesbar, aber so wird wenigstens beim projekt speichern wieder mit weggeschrieben + if(getExistingFile(subSubElem.attribute("FILENAME"), mMainWindow->getProFileName()) != "") + mMainWindow->setTrackFileName( + getExistingFile(subSubElem.attribute("FILENAME"), mMainWindow->getProFileName())); + else // eigentlich nicht lesbar, aber so wird wenigstens beim projekt speichern wieder mit + // weggeschrieben mMainWindow->setTrackFileName(subSubElem.attribute("FILENAME")); } } - else if (subSubElem.tagName() == "SEARCH_REGION") + else if(subSubElem.tagName() == "SEARCH_REGION") { - if (subSubElem.hasAttribute("SCALE")) + if(subSubElem.hasAttribute("SCALE")) trackRegionScale->setValue(subSubElem.attribute("SCALE").toInt()); - if (subSubElem.hasAttribute("LEVELS")) + if(subSubElem.hasAttribute("LEVELS")) trackRegionLevels->setValue(subSubElem.attribute("LEVELS").toInt()); - if (subSubElem.hasAttribute("MAX_ERROR")) + if(subSubElem.hasAttribute("MAX_ERROR")) trackErrorExponent->setValue(subSubElem.attribute("MAX_ERROR").toInt()); - if (subSubElem.hasAttribute("SHOW")) - trackShowSearchSize->setCheckState(subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW")) + trackShowSearchSize->setCheckState( + subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); if(subSubElem.hasAttribute("ADAPTIVE")) - adaptiveLevel->setCheckState(subSubElem.attribute("ADAPTIVE").toInt() ? Qt::Checked : Qt::Unchecked); + adaptiveLevel->setCheckState( + subSubElem.attribute("ADAPTIVE").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "PATH") + else if(subSubElem.tagName() == "PATH") { - if (subSubElem.hasAttribute("SHOW")) + if(subSubElem.hasAttribute("SHOW")) trackShow->setCheckState(subSubElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("FIX")) + if(subSubElem.hasAttribute("FIX")) trackFix->setCheckState(subSubElem.attribute("FIX").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("ONLY_VISIBLE")) - trackShowOnlyVisible->setCheckState(subSubElem.attribute("ONLY_VISIBLE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("ONLY_PEOPLE")) - trackShowOnly->setCheckState(subSubElem.attribute("ONLY_PEOPLE").toInt() ? Qt::Checked : Qt::Unchecked); - - if (subSubElem.hasAttribute("ONLY_PEOPLE_LIST")) - trackShowOnlyList->setCheckState(subSubElem.attribute("ONLY_PEOPLE_LIST").toInt() ? Qt::Checked : Qt::Unchecked); - - // IMPORTANT: reading ONLY_PEOPLE_NR is done in petrack.cpp, as the trajectories need to be loaded before! - if (subSubElem.hasAttribute("SHOW_CURRENT_POINT")) - trackShowCurrentPoint->setCheckState(subSubElem.attribute("SHOW_CURRENT_POINT").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW_POINTS")) - trackShowPoints->setCheckState(subSubElem.attribute("SHOW_POINTS").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW_PATH")) - trackShowPath->setCheckState(subSubElem.attribute("SHOW_PATH").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW_COLLECTIVE_COLOR")) - trackShowColColor->setCheckState(subSubElem.attribute("SHOW_COLLECTIVE_COLOR").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW_COLOR_MARKER")) - trackShowColorMarker->setCheckState(subSubElem.attribute("SHOW_COLOR_MARKER").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW_NUMBER")) - trackShowNumber->setCheckState(subSubElem.attribute("SHOW_NUMBER").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW_GROUND_POSITION")) - trackShowGroundPosition->setCheckState(subSubElem.attribute("SHOW_GROUND_POSITION").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW_GROUND_PATH")) - trackShowGroundPath->setCheckState(subSubElem.attribute("SHOW_GROUND_PATH").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("TRACK_PATH_COLOR")) + if(subSubElem.hasAttribute("ONLY_VISIBLE")) + trackShowOnlyVisible->setCheckState( + subSubElem.attribute("ONLY_VISIBLE").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ONLY_PEOPLE")) + trackShowOnly->setCheckState( + subSubElem.attribute("ONLY_PEOPLE").toInt() ? Qt::Checked : Qt::Unchecked); + + if(subSubElem.hasAttribute("ONLY_PEOPLE_LIST")) + trackShowOnlyList->setCheckState( + subSubElem.attribute("ONLY_PEOPLE_LIST").toInt() ? Qt::Checked : Qt::Unchecked); + + // IMPORTANT: reading ONLY_PEOPLE_NR is done in petrack.cpp, as the trajectories need to be loaded + // before! + if(subSubElem.hasAttribute("SHOW_CURRENT_POINT")) + trackShowCurrentPoint->setCheckState( + subSubElem.attribute("SHOW_CURRENT_POINT").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_POINTS")) + trackShowPoints->setCheckState( + subSubElem.attribute("SHOW_POINTS").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_PATH")) + trackShowPath->setCheckState( + subSubElem.attribute("SHOW_PATH").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_COLLECTIVE_COLOR")) + trackShowColColor->setCheckState( + subSubElem.attribute("SHOW_COLLECTIVE_COLOR").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_COLOR_MARKER")) + trackShowColorMarker->setCheckState( + subSubElem.attribute("SHOW_COLOR_MARKER").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_NUMBER")) + trackShowNumber->setCheckState( + subSubElem.attribute("SHOW_NUMBER").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_GROUND_POSITION")) + trackShowGroundPosition->setCheckState( + subSubElem.attribute("SHOW_GROUND_POSITION").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_GROUND_PATH")) + trackShowGroundPath->setCheckState( + subSubElem.attribute("SHOW_GROUND_PATH").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("TRACK_PATH_COLOR")) { QColor color(subSubElem.attribute("TRACK_PATH_COLOR")); setTrackPathColor(color); } - if (subSubElem.hasAttribute("TRACK_GROUND_PATH_COLOR")) + if(subSubElem.hasAttribute("TRACK_GROUND_PATH_COLOR")) { QColor color(subSubElem.attribute("TRACK_GROUND_PATH_COLOR")); setTrackGroundPathColor(color); } - if (subSubElem.hasAttribute("HEAD_SIZE")) - trackHeadSized->setCheckState(subSubElem.attribute("HEAD_SIZE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("CURRENT_POINT_SIZE")) + if(subSubElem.hasAttribute("HEAD_SIZE")) + trackHeadSized->setCheckState( + subSubElem.attribute("HEAD_SIZE").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("CURRENT_POINT_SIZE")) trackCurrentPointSize->setValue(subSubElem.attribute("CURRENT_POINT_SIZE").toInt()); - if (subSubElem.hasAttribute("POINTS_SIZE")) + if(subSubElem.hasAttribute("POINTS_SIZE")) trackPointSize->setValue(subSubElem.attribute("POINTS_SIZE").toInt()); - if (subSubElem.hasAttribute("PATH_SIZE")) + if(subSubElem.hasAttribute("PATH_SIZE")) trackPathWidth->setValue(subSubElem.attribute("PATH_SIZE").toInt()); - if (subSubElem.hasAttribute("COLLECTIVE_COLOR_SIZE")) + if(subSubElem.hasAttribute("COLLECTIVE_COLOR_SIZE")) trackColColorSize->setValue(subSubElem.attribute("COLLECTIVE_COLOR_SIZE").toInt()); - if (subSubElem.hasAttribute("COLOR_MARKER_SIZE")) + if(subSubElem.hasAttribute("COLOR_MARKER_SIZE")) trackColorMarkerSize->setValue(subSubElem.attribute("COLOR_MARKER_SIZE").toInt()); - if (subSubElem.hasAttribute("NUMBER_SIZE")) + if(subSubElem.hasAttribute("NUMBER_SIZE")) trackNumberSize->setValue(subSubElem.attribute("NUMBER_SIZE").toInt()); - if (subSubElem.hasAttribute("GROUND_POSITION_SIZE")) + if(subSubElem.hasAttribute("GROUND_POSITION_SIZE")) trackGroundPositionSize->setValue(subSubElem.attribute("GROUND_POSITION_SIZE").toInt()); - if (subSubElem.hasAttribute("GROUND_PATH_SIZE")) + if(subSubElem.hasAttribute("GROUND_PATH_SIZE")) trackGroundPathSize->setValue(subSubElem.attribute("GROUND_PATH_SIZE").toInt()); - if (subSubElem.hasAttribute("POINTS_COLORED")) - trackShowPointsColored->setCheckState(subSubElem.attribute("POINTS_COLORED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("NUMBER_BOLD")) - trackNumberBold->setCheckState(subSubElem.attribute("NUMBER_BOLD").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("BEFORE")) + if(subSubElem.hasAttribute("POINTS_COLORED")) + trackShowPointsColored->setCheckState( + subSubElem.attribute("POINTS_COLORED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("NUMBER_BOLD")) + trackNumberBold->setCheckState( + subSubElem.attribute("NUMBER_BOLD").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("BEFORE")) trackShowBefore->setValue(subSubElem.attribute("BEFORE").toInt()); - if (subSubElem.hasAttribute("AFTER")) + if(subSubElem.hasAttribute("AFTER")) trackShowAfter->setValue(subSubElem.attribute("AFTER").toInt()); } else debout << "Unknown TRACKING tag " << subSubElem.tagName() << std::endl; } - else if (subElem.tagName() == "ANALYSIS") + else if(subElem.tagName() == "ANALYSIS") { - for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); subSubElem = subSubElem.nextSiblingElement()) - if (subSubElem.tagName() == "SEARCH_MISSING_FRAMES") + for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); + subSubElem = subSubElem.nextSiblingElement()) + if(subSubElem.tagName() == "SEARCH_MISSING_FRAMES") { - if (subSubElem.hasAttribute("ENABLED")) - anaMissingFrames->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + anaMissingFrames->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "MARK_ACTUAL") + else if(subSubElem.tagName() == "MARK_ACTUAL") { - if (subSubElem.hasAttribute("ENABLED")) - anaMarkAct->setCheckState(subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ENABLED")) + anaMarkAct->setCheckState( + subSubElem.attribute("ENABLED").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "CALCULATION") + else if(subSubElem.tagName() == "CALCULATION") { - if (subSubElem.hasAttribute("STEP_SIZE")) + if(subSubElem.hasAttribute("STEP_SIZE")) anaStep->setValue(subSubElem.attribute("STEP_SIZE").toInt()); - if (subSubElem.hasAttribute("CONSIDER_X")) - anaConsiderX->setCheckState(subSubElem.attribute("CONSIDER_X").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("CONSIDER_Y")) - anaConsiderY->setCheckState(subSubElem.attribute("CONSIDER_Y").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("ABSOLUTE")) - anaConsiderAbs->setCheckState(subSubElem.attribute("ABSOLUTE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("REVERSE")) - anaConsiderRev->setCheckState(subSubElem.attribute("REVERSE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("SHOW_VORONOI")) - showVoronoiCells->setCheckState(subSubElem.attribute("SHOW_VORONOI").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("CONSIDER_X")) + anaConsiderX->setCheckState( + subSubElem.attribute("CONSIDER_X").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("CONSIDER_Y")) + anaConsiderY->setCheckState( + subSubElem.attribute("CONSIDER_Y").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("ABSOLUTE")) + anaConsiderAbs->setCheckState( + subSubElem.attribute("ABSOLUTE").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("REVERSE")) + anaConsiderRev->setCheckState( + subSubElem.attribute("REVERSE").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("SHOW_VORONOI")) + showVoronoiCells->setCheckState( + subSubElem.attribute("SHOW_VORONOI").toInt() ? Qt::Checked : Qt::Unchecked); } else debout << "Unknown ANAYSIS tag " << subSubElem.tagName() << std::endl; @@ -3483,13 +3606,15 @@ reco::RecognitionMethod Control::getRecoMethod() const void Control::on_colorPickerButton_clicked(bool checked) { - //true wenn neu gechecked, false wenn wieder abgewählt + // true wenn neu gechecked, false wenn wieder abgewählt GraphicsView *view = mMainWindow->getView(); if(checked) { connect(view, &GraphicsView::colorSelected, this, &Control::on_expandColor); connect(view, &GraphicsView::setColorEvent, this, &Control::on_setColor); - }else{ + } + else + { disconnect(view, &GraphicsView::colorSelected, this, &Control::on_expandColor); disconnect(view, &GraphicsView::setColorEvent, this, &Control::on_setColor); } @@ -3505,14 +3630,14 @@ void Control::on_colorPickerButton_clicked(bool checked) * * @return Boolean describing, if a color was retrieved */ -bool Control::getColors(QColor& clickedColor, QColor& toColor, QColor& fromColor, RectPlotItem*& map) +bool Control::getColors(QColor &clickedColor, QColor &toColor, QColor &fromColor, RectPlotItem *&map) { if(mMainWindow->getImg().empty()) { return false; } - QImage *hsvImg = mMainWindow->getImage(); + QImage *hsvImg = mMainWindow->getImage(); QPointF imgPoint = mMainWindow->getMousePosOnImage(); if(imgPoint.x() < 0 || imgPoint.x() > hsvImg->width() || imgPoint.y() < 0 || imgPoint.y() > hsvImg->height()) @@ -3520,15 +3645,14 @@ bool Control::getColors(QColor& clickedColor, QColor& toColor, QColor& fromColor debout << "Clicked outside the image with color picker." << std::endl; return false; } - //debout << "Koordinaten: " << imgPoint.x() << ", " << imgPoint.y() << std::endl; - clickedColor = QColor {hsvImg->pixel(imgPoint.toPoint())}; - //debout << "Farbe: " << (int)clickedColor[0] << ", " << (int)clickedColor[1] << ", " << (int)clickedColor[2] << std::endl; + clickedColor = QColor{hsvImg->pixel(imgPoint.toPoint())}; - map = this->getColorPlot()->getMapItem(); - toColor = map->getActMapToColor(); + map = this->getColorPlot()->getMapItem(); + toColor = map->getActMapToColor(); fromColor = map->getActMapFromColor(); - if(!toColor.isValid() || !fromColor.isValid()){ + if(!toColor.isValid() || !fromColor.isValid()) + { debout << "Map is corrupted" << std::endl; return false; } @@ -3547,10 +3671,9 @@ bool Control::getColors(QColor& clickedColor, QColor& toColor, QColor& fromColor */ void Control::on_expandColor() { - - QColor fromColor, toColor; - RectPlotItem* map; - QColor clickedColor; + QColor fromColor, toColor; + RectPlotItem *map; + QColor clickedColor; if(!getColors(clickedColor, toColor, fromColor, map)) { return; @@ -3571,51 +3694,54 @@ void Control::on_setColor() { constexpr int BUFFER = 5; - QColor fromColor, toColor; - RectPlotItem* map; - QColor clickedColor; + QColor fromColor, toColor; + RectPlotItem *map; + QColor clickedColor; if(!getColors(clickedColor, toColor, fromColor, map)) { return; } int minHue, maxHue; - if( (clickedColor.hue()+BUFFER)%359 < clickedColor.hue()+BUFFER) + if((clickedColor.hue() + BUFFER) % 359 < clickedColor.hue() + BUFFER) { - maxHue = (clickedColor.hue()+BUFFER)%BUFFER; + maxHue = (clickedColor.hue() + BUFFER) % BUFFER; map->changeActMapInvHue(true); - }else{ - maxHue = clickedColor.hue()+BUFFER; + } + else + { + maxHue = clickedColor.hue() + BUFFER; map->changeActMapInvHue(false); } - if( (clickedColor.hue() - BUFFER) < 0) + if((clickedColor.hue() - BUFFER) < 0) { minHue = 360 + (clickedColor.hue() - BUFFER); map->changeActMapInvHue(true); - }else{ + } + else + { minHue = clickedColor.hue() - BUFFER; - //map->changeActMapInvHue(false); } - toColor.setHsv(maxHue, std::min((clickedColor.saturation()+BUFFER),255), std::min(clickedColor.value()+BUFFER, 255)); - fromColor.setHsv(minHue, std::max(clickedColor.saturation()-BUFFER,0), std::max(clickedColor.value()-BUFFER,0)); + toColor.setHsv( + maxHue, std::min((clickedColor.saturation() + BUFFER), 255), std::min(clickedColor.value() + BUFFER, 255)); + fromColor.setHsv( + minHue, std::max(clickedColor.saturation() - BUFFER, 0), std::max(clickedColor.value() - BUFFER, 0)); - //debout << "Inv Hue nach setCol: " << map->getActMapInvHue() << std::endl; saveChange(fromColor, toColor, map); } // NOTE Use duplicate observed data on color Data // Meaning: Own class for the Data and every View works with his class!!! // NOTE that color slides are not actually working properly on their own; use this or colorRangeWidget! -void Control::saveChange(const QColor& fromColor, const QColor& toColor, RectPlotItem* map) +void Control::saveChange(const QColor &fromColor, const QColor &toColor, RectPlotItem *map) { - map->changeActMapToColor(toColor); map->changeActMapFromColor(fromColor); - mMainWindow->getColorRangeWidget()->setControlWidget(toColor.hue(), fromColor.hue(), - toColor.saturation(), fromColor.saturation()); - mMainWindow->setRecognitionChanged(true);// flag indicates that changes of recognition parameters happens - if( !mMainWindow->isLoading() ) + mMainWindow->getColorRangeWidget()->setControlWidget( + toColor.hue(), fromColor.hue(), toColor.saturation(), fromColor.saturation()); + mMainWindow->setRecognitionChanged(true); // flag indicates that changes of recognition parameters happens + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); } @@ -3631,7 +3757,7 @@ void Control::saveChange(const QColor& fromColor, const QColor& toColor, RectPlo * @param toColor[in,out] toColor of the map, gets changed! * @param clickedColor[in] */ -void Control::expandRange(QColor& fromColor, QColor& toColor, const QColor& clickedColor) const +void Control::expandRange(QColor &fromColor, QColor &toColor, const QColor &clickedColor) const { // NOTE BUFFER in Klassenebene verschieben und bei setColor auch nutzen? (verschiedene Größe vllt. gewünscht?) constexpr int BUFFER = 10; @@ -3643,12 +3769,9 @@ void Control::expandRange(QColor& fromColor, QColor& toColor, const QColor& clic std::array<int, 3> fromColorArr; fromColor.getHsv(&fromColorArr[0], &fromColorArr[1], &fromColorArr[2]); - //debout << "Alte Grenze: toColor: " << toColorArr[0] << " " << toColorArr[1] << " "<< toColorArr[2] << std::endl; - //debout << "Alte Grenze: fromColor: " << fromColorArr[0] << " " << fromColorArr[1] << " " << fromColorArr[2] << std::endl; - std::array<bool, 3> isInRange {true, true, true}; - bool invHue = getColorPlot()->getMapItem()->getActMapInvHue(); - //debout << "Inverse Hue vorher: " << invHue << std::endl; + std::array<bool, 3> isInRange{true, true, true}; + bool invHue = getColorPlot()->getMapItem()->getActMapInvHue(); // What values do need to be altered? if(invHue) @@ -3659,14 +3782,16 @@ void Control::expandRange(QColor& fromColor, QColor& toColor, const QColor& clic { isInRange[0] = false; } - }else + } + else { if(!(clickedColor.hue() <= toColor.hue() || clickedColor.hue() >= fromColor.hue())) { isInRange[0] = false; } } - }else + } + else { if(toColor.hue() > fromColor.hue()) { @@ -3674,7 +3799,8 @@ void Control::expandRange(QColor& fromColor, QColor& toColor, const QColor& clic { isInRange[0] = false; } - }else + } + else { if(!(clickedColor.hue() >= toColor.hue() && clickedColor.hue() <= fromColor.hue())) { @@ -3691,7 +3817,9 @@ void Control::expandRange(QColor& fromColor, QColor& toColor, const QColor& clic { isInRange[i] = false; } - }else{ + } + else + { if(!(clickedColorArr[i] >= toColorArr[i] && clickedColorArr[i] <= fromColorArr[i])) { isInRange[i] = false; @@ -3700,11 +3828,12 @@ void Control::expandRange(QColor& fromColor, QColor& toColor, const QColor& clic } // if all in range, no expanding required - if(std::count(isInRange.cbegin(), isInRange.cend(), true) == 3){ + if(std::count(isInRange.cbegin(), isInRange.cend(), true) == 3) + { return; } - int distToColor = 0; + int distToColor = 0; int distFromColor = 0; for(int i = 0; i < 3; ++i) @@ -3712,48 +3841,53 @@ void Control::expandRange(QColor& fromColor, QColor& toColor, const QColor& clic if(isInRange[i]) continue; - distToColor = abs(toColorArr[i] - clickedColorArr[i]); + distToColor = abs(toColorArr[i] - clickedColorArr[i]); distFromColor = abs(fromColorArr[i] - clickedColorArr[i]); if(distFromColor < distToColor) { int buffer = fromColorArr[i] - clickedColorArr[i] < 0 ? BUFFER : -BUFFER; - if(i==0) // Hue + if(i == 0) // Hue { fromColorArr[i] = std::min(359, std::max(0, clickedColorArr[i] + buffer)); - }else + } + else { fromColorArr[i] = std::min(255, std::max(0, clickedColorArr[i] + buffer)); } - }else{ + } + else + { int buffer = toColorArr[i] - clickedColorArr[i] < 0 ? BUFFER : -BUFFER; - if(i==0) // Hue + if(i == 0) // Hue { toColorArr[i] = std::min(359, std::max(0, clickedColorArr[i] + buffer)); - }else + } + else { toColorArr[i] = std::min(255, std::max(0, clickedColorArr[i] + buffer)); } } } - int toHue = toColorArr[0]; + int toHue = toColorArr[0]; int fromHue = fromColorArr[0]; - if(invHue){ - if(toHue+360-fromHue > 180){ + if(invHue) + { + if(toHue + 360 - fromHue > 180) + { getColorPlot()->getMapItem()->changeActMapInvHue(false); } - }else{ - if(toHue-fromHue > 180){ + } + else + { + if(toHue - fromHue > 180) + { getColorPlot()->getMapItem()->changeActMapInvHue(true); } } - //debout << "Inverse Hue nachher " << getColorPlot()->getMapItem()->getActMapInvHue() << std::endl; - //debout << "Neue Grenze: toColor: " << toColorArr[0] << " " << toColorArr[1] << " "<< toColorArr[2] << std::endl; - //debout << "Neue Grenze: fromColor: " << fromColorArr[0] << " " << fromColorArr[1] << " " << fromColorArr[2] << std::endl; toColor.setHsv(toColorArr[0], toColorArr[1], toColorArr[2]); fromColor.setHsv(fromColorArr[0], fromColorArr[1], fromColorArr[2]); } #include "moc_control.cpp" - diff --git a/src/coordItem.cpp b/src/coordItem.cpp index 7a41014bb9638d56db42b1bc5e6a6ed5698188d1..960b50cdd7f5b2ce3203bdda987c41881c3f2583 100644 --- a/src/coordItem.cpp +++ b/src/coordItem.cpp @@ -18,26 +18,26 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <cmath> -#include <QtWidgets> +#include "coordItem.h" -#include "petrack.h" #include "control.h" -#include "view.h" -#include "coordItem.h" #include "extrCalibration.h" +#include "petrack.h" +#include "view.h" + +#include <QtWidgets> +#include <cmath> // in x und y gleichermassen skaliertes koordinatensystem, // da von einer vorherigen intrinsischen kamerakalibrierung ausgegenagen wird, -// so dass pixel quadratisch -CoordItem::CoordItem(QWidget *wParent,/* QGraphicsScene * scene,*/ QGraphicsItem * parent) - : QGraphicsItem(parent/*, scene*/) +// so dass pixel quadratisch +CoordItem::CoordItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) { - mMainWindow = (class Petrack*) wParent; - extCalib = mMainWindow->getExtrCalibration(); + mMainWindow = (class Petrack *) wParent; + extCalib = mMainWindow->getExtrCalibration(); mControlWidget = mMainWindow->getControlWidget(); - //Set Min and Max + // Set Min and Max calibPointsMin.x = 50000; calibPointsMax.x = 0; calibPointsMin.y = 50000; @@ -57,29 +57,29 @@ CoordItem::CoordItem(QWidget *wParent,/* QGraphicsScene * scene,*/ QGraphicsItem QRectF CoordItem::boundingRect() const { // bounding box wird in lokalen koordinaten angegeben!!! (+-10 wegen zahl "1") - if (mControlWidget->getCalibCoordShow()) + if(mControlWidget->getCalibCoordShow()) { - if( mControlWidget->getCalibCoordDimension() != 0 ) // 2D view + if(mControlWidget->getCalibCoordDimension() != 0) // 2D view { return QRectF(-110., -110., 220., 220.); } else // 3D view { - double min_x = std::min(std::min(x.x,y.x),std::min(z.x,ursprung.x)); - double max_x = std::max(std::max(x.x,y.x),std::max(z.x,ursprung.x)); + double min_x = std::min(std::min(x.x, y.x), std::min(z.x, ursprung.x)); + double max_x = std::max(std::max(x.x, y.x), std::max(z.x, ursprung.x)); - double min_y = std::min(std::min(x.y,y.y),std::min(z.y,ursprung.y)); - double max_y = std::max(std::max(x.y,y.y),std::max(z.y,ursprung.y)); + double min_y = std::min(std::min(x.y, y.y), std::min(z.y, ursprung.y)); + double max_y = std::max(std::max(x.y, y.y), std::max(z.y, ursprung.y)); - if( mControlWidget->getCalibExtrCalibPointsShow() ) + if(mControlWidget->getCalibExtrCalibPointsShow()) { - min_x = std::min(float(min_x),calibPointsMin.x); - max_x = std::max(float(max_x),calibPointsMax.x); + min_x = std::min(float(min_x), calibPointsMin.x); + max_x = std::max(float(max_x), calibPointsMax.x); - min_y = std::min(float(min_y),calibPointsMin.y); - max_y = std::max(float(max_y),calibPointsMax.y); + min_y = std::min(float(min_y), calibPointsMin.y); + max_y = std::max(float(max_y), calibPointsMax.y); } - return QRectF(min_x-25, min_y-25, max_x-min_x+50, max_y-min_y+50); + return QRectF(min_x - 25, min_y - 25, max_x - min_x + 50, max_y - min_y + 50); } } else @@ -91,52 +91,57 @@ QRectF CoordItem::boundingRect() const // event, of moving mouse while button is pressed void CoordItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - // if coordinate system position is not fixed - if (!mControlWidget->getCalibCoordFix()) + if(!mControlWidget->getCalibCoordFix()) { - setCursor(Qt::ClosedHandCursor); - QPointF diff = event->scenePos()-event->lastScenePos(); //screenPos()-buttonDownScreenPos(Qt::RightButton) also interesting - if (event->buttons() == Qt::RightButton) // event->button() doesnt work + QPointF diff = event->scenePos() - + event->lastScenePos(); // screenPos()-buttonDownScreenPos(Qt::RightButton) also interesting + if(event->buttons() == Qt::RightButton) // event->button() doesnt work { - mControlWidget->setCalibCoordRotate(mControlWidget->getCalibCoordRotate()-(int)(3.*(diff.x()+diff.y()))); //10* nicht noetig, da eh nur relativ + mControlWidget->setCalibCoordRotate( + mControlWidget->getCalibCoordRotate() - + (int) (3. * (diff.x() + diff.y()))); // 10* nicht noetig, da eh nur relativ } - else if (event->buttons() == Qt::LeftButton) + else if(event->buttons() == Qt::LeftButton) { - if( mControlWidget->getCalibCoordDimension() == 0 ) // 3D + if(mControlWidget->getCalibCoordDimension() == 0) // 3D { - cv::Point3f p_cur = extCalib->get3DPoint(cv::Point2f(event->scenePos().x(), - event->scenePos().y()), - mControlWidget->getCalibCoord3DTransZ()); - cv::Point3f p_last = extCalib->get3DPoint(cv::Point2f(mouse_x/*event->lastScenePos().x()*/, - mouse_y/*event->lastScenePos().y()*/), - mControlWidget->getCalibCoord3DTransZ()); + cv::Point3f p_cur = extCalib->get3DPoint( + cv::Point2f(event->scenePos().x(), event->scenePos().y()), mControlWidget->getCalibCoord3DTransZ()); + cv::Point3f p_last = extCalib->get3DPoint( + cv::Point2f(mouse_x /*event->lastScenePos().x()*/, mouse_y /*event->lastScenePos().y()*/), + mControlWidget->getCalibCoord3DTransZ()); // ToDo: - // Problem: Die Mouse Bewegungen, die erfasst werden sind zu gering, sodass viele Werte als 0 gewertet werden - // und nicht als Bewegung bercksichtigt werden, obwohl man die Maus bewegt. D.h. die Maus bewegt sich - // der Abstand zwischen dem Start und dem End-punkt ist aber sehr gering und wird als 0 gewertet und - // das Kooridnatensystem bewegt sich nicht. Effekt wird noch verstrkt, da das stndig passiert + // Problem: Die Mouse Bewegungen, die erfasst werden sind zu gering, sodass viele Werte als 0 gewertet + // werden und nicht als Bewegung bercksichtigt werden, obwohl man die Maus bewegt. D.h. die Maus bewegt + // sich der Abstand zwischen dem Start und dem End-punkt ist aber sehr gering und wird als 0 gewertet + // und das Kooridnatensystem bewegt sich nicht. Effekt wird noch verstrkt, da das stndig passiert // Besonders schnelle Mausbewegungen lindern den Effekt - mControlWidget->setCalibCoord3DTransX(coordTrans_x-(mControlWidget->getCalibCoord3DSwapX() ? -1 : 1)*round(p_last.x-p_cur.x)); - mControlWidget->setCalibCoord3DTransY(coordTrans_y-(mControlWidget->getCalibCoord3DSwapY() ? -1 : 1)*round(p_last.y-p_cur.y)); - - }else + mControlWidget->setCalibCoord3DTransX( + coordTrans_x - (mControlWidget->getCalibCoord3DSwapX() ? -1 : 1) * round(p_last.x - p_cur.x)); + mControlWidget->setCalibCoord3DTransY( + coordTrans_y - (mControlWidget->getCalibCoord3DSwapY() ? -1 : 1) * round(p_last.y - p_cur.y)); + } + else { - mControlWidget->setCalibCoordTransX(mControlWidget->getCalibCoordTransX()+(int)(10.*diff.x())); - mControlWidget->setCalibCoordTransY(mControlWidget->getCalibCoordTransY()+(int)(10.*diff.y())); + mControlWidget->setCalibCoordTransX(mControlWidget->getCalibCoordTransX() + (int) (10. * diff.x())); + mControlWidget->setCalibCoordTransY(mControlWidget->getCalibCoordTransY() + (int) (10. * diff.y())); } } - else if (event->buttons() == Qt::MiddleButton) + else if(event->buttons() == Qt::MiddleButton) { - if( mControlWidget->getCalibCoordDimension() == 0 ) + if(mControlWidget->getCalibCoordDimension() == 0) { - mControlWidget->setCalibCoord3DAxeLen(mControlWidget->getCalibCoord3DAxeLen()+(int)(10.*(diff.x()-diff.y()))); - }else + mControlWidget->setCalibCoord3DAxeLen( + mControlWidget->getCalibCoord3DAxeLen() + (int) (10. * (diff.x() - diff.y()))); + } + else { - mControlWidget->setCalibCoordScale(mControlWidget->getCalibCoordScale()+(int)(10.*(diff.x()-diff.y()))); + mControlWidget->setCalibCoordScale( + mControlWidget->getCalibCoordScale() + (int) (10. * (diff.x() - diff.y()))); } } } @@ -148,9 +153,9 @@ void CoordItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void CoordItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (!mControlWidget->getCalibCoordFix()) + if(!mControlWidget->getCalibCoordFix()) { - if (event->button() == Qt::LeftButton) + if(event->button() == Qt::LeftButton) { mouse_x = event->scenePos().x(); mouse_y = event->scenePos().y(); @@ -158,7 +163,8 @@ void CoordItem::mousePressEvent(QGraphicsSceneMouseEvent *event) coordTrans_x = mControlWidget->getCalibCoord3DTransX(); coordTrans_y = mControlWidget->getCalibCoord3DTransY(); } - }else + } + else { QGraphicsItem::mousePressEvent(event); } @@ -166,118 +172,127 @@ void CoordItem::mousePressEvent(QGraphicsSceneMouseEvent *event) void CoordItem::updateData() { - if (!mControlWidget->getCalibCoordFix()) - setFlag(ItemIsMovable); // noetig, damit mouseEvent leftmousebutton weitergegeben wird, aber drag mach ich selber + if(!mControlWidget->getCalibCoordFix()) + setFlag( + ItemIsMovable); // noetig, damit mouseEvent leftmousebutton weitergegeben wird, aber drag mach ich selber else - setFlag(ItemIsMovable, false); // noetig, damit mouseEvent leftmousebutton weitergegeben wird, aber drag mach ich selber + setFlag( + ItemIsMovable, + false); // noetig, damit mouseEvent leftmousebutton weitergegeben wird, aber drag mach ich selber - if( mControlWidget->getCalibCoordDimension() == 1 ) // 2D + if(mControlWidget->getCalibCoordDimension() == 1) // 2D { - double sc = mControlWidget->getCalibCoordScale()/10.; - double tX = mControlWidget->getCalibCoordTransX()/10.; - double tY = mControlWidget->getCalibCoordTransY()/10.; - double ro = mControlWidget->getCalibCoordRotate()/10.; + double sc = mControlWidget->getCalibCoordScale() / 10.; + double tX = mControlWidget->getCalibCoordTransX() / 10.; + double tY = mControlWidget->getCalibCoordTransY() / 10.; + double ro = mControlWidget->getCalibCoordRotate() / 10.; // aktualisierung der transformationsmatrix QTransform matrix; // matrix wird nur bei aenderungen neu bestimmt matrix.translate(tX, tY); matrix.rotate(ro); - matrix.scale(sc/100., sc/100.); - //matrix.shear(tX,tY); + matrix.scale(sc / 100., sc / 100.); + // matrix.shear(tX,tY); setTransform(matrix); - - }else // 3D + } + else // 3D { //////////////////////////////////////// // 3D World-Coordinate-System // //////////////////////////////////////// - if( mMainWindow->getImage()) + if(mMainWindow->getImage()) { + // Reset Matrix - No Matrix Transformations for 3D Coordsystem + // aktualisierung der transformationsmatrix + QTransform matrix; + // matrix wird nur bei aenderungen neu bestimmt + matrix.translate(0, 0); + matrix.rotate(0); + matrix.scale(1, 1); + setTransform(matrix); - // Reset Matrix - No Matrix Transformations for 3D Coordsystem - // aktualisierung der transformationsmatrix - QTransform matrix; - // matrix wird nur bei aenderungen neu bestimmt - matrix.translate(0, 0); - matrix.rotate(0); - matrix.scale(1, 1); - setTransform(matrix); - - double axeLen = mControlWidget->getCalibCoord3DAxeLen(); - int bS = mMainWindow->getImageBorderSize(); + double axeLen = mControlWidget->getCalibCoord3DAxeLen(); + int bS = mMainWindow->getImageBorderSize(); - // Coordinate-system origin at (tX,tY,tZ) - if( extCalib->isSetExtrCalib() ){ + // Coordinate-system origin at (tX,tY,tZ) + if(extCalib->isSetExtrCalib()) + { + ursprung = extCalib->getImagePoint(cv::Point3f(0, 0, 0)); - ursprung = extCalib->getImagePoint(cv::Point3f(0,0,0)); + x3D = cv::Point3f(axeLen, 0, 0); + y3D = cv::Point3f(0, axeLen, 0); + z3D = cv::Point3f(0, 0, axeLen); - x3D = cv::Point3f(axeLen,0,0); - y3D = cv::Point3f(0,axeLen,0); - z3D = cv::Point3f(0,0,axeLen); + // Tests if the origin-point of the coordinate-system is outside the image + if(extCalib->isOutsideImage(ursprung)) + { + return; + } + x3D.x++; + y3D.y++; + z3D.z++; - // Tests if the origin-point of the coordinate-system is outside the image - if( extCalib->isOutsideImage(ursprung) ) - { - return; + // Kuerzt die Koordinaten-Achsen, falls sie aus dem angezeigten Bild raus laufen wuerden + do + { + x3D.x--; + x = extCalib->getImagePoint(x3D); + // tests if the coord system axis are inside the view or outside, if outside short them till they + // are inside the image + } while(x.x < -bS || x.x > mMainWindow->getImage()->width() - bS || x.y < -bS || + x.y > mMainWindow->getImage()->height() - bS); + do + { + y3D.y--; + y = extCalib->getImagePoint(y3D); + } while(y.x < -bS || y.x > mMainWindow->getImage()->width() - bS || y.y < -bS || + y.y > mMainWindow->getImage()->height() - bS); + do + { + z3D.z--; + z = extCalib->getImagePoint(z3D); + } while(z.x < -bS || z.x > mMainWindow->getImage()->width() - bS || z.y < -bS || + z.y > mMainWindow->getImage()->height() - bS); } - x3D.x++; - y3D.y++; - z3D.z++; - - // Kuerzt die Koordinaten-Achsen, falls sie aus dem angezeigten Bild raus laufen wuerden - do{ - x3D.x--; - x = extCalib->getImagePoint(x3D); - // tests if the coord system axis are inside the view or outside, if outside short them till they are inside the image - }while( x.x < -bS || x.x > mMainWindow->getImage()->width()-bS || x.y < -bS || x.y > mMainWindow->getImage()->height()-bS ); - do{ - y3D.y--; - y = extCalib->getImagePoint(y3D); - }while( y.x < -bS || y.x > mMainWindow->getImage()->width()-bS || y.y < -bS || y.y > mMainWindow->getImage()->height()-bS ); - do{ - z3D.z--; - z = extCalib->getImagePoint(z3D); - }while( z.x < -bS || z.x > mMainWindow->getImage()->width()-bS || z.y < -bS || z.y > mMainWindow->getImage()->height()-bS ); - } } prepareGeometryChange(); - } - if (!mMainWindow->isLoading()){ + if(!mMainWindow->isLoading()) + { mMainWindow->updateImage(); } } -void CoordItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) +void CoordItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { bool debug = false; - if( debug ) debout << "**************** CoordItem:paint() aufgerufen" << std::endl; - if( debug ) debout << "show coord: " << mControlWidget->getCalibCoordShow() << std::endl; + if(debug) + debout << "**************** CoordItem:paint() aufgerufen" << std::endl; + if(debug) + debout << "show coord: " << mControlWidget->getCalibCoordShow() << std::endl; //////////////////////////////// // Drawing Calibration Points // //////////////////////////////// - if( mControlWidget->getCalibExtrCalibPointsShow() && mControlWidget->getCalibCoordDimension() == 0 ) + if(mControlWidget->getCalibExtrCalibPointsShow() && mControlWidget->getCalibCoordDimension() == 0) { - - if( extCalib->isSetExtrCalib() ) + if(extCalib->isSetExtrCalib()) { - QFont font; font.setBold(mControlWidget->trackNumberBold->checkState() == Qt::Checked); font.setPixelSize(mControlWidget->trackNumberSize->value()); painter->setFont(font); - for(size_t i=0; i< extCalib->get2DList().size(); i++) + for(size_t i = 0; i < extCalib->get2DList().size(); i++) { painter->setPen(Qt::red); painter->setBrush(Qt::NoBrush); // Original 2D-Pixel-Points cv::Point2f p2 = extCalib->get2DList().at(i); - painter->drawEllipse(p2.x-8,p2.y-8,16,16); + painter->drawEllipse(p2.x - 8, p2.y - 8, 16, 16); // general configuration painter->setPen(Qt::blue); @@ -295,398 +310,437 @@ void CoordItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*optio cv::Point2f p3 = extCalib->getImagePoint(p3d); - painter->drawEllipse(p3.x-4,p3.y-4,8,8); + painter->drawEllipse(p3.x - 4, p3.y - 4, 8, 8); // Connecting-line Pixel-3D-Points - painter->drawLine(QPointF(p2.x,p2.y),QPointF(p3.x,p3.y)); + painter->drawLine(QPointF(p2.x, p2.y), QPointF(p3.x, p3.y)); // Show point number painter->setPen(Qt::black); painter->setBrush(Qt::black); - painter->drawText(QPointF(p2.x+10,p2.y+font.pixelSize()), QObject::tr("%1").arg((i+1))); - - if( p2.x < calibPointsMin.x ) calibPointsMin.x = p2.x; - if( p2.x > calibPointsMax.x ) calibPointsMax.x = p2.x; - if( p3.x < calibPointsMin.x ) calibPointsMin.x = p3.x; - if( p3.x > calibPointsMax.x ) calibPointsMax.x = p3.x; - - if( p2.y < calibPointsMin.y ) calibPointsMin.y = p2.y; - if( p2.y > calibPointsMax.y ) calibPointsMax.y = p2.y; - if( p3.y < calibPointsMin.y ) calibPointsMin.y = p3.y; - if( p3.y > calibPointsMax.y ) calibPointsMax.y = p3.y; - + painter->drawText(QPointF(p2.x + 10, p2.y + font.pixelSize()), QObject::tr("%1").arg((i + 1))); + + if(p2.x < calibPointsMin.x) + calibPointsMin.x = p2.x; + if(p2.x > calibPointsMax.x) + calibPointsMax.x = p2.x; + if(p3.x < calibPointsMin.x) + calibPointsMin.x = p3.x; + if(p3.x > calibPointsMax.x) + calibPointsMax.x = p3.x; + + if(p2.y < calibPointsMin.y) + calibPointsMin.y = p2.y; + if(p2.y > calibPointsMax.y) + calibPointsMax.y = p2.y; + if(p3.y < calibPointsMin.y) + calibPointsMin.y = p3.y; + if(p3.y > calibPointsMax.y) + calibPointsMax.y = p3.y; } } } - if (mControlWidget->getCalibCoordShow()) + if(mControlWidget->getCalibCoordShow()) { // general configuration painter->setPen(Qt::blue); - painter->setBrush(QBrush(Qt::blue,Qt::SolidPattern)); + painter->setBrush(QBrush(Qt::blue, Qt::SolidPattern)); - if ( mControlWidget->getCalibCoordDimension() == 1 ) // 2D + if(mControlWidget->getCalibCoordDimension() == 1) // 2D { ////////////////////////// // 2D Coordinate-System // ////////////////////////// - painter->setPen(QPen(QBrush(Qt::blue),0)); + painter->setPen(QPen(QBrush(Qt::blue), 0)); static QPointF points[3]; // Koordinatenachsen - points[0].setX(-10.); points[0].setY(0.); - points[1].setX(100.); points[1].setY(0.); + points[0].setX(-10.); + points[0].setY(0.); + points[1].setX(100.); + points[1].setY(0.); painter->drawLine(points[0], points[1]); - points[0].setX(0.); points[0].setY(10.); - points[1].setX(0.); points[1].setY(-100.); + points[0].setX(0.); + points[0].setY(10.); + points[1].setX(0.); + points[1].setY(-100.); painter->drawLine(points[0], points[1]); // Ticks - for (int i=1; i<11; i++) // i=10 zeichnen sieht ungewoehnlich aus, laeest sich aber besser mit messen + for(int i = 1; i < 11; i++) // i=10 zeichnen sieht ungewoehnlich aus, laeest sich aber besser mit messen { - points[0].setX(2.); points[0].setY(-i*10.); - points[1].setX(-2.); points[1].setY(-i*10.); + points[0].setX(2.); + points[0].setY(-i * 10.); + points[1].setX(-2.); + points[1].setY(-i * 10.); painter->drawLine(points[0], points[1]); - points[0].setX(i*10.); points[0].setY(2.); - points[1].setX(i*10.); points[1].setY(-2.); + points[0].setX(i * 10.); + points[0].setY(2.); + points[1].setX(i * 10.); + points[1].setY(-2.); painter->drawLine(points[0], points[1]); } // Beschriftung - points[0].setX(97.); points[0].setY(12.); + points[0].setX(97.); + points[0].setY(12.); painter->drawText(points[0], QObject::tr("1")); - points[0].setX(-8.); points[0].setY(-97.); + points[0].setX(-8.); + points[0].setY(-97.); painter->drawText(points[0], QObject::tr("1")); // Pfeilspitzen painter->setPen(Qt::NoPen); painter->setBrush(Qt::blue); - points[0].setX(100.);points[0].setY(0.); - points[1].setX(95.); points[1].setY(2.); - points[2].setX(95.); points[2].setY(-2.); + points[0].setX(100.); + points[0].setY(0.); + points[1].setX(95.); + points[1].setY(2.); + points[2].setX(95.); + points[2].setY(-2.); painter->drawPolygon(points, 3); - points[0].setX(0.); points[0].setY(-100.); - points[1].setX(2.); points[1].setY(-95.); - points[2].setX(-2.); points[2].setY(-95.); + points[0].setX(0.); + points[0].setY(-100.); + points[1].setX(2.); + points[1].setY(-95.); + points[2].setX(-2.); + points[2].setY(-95.); painter->drawPolygon(points, 3); - }else + } + else { - double tX3D = mControlWidget->getCalibCoord3DTransX(); - double tY3D = mControlWidget->getCalibCoord3DTransY(); - double tZ3D = mControlWidget->getCalibCoord3DTransZ(); + double tX3D = mControlWidget->getCalibCoord3DTransX(); + double tY3D = mControlWidget->getCalibCoord3DTransY(); + double tZ3D = mControlWidget->getCalibCoord3DTransZ(); double axeLen = mControlWidget->getCalibCoord3DAxeLen(); qreal coordLineWidth = 2.0; - if( extCalib->isSetExtrCalib() ){ + if(extCalib->isSetExtrCalib()) + { + QPointF points[4]; + cv::Point2f p[4]; + QString coordinaten; - QPointF points[4]; - cv::Point2f p[4]; - QString coordinaten; + ///////////////////////////////////////////////////// + // Draw a cube (Quader) near coord system // + ///////////////////////////////////////////////////// - ///////////////////////////////////////////////////// - // Draw a cube (Quader) near coord system // - ///////////////////////////////////////////////////// + bool drawCube = false; - bool drawCube = false; + if(drawCube) + { + painter->setPen(Qt::green); + // Boden + p[0] = extCalib->getImagePoint(cv::Point3f(100, 100, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(200, 100, 0)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(200, 100, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(200, 200, 0)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(200, 200, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(100, 200, 0)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(100, 200, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(100, 100, 0)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + // Seiten + p[0] = extCalib->getImagePoint(cv::Point3f(100, 100, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(100, 100, 100)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(200, 100, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(200, 100, 100)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(100, 200, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(100, 200, 100)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(200, 200, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(200, 200, 100)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + // Oben + p[0] = extCalib->getImagePoint(cv::Point3f(100, 100, 100)); + p[1] = extCalib->getImagePoint(cv::Point3f(200, 100, 100)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(200, 100, 100)); + p[1] = extCalib->getImagePoint(cv::Point3f(200, 200, 100)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(200, 200, 100)); + p[1] = extCalib->getImagePoint(cv::Point3f(100, 200, 100)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(100, 200, 100)); + p[1] = extCalib->getImagePoint(cv::Point3f(100, 100, 100)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + } - if( drawCube ){ - painter->setPen(Qt::green); - // Boden - p[0] = extCalib->getImagePoint(cv::Point3f(100,100,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(200,100,0)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(200,100,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(200,200,0)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(200,200,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(100,200,0)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(100,200,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(100,100,0)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - // Seiten - p[0] = extCalib->getImagePoint(cv::Point3f(100,100,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(100,100,100)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(200,100,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(200,100,100)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(100,200,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(100,200,100)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(200,200,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(200,200,100)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - // Oben - p[0] = extCalib->getImagePoint(cv::Point3f(100,100,100)); - p[1] = extCalib->getImagePoint(cv::Point3f(200,100,100)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(200,100,100)); - p[1] = extCalib->getImagePoint(cv::Point3f(200,200,100)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(200,200,100)); - p[1] = extCalib->getImagePoint(cv::Point3f(100,200,100)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(100,200,100)); - p[1] = extCalib->getImagePoint(cv::Point3f(100,100,100)); - painter->drawLine(QPointF(p[0].x,p[0].y), QPointF(p[1].x, p[1].y)); + ///////////////////////////////////////////////////// + // Draw the bounding rect // + ///////////////////////////////////////////////////// + bool drawBoundingRect = false; - } + if(drawBoundingRect) + { + QRectF boundingBox = boundingRect(); + double min_x = boundingBox.x(), max_x = min_x + boundingBox.width(); + double min_y = boundingBox.y(), max_y = min_y + boundingBox.height(); + + painter->setPen(Qt::cyan); + painter->drawLine(QPointF(min_x, min_y), QPointF(min_x, max_y)); + painter->drawLine(QPointF(min_x, max_y), QPointF(max_x, max_y)); + painter->drawLine(QPointF(max_x, max_y), QPointF(max_x, min_y)); + painter->drawLine(QPointF(max_x, min_y), QPointF(min_x, min_y)); + } - ///////////////////////////////////////////////////// - // Draw the bounding rect // - ///////////////////////////////////////////////////// + ///////////////////////////////////////////////////// + // Draw a rect around the whole coordinate system // + ///////////////////////////////////////////////////// - bool drawBoundingRect = false; + bool paintRectCoordArea = false; - if( drawBoundingRect ) - { - QRectF boundingBox = boundingRect(); - double min_x = boundingBox.x(), max_x = min_x+boundingBox.width(); - double min_y = boundingBox.y(), max_y = min_y+boundingBox.height(); - - painter->setPen(Qt::cyan); - painter->drawLine(QPointF(min_x, min_y), QPointF(min_x, max_y)); - painter->drawLine(QPointF(min_x, max_y), QPointF(max_x, max_y)); - painter->drawLine(QPointF(max_x, max_y), QPointF(max_x, min_y)); - painter->drawLine(QPointF(max_x, min_y), QPointF(min_x, min_y)); - } + if(paintRectCoordArea) + { + int min_x = std::min(std::min(x.x, y.x), std::min(z.x, ursprung.x)); + int max_x = std::max(std::max(x.x, y.x), std::max(z.x, ursprung.x)); - ///////////////////////////////////////////////////// - // Draw a rect around the whole coordinate system // - ///////////////////////////////////////////////////// + int min_y = std::min(std::min(x.y, y.y), std::min(z.y, ursprung.y)); + int max_y = std::max(std::max(x.y, y.y), std::max(z.y, ursprung.y)); - bool paintRectCoordArea = false; + painter->setFont(QFont("Arial", 20)); - if( paintRectCoordArea ) - { - int min_x = std::min(std::min(x.x,y.x),std::min(z.x,ursprung.x)); - int max_x = std::max(std::max(x.x,y.x),std::max(z.x,ursprung.x)); + painter->setPen(Qt::green); - int min_y = std::min(std::min(x.y,y.y),std::min(z.y,ursprung.y)); - int max_y = std::max(std::max(x.y,y.y),std::max(z.y,ursprung.y)); + painter->drawLine(QPointF(min_x, min_y), QPointF(min_x, max_y)); + painter->drawLine(QPointF(min_x, max_y), QPointF(max_x, max_y)); + painter->drawLine(QPointF(max_x, max_y), QPointF(max_x, min_y)); + painter->drawLine(QPointF(max_x, min_y), QPointF(min_x, min_y)); - painter->setFont(QFont("Arial", 20)); + coordinaten = QString::asprintf("(%d, %d)", min_x, min_y); + painter->drawText(QPoint(min_x - 45, min_y - 10), coordinaten); - painter->setPen(Qt::green); + coordinaten = QString::asprintf("%d", max_y - min_y); + painter->drawText(QPoint(min_x + 10, min_y + (max_y - min_y) / 2.0), coordinaten); - painter->drawLine(QPointF(min_x, min_y), QPointF(min_x, max_y)); - painter->drawLine(QPointF(min_x, max_y), QPointF(max_x, max_y)); - painter->drawLine(QPointF(max_x, max_y), QPointF(max_x, min_y)); - painter->drawLine(QPointF(max_x, min_y), QPointF(min_x, min_y)); + coordinaten = QString::asprintf("%d", max_x - min_x); + painter->drawText(QPoint(min_x + (max_x - min_x) / 2.0, min_y + 30), coordinaten); + } - coordinaten = QString::asprintf("(%d, %d)", min_x, min_y); - painter->drawText(QPoint(min_x-45, min_y-10), coordinaten); - coordinaten = QString::asprintf("%d", max_y - min_y); - painter->drawText(QPoint(min_x+10,min_y+(max_y-min_y)/2.0), coordinaten); + ////////////////////////////// + // Drawing the X,Y,Z - Axis // + ////////////////////////////// - coordinaten = QString::asprintf("%d", max_x - min_x); - painter->drawText(QPoint(min_x+(max_x-min_x)/2.0,min_y+30), coordinaten); - } + painter->setPen(QPen(QBrush(Qt::blue), coordLineWidth)); + p[0] = extCalib->getImagePoint(cv::Point3f(0, 0, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(x3D.x, x3D.y, x3D.z)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[1] = extCalib->getImagePoint(cv::Point3f(y3D.x, y3D.y, y3D.z)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[1] = extCalib->getImagePoint(cv::Point3f(z3D.x, z3D.y, z3D.z)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + ///////////////////////////////// + // Drawing the X,Y,Z - Symbols // + ///////////////////////////////// - ////////////////////////////// - // Drawing the X,Y,Z - Axis // - ////////////////////////////// + painter->setPen(QPen(QBrush(Qt::black), coordLineWidth)); + painter->setFont(QFont("Arial", 15)); - painter->setPen(QPen(QBrush(Qt::blue),coordLineWidth)); - p[0] = extCalib->getImagePoint(cv::Point3f(0,0,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(x3D.x,x3D.y,x3D.z)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - p[1] = extCalib->getImagePoint(cv::Point3f(y3D.x,y3D.y,y3D.z)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - p[1] = extCalib->getImagePoint(cv::Point3f(z3D.x,z3D.y,z3D.z)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(x3D.x + 10, x3D.y, x3D.z)); + painter->drawText(QPointF(p[0].x - 5, p[0].y + 5), QString("X")); + p[0] = extCalib->getImagePoint(cv::Point3f(y3D.x, y3D.y + 10, y3D.z)); + painter->drawText(QPointF(p[0].x - 5, p[0].y + 5), QString("Y")); + p[0] = extCalib->getImagePoint(cv::Point3f(z3D.x, z3D.y, z3D.z + 10)); + painter->drawText(QPointF(p[0].x - 5, p[0].y + 5), QString("Z")); - ///////////////////////////////// - // Drawing the X,Y,Z - Symbols // - ///////////////////////////////// - painter->setPen(QPen(QBrush(Qt::black),coordLineWidth)); - painter->setFont(QFont("Arial", 15 )); + if(debug) + debout << "Ursprungskoordinaten: " << ursprung.x << ", " << ursprung.y << std::endl; + if(debug) + debout << "Bildsize: " << mMainWindow->getImage()->width() << "x" + << mMainWindow->getImage()->height() << std::endl; + if(debug) + coordinaten = QString::asprintf("(%f %f %f)", tX3D, tY3D, tZ3D); - p[0] = extCalib->getImagePoint(cv::Point3f(x3D.x+10, x3D.y, x3D.z)); - painter->drawText(QPointF(p[0].x-5,p[0].y+5), QString("X")); - p[0] = extCalib->getImagePoint(cv::Point3f(y3D.x, y3D.y+10, y3D.z)); - painter->drawText(QPointF(p[0].x-5,p[0].y+5), QString("Y")); - p[0] = extCalib->getImagePoint(cv::Point3f(z3D.x, z3D.y, z3D.z+10)); - painter->drawText(QPointF(p[0].x-5,p[0].y+5), QString("Z")); + ////////////////////////////// + // Drawing the tick-markers // + ////////////////////////////// + int tickLength = AXIS_MARKERS_LENGTH; + painter->setPen(QPen(QBrush(Qt::blue), coordLineWidth)); - if( debug ) debout << "Ursprungskoordinaten: " << ursprung.x << ", " << ursprung.y << std::endl; - if( debug ) debout << "Bildsize: " << mMainWindow->getImage()->width() << "x" << mMainWindow->getImage()->height() << std::endl; - if( debug ) coordinaten = QString::asprintf("(%f %f %f)", tX3D, tY3D, tZ3D); + // Start bei 100cm bis Achsen-Laenge-Pfeilspitzenlaenge alle 100cm + for(int i = 100; i < axeLen - tickLength; i += 100) + { + // Solange Achsen-Ende noch nicht erreicht: Markierung zeichnen + if(i + tickLength < x3D.x) + { + p[0] = extCalib->getImagePoint(cv::Point3f(i, -tickLength, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(i, tickLength, 0)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(i, 0, -tickLength)); + p[1] = extCalib->getImagePoint(cv::Point3f(i, 0, tickLength)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(i, 0, 0)); + } + if(i + tickLength < y3D.y) + { + p[0] = extCalib->getImagePoint(cv::Point3f(-tickLength, i, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(tickLength, i, 0)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(0, i, -tickLength)); + p[1] = extCalib->getImagePoint(cv::Point3f(0, i, tickLength)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + } + if(i + tickLength < z3D.z) + { + p[0] = extCalib->getImagePoint(cv::Point3f(-tickLength, 0, i)); + p[1] = extCalib->getImagePoint(cv::Point3f(tickLength, 0, i)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(0, -tickLength, i)); + p[1] = extCalib->getImagePoint(cv::Point3f(0, tickLength, i)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + } + } - ////////////////////////////// - // Drawing the tick-markers // - ////////////////////////////// + QFont font("Arial", tickLength * 0.5); + painter->setFont(font); - int tickLength = AXIS_MARKERS_LENGTH; - painter->setPen(QPen(QBrush(Qt::blue),coordLineWidth)); + painter->setPen(Qt::green); + painter->setBrush(Qt::green); + painter->setFont(QFont("Arial", 20)); - // Start bei 100cm bis Achsen-Laenge-Pfeilspitzenlaenge alle 100cm - for(int i=100;i<axeLen-tickLength;i+=100) - { - // Solange Achsen-Ende noch nicht erreicht: Markierung zeichnen - if( i+tickLength < x3D.x ) - { - p[0] = extCalib->getImagePoint(cv::Point3f(i,-tickLength,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(i, tickLength,0)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(i,0,-tickLength)); - p[1] = extCalib->getImagePoint(cv::Point3f(i,0, tickLength)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(i,0,0)); - } - if( i+tickLength < y3D.y ) - { - p[0] = extCalib->getImagePoint(cv::Point3f(-tickLength,i,0)); - p[1] = extCalib->getImagePoint(cv::Point3f( tickLength,i,0)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(0,i,-tickLength)); - p[1] = extCalib->getImagePoint(cv::Point3f(0,i, tickLength)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - } - if( i+tickLength < z3D.z ) - { - p[0] = extCalib->getImagePoint(cv::Point3f(-tickLength,0,i)); - p[1] = extCalib->getImagePoint(cv::Point3f( tickLength,0,i)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(0,-tickLength,i)); - p[1] = extCalib->getImagePoint(cv::Point3f(0, tickLength,i)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - } - } + if(debug) + coordinaten = QString::asprintf("(%.2f, %.2f)", ursprung.x, ursprung.y); + if(debug) + painter->drawText(QPoint(ursprung.x - 100, ursprung.y), coordinaten); - QFont font("Arial", tickLength*0.5 ); - painter->setFont(font); + ////////////////////////////////////////////// + // Drawing the peaks at the end of the axis // + ////////////////////////////////////////////// + + int peakSize = AXIS_MARKERS_LENGTH; - painter->setPen(Qt::green); - painter->setBrush(Qt::green); - painter->setFont(QFont("Arial", 20)); - - if( debug ) coordinaten = QString::asprintf("(%.2f, %.2f)", ursprung.x,ursprung.y); - if( debug ) painter->drawText(QPoint(ursprung.x-100,ursprung.y),coordinaten); - - ////////////////////////////////////////////// - // Drawing the peaks at the end of the axis // - ////////////////////////////////////////////// - - int peakSize = AXIS_MARKERS_LENGTH; - - /////// - // X // - /////// - - p[0] = extCalib->getImagePoint(cv::Point3f(x3D.x,0,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(x3D.x-peakSize,-peakSize,0)); - p[2] = extCalib->getImagePoint(cv::Point3f(x3D.x-peakSize, peakSize,0)); - points[0] = QPointF(p[0].x,p[0].y); - points[1] = QPointF(p[1].x,p[1].y); - points[2] = QPointF(p[2].x,p[2].y); - painter->setPen(Qt::green); - painter->setPen(QPen(QBrush(Qt::blue),coordLineWidth)); - painter->drawLine(points[0],points[1]); - painter->drawLine(points[0],points[2]); - painter->drawLine(points[2],points[1]); - p[0] = extCalib->getImagePoint(cv::Point3f(x3D.x,0,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(x3D.x-peakSize,0,-peakSize)); - p[2] = extCalib->getImagePoint(cv::Point3f(x3D.x-peakSize,0, peakSize)); - p[3] = extCalib->getImagePoint(cv::Point3f(x3D.x+peakSize,0,0)); - points[0] = QPointF(p[0].x,p[0].y); - points[1] = QPointF(p[1].x,p[1].y); - points[2] = QPointF(p[2].x,p[2].y); - painter->setPen(Qt::green); - painter->setPen(QPen(QBrush(Qt::blue),coordLineWidth)); - painter->drawLine(points[0],points[1]); - painter->drawLine(points[0],points[2]); - painter->drawLine(points[2],points[1]); - - if( debug ) coordinaten = QString::asprintf("(% .2f, % .2f)", p[1].x,p[1].y); - if( debug ) painter->drawText(QPoint(p[3].x,p[3].y),coordinaten); - - if( debug ) coordinaten = QString::fromLatin1("X"); - if( debug ) painter->drawText(QPoint(p[1].x,p[1].y),coordinaten); - - /////// - // Y // - /////// - - p[0] = extCalib->getImagePoint(cv::Point3f(0,y3D.y,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(-peakSize,y3D.y-peakSize,0)); - p[2] = extCalib->getImagePoint(cv::Point3f( peakSize,y3D.y-peakSize,0)); - points[0] = QPointF(p[0].x,p[0].y); - points[1] = QPointF(p[1].x,p[1].y); - points[2] = QPointF(p[2].x,p[2].y); - painter->setPen(Qt::green); - painter->setPen(QPen(QBrush(Qt::blue),coordLineWidth)); - painter->drawLine(points[0],points[1]); - painter->drawLine(points[0],points[2]); - painter->drawLine(points[2],points[1]); - p[0] = extCalib->getImagePoint(cv::Point3f(0,y3D.y,0)); - p[1] = extCalib->getImagePoint(cv::Point3f(0,y3D.y-peakSize,-peakSize)); - p[2] = extCalib->getImagePoint(cv::Point3f(0,y3D.y-peakSize, peakSize)); - p[3] = extCalib->getImagePoint(cv::Point3f(0,y3D.y+peakSize,0)); - points[0] = QPointF(p[0].x,p[0].y); - points[1] = QPointF(p[1].x,p[1].y); - points[2] = QPointF(p[2].x,p[2].y); - painter->setPen(Qt::green); - painter->setPen(QPen(QBrush(Qt::blue),coordLineWidth)); - painter->drawLine(points[0],points[1]); - painter->drawLine(points[0],points[2]); - painter->drawLine(points[2],points[1]); - - if( debug ) coordinaten = QString::asprintf("(%.2f, %.2f)", p[1].x,p[1].y); - if( debug ) painter->drawText(QPoint(p[3].x,p[3].y),coordinaten); - - if( debug ) coordinaten = QString::fromLatin1("Y"); - if( debug ) painter->drawText(QPoint(p[1].x,p[1].y),coordinaten); - - /////// - // Z // - /////// - - p[0] = extCalib->getImagePoint(cv::Point3f(0,0,z3D.z)); - p[1] = extCalib->getImagePoint(cv::Point3f(0,-peakSize,z3D.z-peakSize)); - p[2] = extCalib->getImagePoint(cv::Point3f(0, peakSize,z3D.z-peakSize)); - points[0] = QPointF(p[0].x,p[0].y); - points[1] = QPointF(p[1].x,p[1].y); - points[2] = QPointF(p[2].x,p[2].y); - painter->setPen(Qt::green); - painter->setPen(QPen(QBrush(Qt::blue),coordLineWidth)); - painter->drawLine(points[0],points[1]); - painter->drawLine(points[0],points[2]); - painter->drawLine(points[2],points[1]); - p[0] = extCalib->getImagePoint(cv::Point3f(0,0,z3D.z)); - p[1] = extCalib->getImagePoint(cv::Point3f(-peakSize,0,z3D.z-peakSize)); - p[2] = extCalib->getImagePoint(cv::Point3f( peakSize,0,z3D.z-peakSize)); - p[3] = extCalib->getImagePoint(cv::Point3f(0,0,z3D.z+peakSize)); - points[0] = QPointF(p[0].x,p[0].y); - points[1] = QPointF(p[1].x,p[1].y); - points[2] = QPointF(p[2].x,p[2].y); - painter->setPen(Qt::green); - painter->setPen(QPen(QBrush(Qt::blue),coordLineWidth)); - painter->drawLine(points[0],points[1]); - painter->drawLine(points[0],points[2]); - painter->drawLine(points[2],points[1]); - - if( debug ) coordinaten = QString::asprintf("(%.2f, %.2f)", p[1].x,p[1].y); - if( debug ) painter->drawText(QPoint(p[3].x,p[3].y),coordinaten); - - if( debug ) coordinaten = QString::fromLatin1("Z"); - if( debug ) painter->drawText(QPoint(p[1].x,p[1].y),coordinaten); + /////// + // X // + /////// + p[0] = extCalib->getImagePoint(cv::Point3f(x3D.x, 0, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(x3D.x - peakSize, -peakSize, 0)); + p[2] = extCalib->getImagePoint(cv::Point3f(x3D.x - peakSize, peakSize, 0)); + points[0] = QPointF(p[0].x, p[0].y); + points[1] = QPointF(p[1].x, p[1].y); + points[2] = QPointF(p[2].x, p[2].y); + painter->setPen(Qt::green); + painter->setPen(QPen(QBrush(Qt::blue), coordLineWidth)); + painter->drawLine(points[0], points[1]); + painter->drawLine(points[0], points[2]); + painter->drawLine(points[2], points[1]); + p[0] = extCalib->getImagePoint(cv::Point3f(x3D.x, 0, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(x3D.x - peakSize, 0, -peakSize)); + p[2] = extCalib->getImagePoint(cv::Point3f(x3D.x - peakSize, 0, peakSize)); + p[3] = extCalib->getImagePoint(cv::Point3f(x3D.x + peakSize, 0, 0)); + points[0] = QPointF(p[0].x, p[0].y); + points[1] = QPointF(p[1].x, p[1].y); + points[2] = QPointF(p[2].x, p[2].y); + painter->setPen(Qt::green); + painter->setPen(QPen(QBrush(Qt::blue), coordLineWidth)); + painter->drawLine(points[0], points[1]); + painter->drawLine(points[0], points[2]); + painter->drawLine(points[2], points[1]); + + if(debug) + coordinaten = QString::asprintf("(% .2f, % .2f)", p[1].x, p[1].y); + if(debug) + painter->drawText(QPoint(p[3].x, p[3].y), coordinaten); + + if(debug) + coordinaten = QString::fromLatin1("X"); + if(debug) + painter->drawText(QPoint(p[1].x, p[1].y), coordinaten); + + /////// + // Y // + /////// + + p[0] = extCalib->getImagePoint(cv::Point3f(0, y3D.y, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(-peakSize, y3D.y - peakSize, 0)); + p[2] = extCalib->getImagePoint(cv::Point3f(peakSize, y3D.y - peakSize, 0)); + points[0] = QPointF(p[0].x, p[0].y); + points[1] = QPointF(p[1].x, p[1].y); + points[2] = QPointF(p[2].x, p[2].y); + painter->setPen(Qt::green); + painter->setPen(QPen(QBrush(Qt::blue), coordLineWidth)); + painter->drawLine(points[0], points[1]); + painter->drawLine(points[0], points[2]); + painter->drawLine(points[2], points[1]); + p[0] = extCalib->getImagePoint(cv::Point3f(0, y3D.y, 0)); + p[1] = extCalib->getImagePoint(cv::Point3f(0, y3D.y - peakSize, -peakSize)); + p[2] = extCalib->getImagePoint(cv::Point3f(0, y3D.y - peakSize, peakSize)); + p[3] = extCalib->getImagePoint(cv::Point3f(0, y3D.y + peakSize, 0)); + points[0] = QPointF(p[0].x, p[0].y); + points[1] = QPointF(p[1].x, p[1].y); + points[2] = QPointF(p[2].x, p[2].y); + painter->setPen(Qt::green); + painter->setPen(QPen(QBrush(Qt::blue), coordLineWidth)); + painter->drawLine(points[0], points[1]); + painter->drawLine(points[0], points[2]); + painter->drawLine(points[2], points[1]); + + if(debug) + coordinaten = QString::asprintf("(%.2f, %.2f)", p[1].x, p[1].y); + if(debug) + painter->drawText(QPoint(p[3].x, p[3].y), coordinaten); + + if(debug) + coordinaten = QString::fromLatin1("Y"); + if(debug) + painter->drawText(QPoint(p[1].x, p[1].y), coordinaten); + + /////// + // Z // + /////// + + p[0] = extCalib->getImagePoint(cv::Point3f(0, 0, z3D.z)); + p[1] = extCalib->getImagePoint(cv::Point3f(0, -peakSize, z3D.z - peakSize)); + p[2] = extCalib->getImagePoint(cv::Point3f(0, peakSize, z3D.z - peakSize)); + points[0] = QPointF(p[0].x, p[0].y); + points[1] = QPointF(p[1].x, p[1].y); + points[2] = QPointF(p[2].x, p[2].y); + painter->setPen(Qt::green); + painter->setPen(QPen(QBrush(Qt::blue), coordLineWidth)); + painter->drawLine(points[0], points[1]); + painter->drawLine(points[0], points[2]); + painter->drawLine(points[2], points[1]); + p[0] = extCalib->getImagePoint(cv::Point3f(0, 0, z3D.z)); + p[1] = extCalib->getImagePoint(cv::Point3f(-peakSize, 0, z3D.z - peakSize)); + p[2] = extCalib->getImagePoint(cv::Point3f(peakSize, 0, z3D.z - peakSize)); + p[3] = extCalib->getImagePoint(cv::Point3f(0, 0, z3D.z + peakSize)); + points[0] = QPointF(p[0].x, p[0].y); + points[1] = QPointF(p[1].x, p[1].y); + points[2] = QPointF(p[2].x, p[2].y); + painter->setPen(Qt::green); + painter->setPen(QPen(QBrush(Qt::blue), coordLineWidth)); + painter->drawLine(points[0], points[1]); + painter->drawLine(points[0], points[2]); + painter->drawLine(points[2], points[1]); + + if(debug) + coordinaten = QString::asprintf("(%.2f, %.2f)", p[1].x, p[1].y); + if(debug) + painter->drawText(QPoint(p[3].x, p[3].y), coordinaten); + + if(debug) + coordinaten = QString::fromLatin1("Z"); + if(debug) + painter->drawText(QPoint(p[1].x, p[1].y), coordinaten); } } - } } diff --git a/src/ellipse.cpp b/src/ellipse.cpp index b91ffc0605dd4171e4a9c1f16673efc5caf066ca..90a7c478d3ab0db6286ead73bccf8cb516bf5b13 100644 --- a/src/ellipse.cpp +++ b/src/ellipse.cpp @@ -18,14 +18,14 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <cmath> +#include "ellipse.h" + +#include "helper.h" +#include "vector.h" #include <QPointF> #include <QSizeF> - -#include "ellipse.h" -#include "vector.h" -#include "helper.h" +#include <cmath> // Name musste MyEllipse genommen werden, da anscheinend Ellipse schon vergeben ist @@ -35,22 +35,13 @@ // QGraphicsEllipseItem ist sehr umfangreich fuer die repraesentation // kann auch schief stehen, hat aber keine abfragen, ob punkt innerhalb -MyEllipse::MyEllipse() - : - mR1(0), - mR2(0), - mAngle(0) -{ -} -MyEllipse::MyEllipse(double x, double y, double r1, double r2, double angle) - : mC(x, y), - mR1(r1 > r2 ? r1 : r2), - mR2(r1 > r2 ? r2 : r1), - mAngle(angle) +MyEllipse::MyEllipse() : mR1(0), mR2(0), mAngle(0) {} +MyEllipse::MyEllipse(double x, double y, double r1, double r2, double angle) : + mC(x, y), mR1(r1 > r2 ? r1 : r2), mR2(r1 > r2 ? r2 : r1), mAngle(angle) { double dist = sqrt(mR1 * mR1 - mR2 * mR2); // distance of focal points from centre - mF1 = mC + Vec2F::fromAngle(angle) * dist; - mF2 = mC - Vec2F::fromAngle(angle) * dist; + mF1 = mC + Vec2F::fromAngle(angle) * dist; + mF2 = mC - Vec2F::fromAngle(angle) * dist; } MyEllipse::MyEllipse(QPointF center, QSizeF size, double angle) { @@ -68,21 +59,22 @@ QSizeF MyEllipse::size() const double MyEllipse::area() const { - return PI*mR1*mR2; + return PI * mR1 * mR2; } /// only estimation, because of complex elliptical integral double MyEllipse::outline() const { - return PI*(1.5*(mR1+mR2) - sqrt(mR1*mR2)); + return PI * (1.5 * (mR1 + mR2) - sqrt(mR1 * mR2)); // weitere Moeglichkeiten, siehe http://de.wikipedia.org/wiki/Ellipse#Formelsammlung_Fl.C3.A4cheninhalt_und_Umfang - //return PI*(mR1+mR2)*(1+(3*((mR1-mR2)/(mR1+mR2))*((mR1-mR2)/(mR1+mR2)))/(10+sqrt(4-(3*((mR1-mR2)/(mR1+mR2))*((mR1-mR2)/(mR1+mR2)))))); - //return PI*sqrt(2.*(mR1*mR1+mR2*mR2)); - //return PI*(mR1+mR2); + // return + // PI*(mR1+mR2)*(1+(3*((mR1-mR2)/(mR1+mR2))*((mR1-mR2)/(mR1+mR2)))/(10+sqrt(4-(3*((mR1-mR2)/(mR1+mR2))*((mR1-mR2)/(mR1+mR2)))))); + // return PI*sqrt(2.*(mR1*mR1+mR2*mR2)); + // return PI*(mR1+mR2); } /// is point p inside or on the ellipse -bool MyEllipse::isInside(const Vec2F& p) const +bool MyEllipse::isInside(const Vec2F &p) const { // for a point to be inside the ellipse the sum of the // distances from both focal points must be <= 2 * mR1 @@ -94,18 +86,15 @@ bool MyEllipse::isInside(double x, double y) const } bool MyEllipse::isNearlyCircle() const { - return ratio()<1.3; + return ratio() < 1.3; } void MyEllipse::draw(cv::Mat &img, int r, int g, int b) const { cv::Size size; - size.width = myRound(mR1); - size.height = myRound(mR2); - Vec2F centerVec = center(); + size.width = myRound(mR1); + size.height = myRound(mR2); + Vec2F centerVec = center(); cv::Point centerPoint(centerVec.x(), centerVec.y()); - cv::ellipse(img, centerPoint, size, 180*mAngle/PI, 0, 360, cv::Scalar(r,g,b), 1, cv::LINE_AA, 0); + cv::ellipse(img, centerPoint, size, 180 * mAngle / PI, 0, 360, cv::Scalar(r, g, b), 1, cv::LINE_AA, 0); } - - - diff --git a/src/extrCalibration.cpp b/src/extrCalibration.cpp index 2bab8906047e94349ed8da85fe455a6e1b857e5f..3def6fd03c29c5a991c60fcb88ec18a6d2d6f5c7 100644 --- a/src/extrCalibration.cpp +++ b/src/extrCalibration.cpp @@ -18,39 +18,38 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> -#include <QFileDialog> - #include "extrCalibration.h" + +#include "control.h" #include "pMessageBox.h" #include "petrack.h" -#include "control.h" + +#include <QFileDialog> +#include <QtWidgets> #define MAX_AV_ERROR 20 ExtrCalibration::ExtrCalibration() { - mMainWindow = nullptr; + mMainWindow = nullptr; mControlWidget = nullptr; } -ExtrCalibration::~ExtrCalibration() -{ -} +ExtrCalibration::~ExtrCalibration() {} void ExtrCalibration::setMainWindow(Petrack *mw) { - mMainWindow = mw; + mMainWindow = mw; mControlWidget = mw->getControlWidget(); init(); } void ExtrCalibration::init() { - rotation_matrix = new double[9]; - translation_vector = new double[3]; + rotation_matrix = new double[9]; + translation_vector = new double[3]; translation_vector2 = new double[3]; - camValues = new double[9]; + camValues = new double[9]; distValues = new double[8]; isExtCalib = false; @@ -67,30 +66,33 @@ void ExtrCalibration::setExtrCalibFile(const QString &f) QString ExtrCalibration::getExtrCalibFile() { - if (!this->isEmptyExtrCalibFile()) + if(!this->isEmptyExtrCalibFile()) return mExtrCalibFile; else return QString(); } -bool ExtrCalibration::openExtrCalibFile(){ - - if (mMainWindow) +bool ExtrCalibration::openExtrCalibFile() +{ + if(mMainWindow) { static QString lastDir; - if (!mExtrCalibFile.isEmpty()) + if(!mExtrCalibFile.isEmpty()) lastDir = QFileInfo(mExtrCalibFile).path(); - QString extrCalibFile = QFileDialog::getOpenFileName(mMainWindow, Petrack::tr("Open extrinisc calibration file with point correspondences"), lastDir, "3D-Calibration-File (*.3dc);;Text (*.txt);;All supported types (*.3dc *.txt);;All files (*.*)"); - if (!extrCalibFile.isEmpty()) + QString extrCalibFile = QFileDialog::getOpenFileName( + mMainWindow, + Petrack::tr("Open extrinisc calibration file with point correspondences"), + lastDir, + "3D-Calibration-File (*.3dc);;Text (*.txt);;All supported types (*.3dc *.txt);;All files (*.*)"); + if(!extrCalibFile.isEmpty()) { mExtrCalibFile = extrCalibFile; return loadExtrCalibFile(); } } return false; - } /** @@ -115,18 +117,21 @@ bool ExtrCalibration::openExtrCalibFile(){ * * @return */ -bool ExtrCalibration::loadExtrCalibFile(){ - +bool ExtrCalibration::loadExtrCalibFile() +{ bool all_ok = true; - if( !mExtrCalibFile.isEmpty() ) + if(!mExtrCalibFile.isEmpty()) { - if( mExtrCalibFile.right(4) == ".3dc" || mExtrCalibFile.right(4) == ".txt" ) + if(mExtrCalibFile.right(4) == ".3dc" || mExtrCalibFile.right(4) == ".txt") { QFile file(mExtrCalibFile); - if( !file.open(QIODevice::ReadOnly | QIODevice::Text) ) + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - PCritical(mMainWindow, QObject::tr("Petrack"), QObject::tr("Error: Cannot open %1:\n%2.").arg(mExtrCalibFile, file.errorString())); + PCritical( + mMainWindow, + QObject::tr("Petrack"), + QObject::tr("Error: Cannot open %1:\n%2.").arg(mExtrCalibFile, file.errorString())); return false; } @@ -137,133 +142,146 @@ bool ExtrCalibration::loadExtrCalibFile(){ std::vector<cv::Point2f> points2D_tmp; QTextStream in(&file); - QString line; - int line_counter = 0, counter; - float x,y,z,px,py; - float zahl; - bool with_2D_data = false, - with_3D_data = false, - end_loop = false; + QString line; + int line_counter = 0, counter; + float x, y, z, px, py; + float zahl; + bool with_2D_data = false, with_3D_data = false, end_loop = false; // Exit loop when reaching the end of the file - while( !in.atEnd() ) + while(!in.atEnd()) { // Neue Zeile einlesen line = in.readLine(); ++line_counter; // Kommentare ueberlesen - if( line.startsWith("#",Qt::CaseInsensitive) || - line.startsWith(";;",Qt::CaseInsensitive) || - line.startsWith("//",Qt::CaseInsensitive) || - line.startsWith("!",Qt::CaseInsensitive) ) + if(line.startsWith("#", Qt::CaseInsensitive) || line.startsWith(";;", Qt::CaseInsensitive) || + line.startsWith("//", Qt::CaseInsensitive) || line.startsWith("!", Qt::CaseInsensitive)) continue; QTextStream stream(&line); - counter = 0; + counter = 0; end_loop = false; - while( !stream.atEnd() && !end_loop ) + while(!stream.atEnd() && !end_loop) { stream >> zahl; ++counter; - switch( counter ) + switch(counter) { - case 1: - x = zahl; - if( !with_3D_data ) - { - points3D_tmp.clear(); - with_3D_data = true; - } - break; - case 2: - y = zahl; - break; - case 3: - z = zahl; - break; - case 4: - px = zahl; - if( !with_2D_data ) - { - points2D_tmp.clear(); - with_2D_data = true; - } - break; - case 5: - py = zahl; - break; - default: - end_loop = true; + case 1: + x = zahl; + if(!with_3D_data) + { + points3D_tmp.clear(); + with_3D_data = true; + } + break; + case 2: + y = zahl; + break; + case 3: + z = zahl; + break; + case 4: + px = zahl; + if(!with_2D_data) + { + points2D_tmp.clear(); + with_2D_data = true; + } + break; + case 5: + py = zahl; + break; + default: + end_loop = true; } - } - if( counter == 1 ) + if(counter == 1) { debout << "Optional number of points in line " << line_counter << " ignored." << std::endl; - }else if( counter != 3 && counter != 5 ) - debout << "Something wrong in line " << line_counter << "( " << line << " )! Ignored. (counter=" << counter << ")" << std::endl; + } + else if(counter != 3 && counter != 5) + debout << "Something wrong in line " << line_counter << "( " << line + << " )! Ignored. (counter=" << counter << ")" << std::endl; // 3D daten abspeichern - if( with_3D_data && (counter == 3 || counter == 5) ) + if(with_3D_data && (counter == 3 || counter == 5)) { - //debout << "x: " << x << " y: " << y << " z: " << z << endl; - points3D_tmp.push_back( cv::Point3f( x, y, z ) ); + // debout << "x: " << x << " y: " << y << " z: " << z << endl; + points3D_tmp.push_back(cv::Point3f(x, y, z)); } // 2D daten abspeichern - if( with_2D_data && counter == 5 ) + if(with_2D_data && counter == 5) { - //debout << " px: " << px << " py: " << py << endl; - points2D_tmp.push_back( cv::Point2f( px, py ) ); + // debout << " px: " << px << " py: " << py << endl; + points2D_tmp.push_back(cv::Point2f(px, py)); } - - - } // Check if there are more than 4 points for calibration in the file - if( points3D_tmp.size() < 4 ) + if(points3D_tmp.size() < 4) { - PCritical(mMainWindow, QObject::tr("PeTrack"), QObject::tr("Error: Not enough points given: %1 (minimum 4 needed!). Please check your extrinsic calibration file!").arg(points3D_tmp.size())); + PCritical( + mMainWindow, + QObject::tr("PeTrack"), + QObject::tr("Error: Not enough points given: %1 (minimum 4 needed!). Please check your extrinsic " + "calibration file!") + .arg(points3D_tmp.size())); all_ok = false; } // Check if 2D points delivered and if the number of 2D and 3D points agree - else if( points2D_tmp.size() > 0 && points2D_tmp.size() != points3D_tmp.size() ) + else if(points2D_tmp.size() > 0 && points2D_tmp.size() != points3D_tmp.size()) { - PCritical(mMainWindow, QObject::tr("PeTrack"), QObject::tr("Error: Unsupported File Format in: %1 (number of 3D (%2) and 2D (%3) points disagree!)").arg(mExtrCalibFile).arg(points3D_tmp.size()).arg(points2D_tmp.size())); + PCritical( + mMainWindow, + QObject::tr("PeTrack"), + QObject::tr( + "Error: Unsupported File Format in: %1 (number of 3D (%2) and 2D (%3) points disagree!)") + .arg(mExtrCalibFile) + .arg(points3D_tmp.size()) + .arg(points2D_tmp.size())); all_ok = false; } // Check if number of loaded 3D points agree with stored 2D points - else if( !with_2D_data && points2D.size()>0 && points3D_tmp.size() != points2D.size() ) + else if(!with_2D_data && points2D.size() > 0 && points3D_tmp.size() != points2D.size()) { // ask if stored 2D points should be deleted? - int result = PWarning(mMainWindow, - QObject::tr("PeTrack"), - QObject::tr("Number of 3D points (%1) disagree with number of stored 2D points (%2)!<br />The 2D points will be deleted! You have to fetch new ones from the image!").arg(points3D_tmp.size()).arg(points2D.size()), - PMessageBox::StandardButton::Ok | PMessageBox::StandardButton::Abort); - if (result != PMessageBox::StandardButton::Ok) + int result = PWarning( + mMainWindow, + QObject::tr("PeTrack"), + QObject::tr("Number of 3D points (%1) disagree with number of stored 2D points (%2)!<br />The 2D " + "points will be deleted! You have to fetch new ones from the image!") + .arg(points3D_tmp.size()) + .arg(points2D.size()), + PMessageBox::StandardButton::Ok | PMessageBox::StandardButton::Abort); + if(result != PMessageBox::StandardButton::Ok) all_ok = false; else points2D.clear(); - } - if( all_ok ) + if(all_ok) { - if( with_3D_data ) points3D = points3D_tmp; - if( with_2D_data ) points2D = points2D_tmp; + if(with_3D_data) + points3D = points3D_tmp; + if(with_2D_data) + points2D = points2D_tmp; } - }else + } + else { debout << "unsupported file extension (supported: .3dc,.txt)" << std::endl; } - }else + } + else { // no calib_file all_ok = false; } - if (all_ok && !mMainWindow->isLoading()) + if(all_ok && !mMainWindow->isLoading()) calibExtrParams(); return all_ok; } @@ -278,33 +296,42 @@ bool ExtrCalibration::loadExtrCalibFile(){ bool ExtrCalibration::fetch2DPoints() { bool all_ok = true; - if( !mMainWindow->getTracker() || mMainWindow->getTracker()->size() < 4 ) + if(!mMainWindow->getTracker() || mMainWindow->getTracker()->size() < 4) { - PCritical(mMainWindow, QObject::tr("Petrack"), QObject::tr("Error: At minimum four 3D calibration points needed for 3D calibration.")); - all_ok = false; - }else + PCritical( + mMainWindow, + QObject::tr("Petrack"), + QObject::tr("Error: At minimum four 3D calibration points needed for 3D calibration.")); + all_ok = false; + } + else { size_t sz_2d = mMainWindow->getTracker()->size(); - if( points3D.size()>0 && sz_2d != points3D.size() ){ - PCritical(mMainWindow, QObject::tr("Petrack"), QObject::tr("Count of 2D-Points (%1) and 3D-Points (%2) disagree").arg(sz_2d).arg(points3D.size())); + if(points3D.size() > 0 && sz_2d != points3D.size()) + { + PCritical( + mMainWindow, + QObject::tr("Petrack"), + QObject::tr("Count of 2D-Points (%1) and 3D-Points (%2) disagree").arg(sz_2d).arg(points3D.size())); all_ok = false; - } - //debout << "Marked 2D-Image-Points: " << endl; - if( all_ok ) + // debout << "Marked 2D-Image-Points: " << endl; + if(all_ok) { points2D.clear(); for(int i = 0; i < static_cast<int>(sz_2d); i++) { - //debout << "[" << i << "]: (" << mMainWindow->getTracker()->at(i).at(0).x() << ", " << mMainWindow->getTracker()->at(i).at(0).y() << ")" << endl; - // Info: Tracker->TrackPerson->TrackPoint->Vec2F - points2D.push_back(cv::Point2f(mMainWindow->getTracker()->at(i).at(0).x(),mMainWindow->getTracker()->at(i).at(0).y())); + // debout << "[" << i << "]: (" << mMainWindow->getTracker()->at(i).at(0).x() << ", " << + // mMainWindow->getTracker()->at(i).at(0).y() << ")" << endl; + // Info: Tracker->TrackPerson->TrackPoint->Vec2F + points2D.push_back(cv::Point2f( + mMainWindow->getTracker()->at(i).at(0).x(), mMainWindow->getTracker()->at(i).at(0).y())); } } } - if( all_ok ) + if(all_ok) { mMainWindow->getTracker()->clear(); calibExtrParams(); @@ -327,62 +354,73 @@ bool ExtrCalibration::saveExtrCalibPoints() { bool all_okay = false; - QString out_str; + QString out_str; QTextStream out(&out_str); - for (size_t i = 0; i < points3D.size(); ++i) + for(size_t i = 0; i < points3D.size(); ++i) { - out << "[" << QString::number(i+1,'i',0) << "]: "<< QString::number(points3D.at(i).x,'f',1) << " " << QString::number(points3D.at(i).y,'f',1) << " " << QString::number(points3D.at(i).z,'f',1) << " " << QString::number(points2D.at(i).x,'f',3) << " " << QString::number(points2D.at(i).y,'f',3) << Qt::endl; + out << "[" << QString::number(i + 1, 'i', 0) << "]: " << QString::number(points3D.at(i).x, 'f', 1) << " " + << QString::number(points3D.at(i).y, 'f', 1) << " " << QString::number(points3D.at(i).z, 'f', 1) << " " + << QString::number(points2D.at(i).x, 'f', 3) << " " << QString::number(points2D.at(i).y, 'f', 3) + << Qt::endl; } - QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning); - PMessageBox msgBox {nullptr, "PeTrack", - "The corresponding calibration points have been changed.\n" - "Do you want to save your changes?", - QIcon(), - out_str, - PMessageBox::StandardButton::Save | PMessageBox::StandardButton::Cancel, - PMessageBox::StandardButton::Save}; + QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning); + PMessageBox msgBox{ + nullptr, + "PeTrack", + "The corresponding calibration points have been changed.\n" + "Do you want to save your changes?", + QIcon(), + out_str, + PMessageBox::StandardButton::Save | PMessageBox::StandardButton::Cancel, + PMessageBox::StandardButton::Save}; int ret = msgBox.exec(); - switch (ret) { + switch(ret) + { case PMessageBox::StandardButton::Save: { - // Save was clicked + // Save was clicked QFile file(mExtrCalibFile); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - PCritical(mMainWindow, QObject::tr("Petrack"), QObject::tr("Cannot open %1:\n%2.").arg(mExtrCalibFile).arg(file.errorString())); - return false; + PCritical( + mMainWindow, + QObject::tr("Petrack"), + QObject::tr("Cannot open %1:\n%2.").arg(mExtrCalibFile).arg(file.errorString())); + return false; } QTextStream file_out(&file); file_out << points3D.size() << Qt::endl; - for (size_t i = 0; i < points3D.size(); ++i) + for(size_t i = 0; i < points3D.size(); ++i) { - file_out << points3D.at(i).x << " " << points3D.at(i).y << " " << points3D.at(i).z << " " << points2D.at(i).x << " " << points2D.at(i).y << Qt::endl; + file_out << points3D.at(i).x << " " << points3D.at(i).y << " " << points3D.at(i).z << " " + << points2D.at(i).x << " " << points2D.at(i).y << Qt::endl; } all_okay = file.flush(); file.close(); - break; + break; } case PMessageBox::StandardButton::Discard: - // Don't Save was clicked - break; + // Don't Save was clicked + break; case PMessageBox::StandardButton::Cancel: - // Cancel was clicked - break; - default: - // should never be reached - break; + // Cancel was clicked + break; + default: + // should never be reached + break; } return all_okay; } -bool ExtrCalibration::isSetExtrCalib(){ +bool ExtrCalibration::isSetExtrCalib() +{ return true; } @@ -391,97 +429,97 @@ bool ExtrCalibration::isSetExtrCalib(){ */ void ExtrCalibration::calibExtrParams() { - - if( !points3D.empty() && !points2D.empty() && points2D.size() == points3D.size() ) + if(!points3D.empty() && !points2D.empty() && points2D.size() == points3D.size()) { - int bS = mMainWindow->getImageBorderSize(); /* Create Camera-Matrix form Camera-Params in the Petrack-GUI */ + // clang-format off cv::Mat camMat = (cv::Mat_<double>(3,3) << mControlWidget->fx->value(), 0, mControlWidget->cx->value()-bS, 0, mControlWidget->fy->value(), mControlWidget->cy->value()-bS, 0, 0, 1); - - cv::Mat distMat = (cv::Mat_<double>(8,1) << - 0,//mControlWidget->r2->value(), - 0,//mControlWidget->r4->value(), - 0,//mControlWidget->tx->value(), - 0,//mControlWidget->ty->value(), - // r^>4 not supported - 0,//mControlWidget->r6->value(), - 0,//mControlWidget->k4->value(), - 0,//mControlWidget->k5->value(), - 0//mControlWidget->k6->value() - ); - + // clang-format on + cv::Mat distMat = + (cv::Mat_<double>(8, 1) << 0, // mControlWidget->r2->value(), + 0, // mControlWidget->r4->value(), + 0, // mControlWidget->tx->value(), + 0, // mControlWidget->ty->value(), + // r^>4 not supported + 0, // mControlWidget->r6->value(), + 0, // mControlWidget->k4->value(), + 0, // mControlWidget->k5->value(), + 0 // mControlWidget->k6->value() + ); /* Create Mat-objects of point correspondences */ cv::Mat op(points3D); cv::Mat ip(points2D); /* Mat-objects for result rotation and translation vectors */ - cv::Mat rvec(3,1,CV_64F),/*,0),*/ tvec(3,1,CV_64F);//,0); + cv::Mat rvec(3, 1, CV_64F), /*,0),*/ tvec(3, 1, CV_64F); //,0); // Solve the PnP-Problem to calibrate the camera to its environment - cv::solvePnP(op,ip,camMat,distMat,rvec,tvec,false,cv::SOLVEPNP_ITERATIVE); + cv::solvePnP(op, ip, camMat, distMat, rvec, tvec, false, cv::SOLVEPNP_ITERATIVE); - cv::Mat rot_mat(3,3,CV_64F);//, 0); + cv::Mat rot_mat(3, 3, CV_64F); //, 0); // Transform the rotation vector into a rotation matrix with opencvs rodrigues method - Rodrigues(rvec,rot_mat); - - rotation_matrix[0] = rot_mat.at<double>(0,0); - rotation_matrix[1] = rot_mat.at<double>(0,1); - rotation_matrix[2] = rot_mat.at<double>(0,2); - rotation_matrix[3] = rot_mat.at<double>(1,0); - rotation_matrix[4] = rot_mat.at<double>(1,1); - rotation_matrix[5] = rot_mat.at<double>(1,2); - rotation_matrix[6] = rot_mat.at<double>(2,0); - rotation_matrix[7] = rot_mat.at<double>(2,1); - rotation_matrix[8] = rot_mat.at<double>(2,2); - - translation_vector[0] = tvec.at<double>(0,0); - translation_vector[1] = tvec.at<double>(0,1); - translation_vector[2] = tvec.at<double>(0,2); - - translation_vector2[0] = - rotation_matrix[0] * translation_vector[0] + - rotation_matrix[3] * translation_vector[1] + - rotation_matrix[6] * translation_vector[2]; - translation_vector2[1] = - rotation_matrix[1] * translation_vector[0] + - rotation_matrix[4] * translation_vector[1] + - rotation_matrix[7] * translation_vector[2]; - translation_vector2[2] = - rotation_matrix[2] * translation_vector[0] + - rotation_matrix[5] * translation_vector[1] + - rotation_matrix[8] * translation_vector[2]; + Rodrigues(rvec, rot_mat); + + rotation_matrix[0] = rot_mat.at<double>(0, 0); + rotation_matrix[1] = rot_mat.at<double>(0, 1); + rotation_matrix[2] = rot_mat.at<double>(0, 2); + rotation_matrix[3] = rot_mat.at<double>(1, 0); + rotation_matrix[4] = rot_mat.at<double>(1, 1); + rotation_matrix[5] = rot_mat.at<double>(1, 2); + rotation_matrix[6] = rot_mat.at<double>(2, 0); + rotation_matrix[7] = rot_mat.at<double>(2, 1); + rotation_matrix[8] = rot_mat.at<double>(2, 2); + + translation_vector[0] = tvec.at<double>(0, 0); + translation_vector[1] = tvec.at<double>(0, 1); + translation_vector[2] = tvec.at<double>(0, 2); + + translation_vector2[0] = rotation_matrix[0] * translation_vector[0] + + rotation_matrix[3] * translation_vector[1] + + rotation_matrix[6] * translation_vector[2]; + translation_vector2[1] = rotation_matrix[1] * translation_vector[0] + + rotation_matrix[4] * translation_vector[1] + + rotation_matrix[7] * translation_vector[2]; + translation_vector2[2] = rotation_matrix[2] * translation_vector[0] + + rotation_matrix[5] * translation_vector[1] + + rotation_matrix[8] * translation_vector[2]; debout << "-.- ESTIMATED ROTATION -.-" << std::endl; - for ( size_t p=0; p<3; p++ ) - debout << rotation_matrix[p*3] << " , " << rotation_matrix[p*3+1] << " , " << rotation_matrix[p*3+2] << std::endl; + for(size_t p = 0; p < 3; p++) + debout << rotation_matrix[p * 3] << " , " << rotation_matrix[p * 3 + 1] << " , " + << rotation_matrix[p * 3 + 2] << std::endl; debout << "-.- ESTIMATED TRANSLATION -.-" << std::endl; - debout << translation_vector[0] << " , " << translation_vector[1] << " , " << translation_vector[2] << std::endl; + debout << translation_vector[0] << " , " << translation_vector[1] << " , " << translation_vector[2] + << std::endl; debout << "-.- Translation vector -.-" << std::endl; - debout << translation_vector2[0] << " , " << translation_vector2[1] << " , " << translation_vector2[2] << std::endl; + debout << translation_vector2[0] << " , " << translation_vector2[1] << " , " << translation_vector2[2] + << std::endl; debout << "-.- Rotation vector -.-" << std::endl; - debout << rvec.at<double>(0,0) << " , " << rvec.at<double>(1,0) << " , " << rvec.at<double>(2,0) << std::endl; + debout << rvec.at<double>(0, 0) << " , " << rvec.at<double>(1, 0) << " , " << rvec.at<double>(2, 0) + << std::endl; camHeight = translation_vector2[2] < 0 ? -translation_vector2[2] : translation_vector2[2]; - mControlWidget->setCalibExtrRot1(rvec.at<double>(0,0)); - mControlWidget->setCalibExtrRot2(rvec.at<double>(1,0)); - mControlWidget->setCalibExtrRot3(rvec.at<double>(2,0)); + mControlWidget->setCalibExtrRot1(rvec.at<double>(0, 0)); + mControlWidget->setCalibExtrRot2(rvec.at<double>(1, 0)); + mControlWidget->setCalibExtrRot3(rvec.at<double>(2, 0)); mControlWidget->setCalibExtrTrans1(translation_vector2[0]); mControlWidget->setCalibExtrTrans2(translation_vector2[1]); mControlWidget->setCalibExtrTrans3(translation_vector2[2]); - if ( !calcReprojectionError() ) + if(!calcReprojectionError()) { - std::cout << "# Warning: extrinsic calibration not possible! Please select other 2D/3D points!" << std::endl; + std::cout << "# Warning: extrinsic calibration not possible! Please select other 2D/3D points!" + << std::endl; mControlWidget->setCalibExtrRot1(0); mControlWidget->setCalibExtrRot2(0); @@ -501,7 +539,11 @@ void ExtrCalibration::calibExtrParams() reprojectionError = ReprojectionError{}; - PCritical(mMainWindow, QObject::tr("Petrack"), QObject::tr("Error: Could not calculate extrinsic calibration. Please select other 2D/3D point correspondences for extrinsic calibration!")); + PCritical( + mMainWindow, + QObject::tr("Petrack"), + QObject::tr("Error: Could not calculate extrinsic calibration. Please select other 2D/3D point " + "correspondences for extrinsic calibration!")); isExtCalib = false; @@ -511,13 +553,13 @@ void ExtrCalibration::calibExtrParams() isExtCalib = true; std::cout << "End of extern calibration!" << std::endl; - }else + } + else { std::cerr << "# Warning: invalid point correspondences for camera calibration." << std::endl; std::cerr << "# 2D points:" << points2D.size() << ", 3D points: " << points3D.size() << std::endl; } mMainWindow->getScene()->update(); - } /** @@ -536,18 +578,18 @@ bool ExtrCalibration::calcReprojectionError() ////// /// \brief error measurements /// - double val, max_px = -1.0, max_pH = -1.0, max_dH = -1.0, - var_px = 0, sd_px = 0, var_pH = 0, sd_pH = 0, var_dH = 0, sd_dH = 0, - sum_px = 0, sum_pH = 0, sum_dH = 0; + double val, max_px = -1.0, max_pH = -1.0, max_dH = -1.0, var_px = 0, sd_px = 0, var_pH = 0, sd_pH = 0, var_dH = 0, + sd_dH = 0, sum_px = 0, sum_pH = 0, sum_dH = 0; size_t num_points = get2DList().size(); - if(num_points == 0 || num_points != get3DList().size()){ + if(num_points == 0 || num_points != get3DList().size()) + { reprojectionError = ReprojectionError{}; return false; } bool debug = false; - for(size_t i=0; i< num_points; i++) + for(size_t i = 0; i < num_points; i++) { cv::Point2f p2d = get2DList().at(i); cv::Point3f p3d = get3DList().at(i); @@ -557,31 +599,38 @@ bool ExtrCalibration::calcReprojectionError() cv::Point2f p3dTo2d = getImagePoint(p3d); // Error measurements metric (cm) - cv::Point3f p2dTo3d = get3DPoint(p2d,p3d.z); + cv::Point3f p2dTo3d = get3DPoint(p2d, p3d.z); - cv::Point3f p2dTo3dMapDefaultHeight = get3DPoint(p2d,mControlWidget->mapDefaultHeight->value()); + cv::Point3f p2dTo3dMapDefaultHeight = get3DPoint(p2d, mControlWidget->mapDefaultHeight->value()); - cv::Point3f p3dTo2dTo3dMapDefaultHeight = get3DPoint(p3dTo2d,mControlWidget->mapDefaultHeight->value()); + cv::Point3f p3dTo2dTo3dMapDefaultHeight = get3DPoint(p3dTo2d, mControlWidget->mapDefaultHeight->value()); - val = sqrt(pow(p3d.x - p2dTo3d.x,2) + pow(p3d.y - p2dTo3d.y,2)); - if ( val > max_pH ) max_pH = val; - sum_pH += val; - if( debug ) debout << "Error point[" << i << "]: " << val << std::endl; + val = sqrt(pow(p3d.x - p2dTo3d.x, 2) + pow(p3d.y - p2dTo3d.y, 2)); + if(val > max_pH) + max_pH = val; + sum_pH += val; + if(debug) + debout << "Error point[" << i << "]: " << val << std::endl; - val = sqrt(pow(p3dTo2dTo3dMapDefaultHeight.x - p2dTo3dMapDefaultHeight.x,2) + pow(p3dTo2dTo3dMapDefaultHeight.y-p2dTo3dMapDefaultHeight.y,2)); - if ( val > max_dH ) max_dH = val; - sum_dH += val; - if( debug ) debout << "Error point[" << i << "]: " << val << std::endl; + val = sqrt( + pow(p3dTo2dTo3dMapDefaultHeight.x - p2dTo3dMapDefaultHeight.x, 2) + + pow(p3dTo2dTo3dMapDefaultHeight.y - p2dTo3dMapDefaultHeight.y, 2)); + if(val > max_dH) + max_dH = val; + sum_dH += val; + if(debug) + debout << "Error point[" << i << "]: " << val << std::endl; // Error measurements pixel - val = sqrt(pow(p3dTo2d.x - p2d.x,2) + pow(p3dTo2d.y - p2d.y,2)); + val = sqrt(pow(p3dTo2d.x - p2d.x, 2) + pow(p3dTo2d.y - p2d.y, 2)); // Maximum - if ( val > max_px ) max_px = val; - sum_px += val; - if( debug ) debout << "Error point[" << i << "]: " << val << std::endl; - + if(val > max_px) + max_px = val; + sum_px += val; + if(debug) + debout << "Error point[" << i << "]: " << val << std::endl; } - for(size_t i=0; i< num_points; i++) + for(size_t i = 0; i < num_points; i++) { cv::Point2f p2d = get2DList().at(i); cv::Point3f p3d = get3DList().at(i); @@ -591,48 +640,68 @@ bool ExtrCalibration::calcReprojectionError() cv::Point2f p3d_to_2d = getImagePoint(p3d); // Error measurements metric (cm) - cv::Point3f p2d_to_3d = get3DPoint(p2d,p3d.z); + cv::Point3f p2d_to_3d = get3DPoint(p2d, p3d.z); - cv::Point3f p2d_to_3d_mapDefaultHeight = get3DPoint(p2d,mControlWidget->mapDefaultHeight->value()); // mStatusPosRealHeight->value()); ? + cv::Point3f p2d_to_3d_mapDefaultHeight = + get3DPoint(p2d, mControlWidget->mapDefaultHeight->value()); // mStatusPosRealHeight->value()); ? - cv::Point3f p3d_to2d_to3d_mapDefaultHeight = get3DPoint(p3d_to_2d,mControlWidget->mapDefaultHeight->value()); + cv::Point3f p3d_to2d_to3d_mapDefaultHeight = get3DPoint(p3d_to_2d, mControlWidget->mapDefaultHeight->value()); - val = pow(sqrt(pow(p3d.x-p2d_to_3d.x,2) + pow(p3d.y-p2d_to_3d.y,2))-(sum_pH/num_points),2); + val = pow(sqrt(pow(p3d.x - p2d_to_3d.x, 2) + pow(p3d.y - p2d_to_3d.y, 2)) - (sum_pH / num_points), 2); var_pH += val; - val = pow(sqrt(pow(p3d_to2d_to3d_mapDefaultHeight.x-p2d_to_3d_mapDefaultHeight.x,2) + pow(p3d_to2d_to3d_mapDefaultHeight.y-p2d_to_3d_mapDefaultHeight.y,2))-(sum_dH/num_points),2); + val = + pow(sqrt( + pow(p3d_to2d_to3d_mapDefaultHeight.x - p2d_to_3d_mapDefaultHeight.x, 2) + + pow(p3d_to2d_to3d_mapDefaultHeight.y - p2d_to_3d_mapDefaultHeight.y, 2)) - + (sum_dH / num_points), + 2); var_dH += val; - val = pow(sqrt(pow(p3d_to_2d.x-p2d.x,2) + pow(p3d_to_2d.y-p2d.y,2))-(sum_px/num_points),2); + val = pow(sqrt(pow(p3d_to_2d.x - p2d.x, 2) + pow(p3d_to_2d.y - p2d.y, 2)) - (sum_px / num_points), 2); var_px += val; - } // average sum_pH /= num_points; var_pH /= num_points; sd_pH = sqrt(var_pH); - debout << "Reprojection error (pointHeight) average: " << sum_pH << "cm (standard deviation: " << sd_pH << " variance: " << var_pH << " Max error: " << max_pH << "cm)" << std::endl; + debout << "Reprojection error (pointHeight) average: " << sum_pH << "cm (standard deviation: " << sd_pH + << " variance: " << var_pH << " Max error: " << max_pH << "cm)" << std::endl; // average sum_dH /= num_points; var_dH /= num_points; sd_dH = sqrt(var_dH); - debout << "Reprojection error (defaultHeight=" << mControlWidget->mapDefaultHeight->value() << ") average: " << sum_dH << "cm (standard deviation: " << sd_dH << " variance: " << var_dH << " Max error: " << max_dH << "cm)" << std::endl; + debout << "Reprojection error (defaultHeight=" << mControlWidget->mapDefaultHeight->value() + << ") average: " << sum_dH << "cm (standard deviation: " << sd_dH << " variance: " << var_dH + << " Max error: " << max_dH << "cm)" << std::endl; // average sum_px /= num_points; var_px /= num_points; sd_px = sqrt(var_px); - debout << "Reprojection error (Pixel) average: " << sum_px << "px (standard deviation: " << sd_px << " variance: " << var_px << " Max error: " << max_px << "px)" << std::endl; + debout << "Reprojection error (Pixel) average: " << sum_px << "px (standard deviation: " << sd_px + << " variance: " << var_px << " Max error: " << max_px << "px)" << std::endl; reprojectionError = ReprojectionError{ - sum_pH, sd_pH, var_pH, max_pH, - sum_dH, sd_dH, var_dH, max_dH, - sum_px, sd_px, var_px, max_px, + sum_pH, + sd_pH, + var_pH, + max_pH, + sum_dH, + sd_dH, + var_dH, + max_dH, + sum_px, + sd_px, + var_px, + max_px, mControlWidget->mapDefaultHeight->value()}; - return reprojectionError.pointHeightAvg() > MAX_AV_ERROR ? false : true; // Falls pixel fehler im schnitt > 20 ist das Ergebnis nicht akzeptabel + return reprojectionError.pointHeightAvg() > MAX_AV_ERROR ? + false : + true; // Falls pixel fehler im schnitt > 20 ist das Ergebnis nicht akzeptabel } /** @@ -658,7 +727,8 @@ cv::Point2f ExtrCalibration::getImagePoint(cv::Point3f p3d) p3d.y += mControlWidget->getCalibCoord3DTransY(); p3d.z += mControlWidget->getCalibCoord3DTransZ(); - if( debug ) std::cout << "getImagePoint: Start Point3D: (" << p3d.x << ", " << p3d.y << ", " << p3d.z << ")" << std::endl; + if(debug) + std::cout << "getImagePoint: Start Point3D: (" << p3d.x << ", " << p3d.y << ", " << p3d.z << ")" << std::endl; // ToDo: use projectPoints(); int bS = mMainWindow->getImage() ? mMainWindow->getImageBorderSize() : 0; @@ -668,73 +738,71 @@ cv::Point2f ExtrCalibration::getImagePoint(cv::Point3f p3d) rvec_array[1] = mControlWidget->getCalibExtrRot2(); rvec_array[2] = mControlWidget->getCalibExtrRot3(); - cv::Mat rvec(3,1,CV_64F, rvec_array), rot_inv; - cv::Mat rot_mat(3,3,CV_64F), e(3,3,CV_64F); + cv::Mat rvec(3, 1, CV_64F, rvec_array), rot_inv; + cv::Mat rot_mat(3, 3, CV_64F), e(3, 3, CV_64F); // Transform the rotation vector into a rotation matrix with opencvs rodrigues method - Rodrigues(rvec,rot_mat); + Rodrigues(rvec, rot_mat); // use inverse Matrix to get translation_vector? rot_inv = rot_mat.inv(cv::DECOMP_SVD); - e = rot_inv*rot_mat; - - translation_vector[0] = - rot_mat.at<double>(0,0)*mControlWidget->getCalibExtrTrans1()+ - rot_mat.at<double>(0,1)*mControlWidget->getCalibExtrTrans2()+ - rot_mat.at<double>(0,2)*mControlWidget->getCalibExtrTrans3(); - translation_vector[1] = - rot_mat.at<double>(1,0)*mControlWidget->getCalibExtrTrans1()+ - rot_mat.at<double>(1,1)*mControlWidget->getCalibExtrTrans2()+ - rot_mat.at<double>(1,2)*mControlWidget->getCalibExtrTrans3(); - translation_vector[2] = - rot_mat.at<double>(2,0)*mControlWidget->getCalibExtrTrans1()+ - rot_mat.at<double>(2,1)*mControlWidget->getCalibExtrTrans2()+ - rot_mat.at<double>(2,2)*mControlWidget->getCalibExtrTrans3(); - - if( debug ) + e = rot_inv * rot_mat; + + translation_vector[0] = rot_mat.at<double>(0, 0) * mControlWidget->getCalibExtrTrans1() + + rot_mat.at<double>(0, 1) * mControlWidget->getCalibExtrTrans2() + + rot_mat.at<double>(0, 2) * mControlWidget->getCalibExtrTrans3(); + translation_vector[1] = rot_mat.at<double>(1, 0) * mControlWidget->getCalibExtrTrans1() + + rot_mat.at<double>(1, 1) * mControlWidget->getCalibExtrTrans2() + + rot_mat.at<double>(1, 2) * mControlWidget->getCalibExtrTrans3(); + translation_vector[2] = rot_mat.at<double>(2, 0) * mControlWidget->getCalibExtrTrans1() + + rot_mat.at<double>(2, 1) * mControlWidget->getCalibExtrTrans2() + + rot_mat.at<double>(2, 2) * mControlWidget->getCalibExtrTrans3(); + + if(debug) { std::cout << "\n-.- ESTIMATED ROTATION\n"; - for ( int p=0; p<3; p++ ) - printf("%20.18f, %20.18f, %20.18f\n",rot_mat.at<double>(p,0),rot_mat.at<double>(p,1),rot_mat.at<double>(p,2)); + for(int p = 0; p < 3; p++) + printf( + "%20.18f, %20.18f, %20.18f\n", + rot_mat.at<double>(p, 0), + rot_mat.at<double>(p, 1), + rot_mat.at<double>(p, 2)); std::cout << "\n-.- ESTIMATED ROTATION^-1\n"; - for ( int p=0; p<3; p++ ) - printf("%20.18f, %20.18f, %20.18f\n",rot_inv.at<double>(p,0),rot_inv.at<double>(p,1),rot_inv.at<double>(p,2)); + for(int p = 0; p < 3; p++) + printf( + "%20.18f, %20.18f, %20.18f\n", + rot_inv.at<double>(p, 0), + rot_inv.at<double>(p, 1), + rot_inv.at<double>(p, 2)); std::cout << "\n-.- ESTIMATED R^-1*R\n"; - for ( int p=0; p<3; p++ ) - printf("%20.18f, %20.18f, %20.18f\n",e.at<double>(p,0),e.at<double>(p,1),e.at<double>(p,2)); + for(int p = 0; p < 3; p++) + printf("%20.18f, %20.18f, %20.18f\n", e.at<double>(p, 0), e.at<double>(p, 1), e.at<double>(p, 2)); std::cout << "\n-.- ESTIMATED TRANSLATION\n"; - printf("%20.15f, %20.15f, %20.15f\n",translation_vector[0],translation_vector[1],translation_vector[2]); + printf("%20.15f, %20.15f, %20.15f\n", translation_vector[0], translation_vector[1], translation_vector[2]); } cv::Point3f point3D; - point3D.x = - rot_mat.at<double>(0,0) * p3d.x + - rot_mat.at<double>(0,1) * p3d.y + - rot_mat.at<double>(0,2) * p3d.z + - translation_vector[0]; - point3D.y = - rot_mat.at<double>(1,0) * p3d.x + - rot_mat.at<double>(1,1) * p3d.y + - rot_mat.at<double>(1,2) * p3d.z + - translation_vector[1]; - point3D.z = - rot_mat.at<double>(2,0) * p3d.x + - rot_mat.at<double>(2,1) * p3d.y + - rot_mat.at<double>(2,2) * p3d.z + - translation_vector[2]; - - if( debug ) std::cout << "###### After extern calibration: (" << point3D.x << ", " << point3D.y << ", " << point3D.z << ")" << std::endl; - - cv::Point2f point2D = cv::Point2f( 0.0, 0.0 ); - if ( point3D.z != 0 ) + point3D.x = rot_mat.at<double>(0, 0) * p3d.x + rot_mat.at<double>(0, 1) * p3d.y + rot_mat.at<double>(0, 2) * p3d.z + + translation_vector[0]; + point3D.y = rot_mat.at<double>(1, 0) * p3d.x + rot_mat.at<double>(1, 1) * p3d.y + rot_mat.at<double>(1, 2) * p3d.z + + translation_vector[1]; + point3D.z = rot_mat.at<double>(2, 0) * p3d.x + rot_mat.at<double>(2, 1) * p3d.y + rot_mat.at<double>(2, 2) * p3d.z + + translation_vector[2]; + + if(debug) + std::cout << "###### After extern calibration: (" << point3D.x << ", " << point3D.y << ", " << point3D.z << ")" + << std::endl; + + cv::Point2f point2D = cv::Point2f(0.0, 0.0); + if(point3D.z != 0) { - point2D.x = (mControlWidget->fx->value() * point3D.x) / point3D.z + (mControlWidget->cx->value()-bS); - point2D.y = (mControlWidget->fy->value() * point3D.y) / point3D.z + (mControlWidget->cy->value()-bS); + point2D.x = (mControlWidget->fx->value() * point3D.x) / point3D.z + (mControlWidget->cx->value() - bS); + point2D.y = (mControlWidget->fy->value() * point3D.y) / point3D.z + (mControlWidget->cy->value() - bS); } - if (false && bS > 0) + if(false && bS > 0) { point2D.x += bS; point2D.y += bS; @@ -752,117 +820,135 @@ cv::Point2f ExtrCalibration::getImagePoint(cv::Point3f p3d) */ cv::Point3f ExtrCalibration::get3DPoint(cv::Point2f p2d, double h) { - bool debug = false; + bool debug = false; - if( debug ) std::cout << "get3DPoint: Start Point2D: (" << p2d.x << ", " << p2d.y << ") h: " << h << std::endl; + if(debug) + std::cout << "get3DPoint: Start Point2D: (" << p2d.x << ", " << p2d.y << ") h: " << h << std::endl; - int bS = mMainWindow->getImage() ? mMainWindow->getImageBorderSize() : 0; + int bS = mMainWindow->getImage() ? mMainWindow->getImageBorderSize() : 0; - if (false && bS > 0) - { - p2d.x += bS; - p2d.y += bS; - } + if(false && bS > 0) + { + p2d.x += bS; + p2d.y += bS; + } - // Ergebnis 3D-Punkt - cv::Point3f resultPoint, tmpPoint; + // Ergebnis 3D-Punkt + cv::Point3f resultPoint, tmpPoint; - bool newMethod = true; - /////////////// Start new method - if( newMethod ) - { + bool newMethod = true; + /////////////// Start new method + if(newMethod) + { double rvec_array[3], translation_vector[3]; rvec_array[0] = mControlWidget->getCalibExtrRot1(); rvec_array[1] = mControlWidget->getCalibExtrRot2(); rvec_array[2] = mControlWidget->getCalibExtrRot3(); - cv::Mat rvec(3,1,CV_64F, rvec_array), rot_inv; - cv::Mat rot_mat(3,3,CV_64F), e(3,3,CV_64F); + cv::Mat rvec(3, 1, CV_64F, rvec_array), rot_inv; + cv::Mat rot_mat(3, 3, CV_64F), e(3, 3, CV_64F); // Transform the rotation vector into a rotation matrix with opencvs rodrigues method - Rodrigues(rvec,rot_mat); - - translation_vector[0] = - rot_mat.at<double>(0,0)*mControlWidget->getCalibExtrTrans1()+ - rot_mat.at<double>(0,1)*mControlWidget->getCalibExtrTrans2()+ - rot_mat.at<double>(0,2)*mControlWidget->getCalibExtrTrans3(); - translation_vector[1] = - rot_mat.at<double>(1,0)*mControlWidget->getCalibExtrTrans1()+ - rot_mat.at<double>(1,1)*mControlWidget->getCalibExtrTrans2()+ - rot_mat.at<double>(1,2)*mControlWidget->getCalibExtrTrans3(); - translation_vector[2] = - rot_mat.at<double>(2,0)*mControlWidget->getCalibExtrTrans1()+ - rot_mat.at<double>(2,1)*mControlWidget->getCalibExtrTrans2()+ - rot_mat.at<double>(2,2)*mControlWidget->getCalibExtrTrans3(); + Rodrigues(rvec, rot_mat); + + translation_vector[0] = rot_mat.at<double>(0, 0) * mControlWidget->getCalibExtrTrans1() + + rot_mat.at<double>(0, 1) * mControlWidget->getCalibExtrTrans2() + + rot_mat.at<double>(0, 2) * mControlWidget->getCalibExtrTrans3(); + translation_vector[1] = rot_mat.at<double>(1, 0) * mControlWidget->getCalibExtrTrans1() + + rot_mat.at<double>(1, 1) * mControlWidget->getCalibExtrTrans2() + + rot_mat.at<double>(1, 2) * mControlWidget->getCalibExtrTrans3(); + translation_vector[2] = rot_mat.at<double>(2, 0) * mControlWidget->getCalibExtrTrans1() + + rot_mat.at<double>(2, 1) * mControlWidget->getCalibExtrTrans2() + + rot_mat.at<double>(2, 2) * mControlWidget->getCalibExtrTrans3(); // use inverse Matrix rot_inv = rot_mat.inv(cv::DECOMP_LU); - e = rot_inv*rot_mat; + e = rot_inv * rot_mat; - if( debug ) + if(debug) { - debout << "\n-.- ESTIMATED ROTATION\n"; - for ( int p=0; p<3; p++ ) - printf("%20.18f, %20.18f, %20.18f\n",rot_mat.at<double>(p,0),rot_mat.at<double>(p,1),rot_mat.at<double>(p,2)); - - debout << "\n-.- ESTIMATED ROTATION^-1\n"; - for ( int p=0; p<3; p++ ) - printf("%20.18f, %20.18f, %20.18f\n",rot_inv.at<double>(p,0),rot_inv.at<double>(p,1),rot_inv.at<double>(p,2)); - - debout << "\n-.- ESTIMATED R^-1*R\n"; - for ( int p=0; p<3; p++ ) - printf("%20.18f, %20.18f, %20.18f\n",e.at<double>(p,0),e.at<double>(p,1),e.at<double>(p,2)); - - debout << "\n-.- ESTIMATED TRANSLATION\n"; - debout << mControlWidget->getCalibExtrTrans1() << " , " << mControlWidget->getCalibExtrTrans2() << " , " << mControlWidget->getCalibExtrTrans3() << "\n"; - debout << translation_vector[0] << " , " << translation_vector[1] << " , " << translation_vector[2] << "\n"; - - debout << "Det(rot_mat): "<< determinant(rot_mat) << std::endl; - debout << "Det(rot_inv): "<< determinant(rot_inv) << std::endl; + debout << "\n-.- ESTIMATED ROTATION\n"; + for(int p = 0; p < 3; p++) + printf( + "%20.18f, %20.18f, %20.18f\n", + rot_mat.at<double>(p, 0), + rot_mat.at<double>(p, 1), + rot_mat.at<double>(p, 2)); + + debout << "\n-.- ESTIMATED ROTATION^-1\n"; + for(int p = 0; p < 3; p++) + printf( + "%20.18f, %20.18f, %20.18f\n", + rot_inv.at<double>(p, 0), + rot_inv.at<double>(p, 1), + rot_inv.at<double>(p, 2)); + + debout << "\n-.- ESTIMATED R^-1*R\n"; + for(int p = 0; p < 3; p++) + printf("%20.18f, %20.18f, %20.18f\n", e.at<double>(p, 0), e.at<double>(p, 1), e.at<double>(p, 2)); + + debout << "\n-.- ESTIMATED TRANSLATION\n"; + debout << mControlWidget->getCalibExtrTrans1() << " , " << mControlWidget->getCalibExtrTrans2() << " , " + << mControlWidget->getCalibExtrTrans3() << "\n"; + debout << translation_vector[0] << " , " << translation_vector[1] << " , " << translation_vector[2] << "\n"; + + debout << "Det(rot_mat): " << determinant(rot_mat) << std::endl; + debout << "Det(rot_inv): " << determinant(rot_inv) << std::endl; } - double z = h + rot_inv.at<double>(2,0)*translation_vector[0] + - rot_inv.at<double>(2,1)*translation_vector[1] + - rot_inv.at<double>(2,2)*translation_vector[2]; - if( debug ) + double z = h + rot_inv.at<double>(2, 0) * translation_vector[0] + + rot_inv.at<double>(2, 1) * translation_vector[1] + rot_inv.at<double>(2, 2) * translation_vector[2]; + if(debug) { - debout << "##### z: " << h << " + " << rot_inv.at<double>(2,0) << "*" << translation_vector[0] << " + " - << rot_inv.at<double>(2,1) << "*" << translation_vector[1] << " + " - << rot_inv.at<double>(2,2) << "*" << translation_vector[2] << " = " << z << std::endl; + debout << "##### z: " << h << " + " << rot_inv.at<double>(2, 0) << "*" << translation_vector[0] << " + " + << rot_inv.at<double>(2, 1) << "*" << translation_vector[1] << " + " << rot_inv.at<double>(2, 2) + << "*" << translation_vector[2] << " = " << z << std::endl; } - z /= (rot_inv.at<double>(2,0)*(p2d.x-(mControlWidget->getCalibCxValue()-bS))/mControlWidget->getCalibFxValue() + - rot_inv.at<double>(2,1)*(p2d.y-(mControlWidget->getCalibCyValue()-bS))/mControlWidget->getCalibFyValue() + - rot_inv.at<double>(2,2)); - if( debug ) std::cout << "###### z: "<< z << std::endl; - - resultPoint.x = (p2d.x-(mControlWidget->getCalibCxValue()-bS)); - resultPoint.y = (p2d.y-(mControlWidget->getCalibCyValue()-bS)); + z /= + (rot_inv.at<double>(2, 0) * (p2d.x - (mControlWidget->getCalibCxValue() - bS)) / + mControlWidget->getCalibFxValue() + + rot_inv.at<double>(2, 1) * (p2d.y - (mControlWidget->getCalibCyValue() - bS)) / + mControlWidget->getCalibFyValue() + + rot_inv.at<double>(2, 2)); + if(debug) + std::cout << "###### z: " << z << std::endl; + + resultPoint.x = (p2d.x - (mControlWidget->getCalibCxValue() - bS)); + resultPoint.y = (p2d.y - (mControlWidget->getCalibCyValue() - bS)); resultPoint.z = z; - if( debug ) std::cout << "###### (" << resultPoint.x << ", " << resultPoint.y << ", " << resultPoint.z << ")" << std::endl; + if(debug) + std::cout << "###### (" << resultPoint.x << ", " << resultPoint.y << ", " << resultPoint.z << ")" + << std::endl; - resultPoint.x = resultPoint.x * z/mControlWidget->getCalibFxValue(); - resultPoint.y = resultPoint.y * z/mControlWidget->getCalibFyValue(); + resultPoint.x = resultPoint.x * z / mControlWidget->getCalibFxValue(); + resultPoint.y = resultPoint.y * z / mControlWidget->getCalibFyValue(); - if( debug ) std::cout << "###### After intern re-calibration: (" << resultPoint.x << ", " << resultPoint.y << ", " << resultPoint.z << ")" << std::endl; + if(debug) + std::cout << "###### After intern re-calibration: (" << resultPoint.x << ", " << resultPoint.y << ", " + << resultPoint.z << ")" << std::endl; tmpPoint.x = resultPoint.x - translation_vector[0]; tmpPoint.y = resultPoint.y - translation_vector[1]; tmpPoint.z = resultPoint.z - translation_vector[2]; - if( debug ) std::cout << "###### After translation: (" << tmpPoint.x << ", " << tmpPoint.y << ", " << tmpPoint.z << ")" << std::endl; + if(debug) + std::cout << "###### After translation: (" << tmpPoint.x << ", " << tmpPoint.y << ", " << tmpPoint.z << ")" + << std::endl; - resultPoint.x = rot_inv.at<double>(0,0)*(tmpPoint.x)+ - rot_inv.at<double>(0,1)*(tmpPoint.y)+ - rot_inv.at<double>(0,2)*(tmpPoint.z); - resultPoint.y = rot_inv.at<double>(1,0)*(tmpPoint.x)+ - rot_inv.at<double>(1,1)*(tmpPoint.y)+ - rot_inv.at<double>(1,2)*(tmpPoint.z); - resultPoint.z = rot_inv.at<double>(2,0)*(tmpPoint.x)+ - rot_inv.at<double>(2,1)*(tmpPoint.y)+ - rot_inv.at<double>(2,2)*(tmpPoint.z); + resultPoint.x = rot_inv.at<double>(0, 0) * (tmpPoint.x) + rot_inv.at<double>(0, 1) * (tmpPoint.y) + + rot_inv.at<double>(0, 2) * (tmpPoint.z); + resultPoint.y = rot_inv.at<double>(1, 0) * (tmpPoint.x) + rot_inv.at<double>(1, 1) * (tmpPoint.y) + + rot_inv.at<double>(1, 2) * (tmpPoint.z); + resultPoint.z = rot_inv.at<double>(2, 0) * (tmpPoint.x) + rot_inv.at<double>(2, 1) * (tmpPoint.y) + + rot_inv.at<double>(2, 2) * (tmpPoint.z); - if( debug ) std::cout << "#resultPoint: (" << resultPoint.x << ", " << resultPoint.y << ", " << resultPoint.z << ")" << std::endl; - if( debug ) std::cout << "Coord Translation: x: " << mControlWidget->getCalibCoord3DTransX() << ", y: " << mControlWidget->getCalibCoord3DTransY() << ", z: " << mControlWidget->getCalibCoord3DTransZ() << std::endl; + if(debug) + std::cout << "#resultPoint: (" << resultPoint.x << ", " << resultPoint.y << ", " << resultPoint.z << ")" + << std::endl; + if(debug) + std::cout << "Coord Translation: x: " << mControlWidget->getCalibCoord3DTransX() + << ", y: " << mControlWidget->getCalibCoord3DTransY() + << ", z: " << mControlWidget->getCalibCoord3DTransZ() << std::endl; // Coordinate Transformations @@ -874,48 +960,56 @@ cv::Point3f ExtrCalibration::get3DPoint(cv::Point2f p2d, double h) resultPoint.x *= mControlWidget->getCalibCoord3DSwapX() ? -1 : 1; resultPoint.y *= mControlWidget->getCalibCoord3DSwapY() ? -1 : 1; resultPoint.z *= mControlWidget->getCalibCoord3DSwapZ() ? -1 : 1; - - - }else//////////////// End new method - { + } + else //////////////// End new method + { //////////////// Start old method - cv::Point3f camInWorld = transformRT(cv::Point3f(0,0,0)); + cv::Point3f camInWorld = transformRT(cv::Point3f(0, 0, 0)); // 3D-Punkt vor der Kamera mit Tiefe 5 CvPoint3D32f pointBeforeCam; pointBeforeCam.x = (p2d.x - mControlWidget->cx->value()) / mControlWidget->fx->value() * 50; pointBeforeCam.y = (p2d.y - mControlWidget->cy->value()) / mControlWidget->fy->value() * 50; pointBeforeCam.z = 50; - if( debug ) std::cout << "Point before Camera: [" << pointBeforeCam.x << ", " << pointBeforeCam.y << ", " << pointBeforeCam.z << "]" << std::endl; + if(debug) + std::cout << "Point before Camera: [" << pointBeforeCam.x << ", " << pointBeforeCam.y << ", " + << pointBeforeCam.z << "]" << std::endl; // 3D-Punkt vor Kamera in Weltkoordinaten cv::Point3f pBCInWorld = transformRT(pointBeforeCam); - if( debug ) std::cout << "Point before Camera in World-Coordinatesystem: [" << pBCInWorld.x << ", " << pBCInWorld.y << ", " << pBCInWorld.z << "]" << std::endl; - if( debug ) std::cout << "Camera in World-Coordinatesystem: [" << camInWorld.x << ", " << camInWorld.y << ", " << camInWorld.z << "]" << std::endl; + if(debug) + std::cout << "Point before Camera in World-Coordinatesystem: [" << pBCInWorld.x << ", " << pBCInWorld.y + << ", " << pBCInWorld.z << "]" << std::endl; + if(debug) + std::cout << "Camera in World-Coordinatesystem: [" << camInWorld.x << ", " << camInWorld.y << ", " + << camInWorld.z << "]" << std::endl; // Berechnung des Richtungsvektors der Gerade von der Kamera durch den Pixel // Als Sttzvektor der Geraden wird die Position der Kamera gewhlt pBCInWorld.x -= camInWorld.x; pBCInWorld.y -= camInWorld.y; pBCInWorld.z -= camInWorld.z; - if( debug ) std::cout << "G:x = (" << camInWorld.x << " / " << camInWorld.y << " / " << camInWorld.z << ") + lambda (" << pBCInWorld.x << " / " << pBCInWorld.y << " / " << pBCInWorld.z << ")" << std::endl; + if(debug) + std::cout << "G:x = (" << camInWorld.x << " / " << camInWorld.y << " / " << camInWorld.z << ") + lambda (" + << pBCInWorld.x << " / " << pBCInWorld.y << " / " << pBCInWorld.z << ")" << std::endl; // Berechnung des Schnittpunktes: Hier lambda von der Geraden - double lambda = (h -camInWorld.z) / (pBCInWorld.z); - if( debug ) std::cout << "Lambda: " << lambda << std::endl; + double lambda = (h - camInWorld.z) / (pBCInWorld.z); + if(debug) + std::cout << "Lambda: " << lambda << std::endl; // Lambda in Gerade einsetzen resultPoint.x = (mControlWidget->getCalibCoord3DSwapX() ? -1 : 1) * (camInWorld.x + lambda * pBCInWorld.x); resultPoint.y = (mControlWidget->getCalibCoord3DSwapY() ? -1 : 1) * (camInWorld.y + lambda * pBCInWorld.y); resultPoint.z = (mControlWidget->getCalibCoord3DSwapZ() ? -1 : 1) * (camInWorld.z + lambda * pBCInWorld.z); - }//////////////// End old method + } //////////////// End old method - return resultPoint; + return resultPoint; } /** - * Transformiert den angegebenen 3D-Punkt mit der Rotation und Translation - * um Umrechnungen zwischen verschiedenen Koordinatensystemen zu ermglichen - */ + * Transformiert den angegebenen 3D-Punkt mit der Rotation und Translation + * um Umrechnungen zwischen verschiedenen Koordinatensystemen zu ermglichen + */ cv::Point3f ExtrCalibration::transformRT(cv::Point3f p) { // ToDo: use projectPoints(); @@ -925,48 +1019,44 @@ cv::Point3f ExtrCalibration::transformRT(cv::Point3f p) rvec_array[1] = mControlWidget->getCalibExtrRot2(); rvec_array[2] = mControlWidget->getCalibExtrRot3(); - cv::Mat rvec(3,1,CV_64F, rvec_array); - cv::Mat rot_mat(3,3,CV_64F); + cv::Mat rvec(3, 1, CV_64F, rvec_array); + cv::Mat rot_mat(3, 3, CV_64F); // Transform the rotation vector into a rotation matrix with opencvs rodrigues method - Rodrigues(rvec,rot_mat); - - rotation_matrix[0] = rot_mat.at<double>(0,0); - rotation_matrix[1] = rot_mat.at<double>(0,1); - rotation_matrix[2] = rot_mat.at<double>(0,2); - rotation_matrix[3] = rot_mat.at<double>(1,0); - rotation_matrix[4] = rot_mat.at<double>(1,1); - rotation_matrix[5] = rot_mat.at<double>(1,2); - rotation_matrix[6] = rot_mat.at<double>(2,0); - rotation_matrix[7] = rot_mat.at<double>(2,1); - rotation_matrix[8] = rot_mat.at<double>(2,2); + Rodrigues(rvec, rot_mat); + + rotation_matrix[0] = rot_mat.at<double>(0, 0); + rotation_matrix[1] = rot_mat.at<double>(0, 1); + rotation_matrix[2] = rot_mat.at<double>(0, 2); + rotation_matrix[3] = rot_mat.at<double>(1, 0); + rotation_matrix[4] = rot_mat.at<double>(1, 1); + rotation_matrix[5] = rot_mat.at<double>(1, 2); + rotation_matrix[6] = rot_mat.at<double>(2, 0); + rotation_matrix[7] = rot_mat.at<double>(2, 1); + rotation_matrix[8] = rot_mat.at<double>(2, 2); cv::Point3f point3D; - point3D.x = rotation_matrix[0] * p.x + - rotation_matrix[3] * p.y + - rotation_matrix[6] * p.z - - mControlWidget->trans1->value(); - point3D.y = rotation_matrix[1] * p.x + - rotation_matrix[4] * p.y + - rotation_matrix[7] * p.z - - mControlWidget->trans2->value(); - point3D.z = rotation_matrix[2] * p.x + - rotation_matrix[5] * p.y + - rotation_matrix[8] * p.z - - mControlWidget->trans3->value(); + point3D.x = rotation_matrix[0] * p.x + rotation_matrix[3] * p.y + rotation_matrix[6] * p.z - + mControlWidget->trans1->value(); + point3D.y = rotation_matrix[1] * p.x + rotation_matrix[4] * p.y + rotation_matrix[7] * p.z - + mControlWidget->trans2->value(); + point3D.z = rotation_matrix[2] * p.x + rotation_matrix[5] * p.y + rotation_matrix[8] * p.z - + mControlWidget->trans3->value(); return point3D; } bool ExtrCalibration::isOutsideImage(cv::Point2f p2d) { int bS = mMainWindow->getImage() ? mMainWindow->getImageBorderSize() : 0; - if( mMainWindow->getImage()) + if(mMainWindow->getImage()) { - if( !isnormal(p2d.x) || !isnormal(p2d.y) || !isnormal(p2d.x) || !isnormal(p2d.y) ) + if(!isnormal(p2d.x) || !isnormal(p2d.y) || !isnormal(p2d.x) || !isnormal(p2d.y)) return true; - if (isnan(p2d.x) || isnan(p2d.y) || isinf(p2d.x) || isinf(p2d.y)) + if(isnan(p2d.x) || isnan(p2d.y) || isinf(p2d.x) || isinf(p2d.y)) return true; - return p2d.x < -bS || p2d.x > mMainWindow->getImage()->width()-bS || p2d.y < -bS || p2d.y > mMainWindow->getImage()->height()-bS; - }else + return p2d.x < -bS || p2d.x > mMainWindow->getImage()->width() - bS || p2d.y < -bS || + p2d.y > mMainWindow->getImage()->height() - bS; + } + else { return false; } @@ -981,11 +1071,11 @@ void ExtrCalibration::setXml(QDomElement &elem) void ExtrCalibration::getXml(QDomElement &elem) { QDomElement subElem; - QString styleString; + QString styleString; for(subElem = elem.firstChildElement(); !subElem.isNull(); subElem = subElem.nextSiblingElement()) { - if (subElem.tagName() == "REPROJECTION_ERROR") + if(subElem.tagName() == "REPROJECTION_ERROR") { reprojectionError.getXml(subElem); } @@ -994,68 +1084,73 @@ void ExtrCalibration::getXml(QDomElement &elem) void ReprojectionError::getXml(QDomElement &subElem) { - if (subElem.hasAttribute("SUM_PH")) + if(subElem.hasAttribute("SUM_PH")) { mPointHeightAvg = subElem.attribute("AVG_PH").toDouble(); } - if (subElem.hasAttribute("SD_PH")) + if(subElem.hasAttribute("SD_PH")) { mPointHeightStdDev = subElem.attribute("SD_PH").toDouble(); if(mPointHeightStdDev < 0) { mPointHeightVariance = -1; - }else + } + else { mPointHeightVariance = pow(mPointHeightStdDev, 2); } } - if (subElem.hasAttribute("MAX_PH")) + if(subElem.hasAttribute("MAX_PH")) { mPointHeightMax = subElem.attribute("MAX_PH").toDouble(); } - if (subElem.hasAttribute("SUM_DH")) + if(subElem.hasAttribute("SUM_DH")) { mDefaultHeightAvg = subElem.attribute("AVG_DH").toDouble(); } - if (subElem.hasAttribute("SD_DH")) + if(subElem.hasAttribute("SD_DH")) { mDefaultHeightStdDev = subElem.attribute("SD_DH").toDouble(); - if(mDefaultHeightStdDev < 0){ + if(mDefaultHeightStdDev < 0) + { mDefaultHeightVariance = -1; - }else{ + } + else + { mDefaultHeightVariance = pow(mDefaultHeightStdDev, 2); } } - if (subElem.hasAttribute("MAX_DH")) + if(subElem.hasAttribute("MAX_DH")) { mDefaultHeightMax = subElem.attribute("MAX_DH").toDouble(); } - if (subElem.hasAttribute("SUM_PX")) + if(subElem.hasAttribute("SUM_PX")) { mPixelAvg = subElem.attribute("AVG_PX").toDouble(); } - if (subElem.hasAttribute("SD_PX")) + if(subElem.hasAttribute("SD_PX")) { mPixelStdDev = subElem.attribute("SD_PX").toDouble(); if(mPixelStdDev < 0) { mPixelVariance = -1; - }else + } + else { mPixelVariance = pow(mPixelStdDev, 2); } } - if (subElem.hasAttribute("MAX_PX")) + if(subElem.hasAttribute("MAX_PX")) { mPixelMax = subElem.attribute("MAX_PX").toDouble(); } - if (subElem.hasAttribute("USED_HEIGHT")) + if(subElem.hasAttribute("USED_HEIGHT")) { mUsedDefaultHeight = subElem.attribute("USED_HEIGHT").toDouble(); } auto data = getData(); - mValid = !std::any_of(data.begin(), data.end(), [](double a){return !std::isfinite(a) || a < 0;}); + mValid = !std::any_of(data.begin(), data.end(), [](double a) { return !std::isfinite(a) || a < 0; }); } void ReprojectionError::setXml(QDomElement &elem) const @@ -1076,54 +1171,67 @@ void ReprojectionError::setXml(QDomElement &elem) const elem.appendChild(subElem); } -double ReprojectionError::pointHeightAvg() const{ +double ReprojectionError::pointHeightAvg() const +{ return mPointHeightAvg; } -double ReprojectionError::pointHeightStdDev() const{ +double ReprojectionError::pointHeightStdDev() const +{ return mPointHeightStdDev; } -double ReprojectionError::pointHeightVariance() const{ +double ReprojectionError::pointHeightVariance() const +{ return mPointHeightVariance; } -double ReprojectionError::pointHeightMax() const{ +double ReprojectionError::pointHeightMax() const +{ return mPointHeightMax; } -double ReprojectionError::defaultHeightAvg() const{ +double ReprojectionError::defaultHeightAvg() const +{ return mDefaultHeightAvg; } -double ReprojectionError::defaultHeightStdDev() const{ +double ReprojectionError::defaultHeightStdDev() const +{ return mDefaultHeightStdDev; } -double ReprojectionError::defaultHeightVariance() const{ +double ReprojectionError::defaultHeightVariance() const +{ return mDefaultHeightVariance; } -double ReprojectionError::defaultHeightMax() const{ +double ReprojectionError::defaultHeightMax() const +{ return mDefaultHeightMax; } -double ReprojectionError::pixelAvg() const{ +double ReprojectionError::pixelAvg() const +{ return mPixelAvg; } -double ReprojectionError::pixelStdDev() const{ +double ReprojectionError::pixelStdDev() const +{ return mPixelStdDev; } -double ReprojectionError::pixelVariance() const{ +double ReprojectionError::pixelVariance() const +{ return mPixelVariance; } -double ReprojectionError::pixelMax() const{ +double ReprojectionError::pixelMax() const +{ return mPixelMax; } -double ReprojectionError::usedDefaultHeight() const{ +double ReprojectionError::usedDefaultHeight() const +{ return mUsedDefaultHeight; } diff --git a/src/filter.cpp b/src/filter.cpp index efc1cb879bb29ad13d284d0ba406bbbec49a5307..a9873a83a50fe1f7a1b9cc807d3c15785ceb4a3b 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -25,15 +25,15 @@ Parameter::Parameter() { mValue = mMinimum = mMaximum = 0; - mChg = false; - mFilter = nullptr; + mChg = false; + mFilter = nullptr; } void Parameter::setFilter(Filter *filter) { mFilter = filter; } -Filter * Parameter::getFilter() +Filter *Parameter::getFilter() { return mFilter; } @@ -48,7 +48,7 @@ double Parameter::getValue() const } void Parameter::setValue(double d) { - if (d != mValue) + if(d != mValue) { mValue = d; setChanged(true); @@ -83,7 +83,7 @@ bool Parameter::getChanged() const void Parameter::setChanged(bool b) { mChg = b; - if (mFilter) + if(mFilter) mFilter->setChanged(true); } @@ -93,7 +93,7 @@ Filter::Filter() { mEnable = true; mOnCopy = true; - mChg = false; + mChg = false; } /** @@ -117,7 +117,7 @@ bool Filter::getChanged() } void Filter::setChanged(bool b) { - mChg=b; + mChg = b; } /** @@ -134,24 +134,25 @@ void Filter::setChanged(bool b) */ cv::Mat Filter::apply(cv::Mat &img) { - if (getEnabled()) + if(getEnabled()) { - if (getOnCopy()) + if(getOnCopy()) { - cv::Mat res(cv::Size(img.cols,img.rows),CV_8UC(img.channels())); - mRes = act(img,res); + cv::Mat res(cv::Size(img.cols, img.rows), CV_8UC(img.channels())); + mRes = act(img, res); mChg = false; return mRes; - }else + } + else { - mRes = act(img,img); + mRes = act(img, img); mChg = false; return mRes; } - - }else + } + else { - mChg = false; + mChg = false; return mRes = img; } } @@ -163,22 +164,22 @@ cv::Mat Filter::getLastResult() void Filter::freeLastResult() { - //free oder delete? - beides falsch + // free oder delete? - beides falsch } void Filter::enable() { - mChg = true; + mChg = true; mEnable = true; } void Filter::disable() { - mChg = true; + mChg = true; mEnable = false; } void Filter::setEnabled(bool b) { - mChg = true; + mChg = true; mEnable = b; } bool Filter::getEnabled() const @@ -188,7 +189,7 @@ bool Filter::getEnabled() const void Filter::setOnCopy(bool b) { - mChg = true; + mChg = true; mOnCopy = b; } bool Filter::getOnCopy() const diff --git a/src/gridItem.cpp b/src/gridItem.cpp index 880215928b6aeefad3828f2d29c0ec1989409ce8..032dbd6130f48d0ef86a46a415dfd012b3e2ce53 100644 --- a/src/gridItem.cpp +++ b/src/gridItem.cpp @@ -18,19 +18,19 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> -#include <cmath> +#include "gridItem.h" -#include "petrack.h" #include "control.h" +#include "petrack.h" #include "view.h" -#include "gridItem.h" -GridItem::GridItem(QWidget *wParent, QGraphicsItem * parent) - : QGraphicsItem(parent) +#include <QtWidgets> +#include <cmath> + +GridItem::GridItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) { - mMainWindow = (class Petrack*) wParent; - extCalib = mMainWindow->getExtrCalibration(); + mMainWindow = (class Petrack *) wParent; + extCalib = mMainWindow->getExtrCalibration(); mControlWidget = mMainWindow->getControlWidget(); } @@ -46,54 +46,63 @@ QRectF GridItem::boundingRect() const { // -mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize() TUTS NICHT !!!!! // aber setMatrix istr hier nicht so schoen - if (mMainWindow->getImage()) - return QRectF(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), mMainWindow->getImage()->width(), mMainWindow->getImage()->height()); + if(mMainWindow->getImage()) + return QRectF( + -mMainWindow->getImageBorderSize(), + -mMainWindow->getImageBorderSize(), + mMainWindow->getImage()->width(), + mMainWindow->getImage()->height()); else return QRectF(0, 0, 0, 0); // FOLGENDE ZEILE HAT FUER ENDLOSSCHLEIFE GESORGT; DA QT INTERN SICH 2 FKT GEGENSEITIG AUFGERUFEN HABEN!!!!!!!!!! - //return QRectF(0, 0, mMainWindow->getScene()->width(), mMainWindow->getScene()->height()); + // return QRectF(0, 0, mMainWindow->getScene()->width(), mMainWindow->getScene()->height()); } // event, of moving mouse while pressing a mouse button void GridItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (!mControlWidget->getCalibGridFix()) + if(!mControlWidget->getCalibGridFix()) { setCursor(Qt::SizeBDiagCursor); - QPointF diff = event->scenePos()-event->lastScenePos(); //screenPos()-buttonDownScreenPos(Qt::RightButton) also interesting - if (event->buttons() == Qt::RightButton) // event->button() doesnt work + QPointF diff = event->scenePos() - + event->lastScenePos(); // screenPos()-buttonDownScreenPos(Qt::RightButton) also interesting + if(event->buttons() == Qt::RightButton) // event->button() doesnt work { - - mControlWidget->setCalibGridRotate(mControlWidget->getCalibGridRotate()+(int)(3.*(diff.x()+diff.y()))); + mControlWidget->setCalibGridRotate( + mControlWidget->getCalibGridRotate() + (int) (3. * (diff.x() + diff.y()))); } - else if (event->buttons() == Qt::LeftButton) + else if(event->buttons() == Qt::LeftButton) { - if( mControlWidget->getCalibGridDimension() == 0 ) + if(mControlWidget->getCalibGridDimension() == 0) { - cv::Point3f p3d = extCalib->get3DPoint(cv::Point2f(event->scenePos().x(), - event->scenePos().y()), - mControlWidget->getCalibGrid3DTransZ()); - cv::Point3f p3d_last = extCalib->get3DPoint(cv::Point2f(mouse_x/*event->lastScenePos().x()*/, - mouse_y/*event->lastScenePos().y()*/), - mControlWidget->getCalibGrid3DTransZ()); - mControlWidget->setCalibGrid3DTransX(gridTrans_x+(mControlWidget->getCalibCoord3DSwapX() ? -1 : 1)*round(p3d.x-p3d_last.x)); - mControlWidget->setCalibGrid3DTransY(gridTrans_y+(mControlWidget->getCalibCoord3DSwapY() ? -1 : 1)*round(p3d.y-p3d_last.y)); - - }else + cv::Point3f p3d = extCalib->get3DPoint( + cv::Point2f(event->scenePos().x(), event->scenePos().y()), mControlWidget->getCalibGrid3DTransZ()); + cv::Point3f p3d_last = extCalib->get3DPoint( + cv::Point2f(mouse_x /*event->lastScenePos().x()*/, mouse_y /*event->lastScenePos().y()*/), + mControlWidget->getCalibGrid3DTransZ()); + mControlWidget->setCalibGrid3DTransX( + gridTrans_x + (mControlWidget->getCalibCoord3DSwapX() ? -1 : 1) * round(p3d.x - p3d_last.x)); + mControlWidget->setCalibGrid3DTransY( + gridTrans_y + (mControlWidget->getCalibCoord3DSwapY() ? -1 : 1) * round(p3d.y - p3d_last.y)); + } + else { - std::cout << "Grid Move 2D: "<<diff.x() << ", " << diff.y() << std::endl; - mControlWidget->setCalibGridTransX(mControlWidget->getCalibGridTransX()+(int)(10.*diff.x())); - mControlWidget->setCalibGridTransY(mControlWidget->getCalibGridTransY()+(int)(10.*diff.y())); + std::cout << "Grid Move 2D: " << diff.x() << ", " << diff.y() << std::endl; + mControlWidget->setCalibGridTransX(mControlWidget->getCalibGridTransX() + (int) (10. * diff.x())); + mControlWidget->setCalibGridTransY(mControlWidget->getCalibGridTransY() + (int) (10. * diff.y())); } } - else if (event->buttons() == Qt::MiddleButton) + else if(event->buttons() == Qt::MiddleButton) { - if( mControlWidget->getCalibGridDimension() == 0) + if(mControlWidget->getCalibGridDimension() == 0) { - mControlWidget->setCalibGrid3DResolution(mControlWidget->getCalibGrid3DResolution()+(int)(10.*(diff.x()-diff.y()))); - }else + mControlWidget->setCalibGrid3DResolution( + mControlWidget->getCalibGrid3DResolution() + (int) (10. * (diff.x() - diff.y()))); + } + else { - mControlWidget->setCalibGridScale(mControlWidget->getCalibGridScale()+(int)(10.*(diff.x()-diff.y()))); + mControlWidget->setCalibGridScale( + mControlWidget->getCalibGridScale() + (int) (10. * (diff.x() - diff.y()))); } } } @@ -103,9 +112,9 @@ void GridItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void GridItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (!mControlWidget->getCalibGridFix()) + if(!mControlWidget->getCalibGridFix()) { - if (event->button() == Qt::LeftButton) + if(event->button() == Qt::LeftButton) { mouse_x = event->scenePos().x(); mouse_y = event->scenePos().y(); @@ -113,20 +122,21 @@ void GridItem::mousePressEvent(QGraphicsSceneMouseEvent *event) gridTrans_x = mControlWidget->getCalibGrid3DTransX(); gridTrans_y = mControlWidget->getCalibGrid3DTransY(); } - }else + } + else { QGraphicsItem::mousePressEvent(event); } } -int GridItem::drawLine(QPainter *painter, cv::Point2f *p, int y_offset){ - - int bS = mMainWindow->getImageBorderSize(); +int GridItem::drawLine(QPainter *painter, cv::Point2f *p, int y_offset) +{ + int bS = mMainWindow->getImageBorderSize(); QImage *img = mMainWindow->getImage(); int iW, iH; - if (img) + if(img) { iW = img->width(); iH = img->height(); @@ -138,119 +148,127 @@ int GridItem::drawLine(QPainter *painter, cv::Point2f *p, int y_offset){ } - double x1_d = 0., y1_d = 0., x2_d = 0. , y2_d = 0.; + double x1_d = 0., y1_d = 0., x2_d = 0., y2_d = 0.; // Steigung m und Achsenabschnitt b der Geraden berechnen: g(x) = m * x + b - double m = (p[1].y-p[0].y)/(p[1].x-p[0].x), // Steigung - b = p[1].y-m*p[1].x; // Achsenabschnitt + double m = (p[1].y - p[0].y) / (p[1].x - p[0].x), // Steigung + b = p[1].y - m * p[1].x; // Achsenabschnitt // boolean Werte fuer beide Endpunkte der Geraden, am Ende schauen, ob beide gesetzt wurden bool p1IsSet = false, p2IsSet = false; // Sonderfall falls Steigung unendlich ist (horizontale Linie) - if( isinf(m) ) + if(isinf(m)) { - if( p[0].x >= 0-bS && p[0].x <= iW-bS ) + if(p[0].x >= 0 - bS && p[0].x <= iW - bS) { - painter->drawLine(QPointF(p[0].x,-bS),QPointF(p[1].x,iH-bS)); + painter->drawLine(QPointF(p[0].x, -bS), QPointF(p[1].x, iH - bS)); return 1; } } // Schnittpunkt mit oberer Bildkante? ( y = y_offset ) - if( (y_offset-b)/m >= 0-bS && (y_offset-b)/m <= iW-bS ){ - x1_d = (y_offset-b)/m; - y1_d = y_offset; + if((y_offset - b) / m >= 0 - bS && (y_offset - b) / m <= iW - bS) + { + x1_d = (y_offset - b) / m; + y1_d = y_offset; p1IsSet = true; } // Schnittpunkt mit rechter Bildkante? ( x = iW-bS ) - if( m*(iW-bS)+b >= y_offset && m*(iW-bS)+b <= iH-bS ){ - if( p1IsSet ){ - x2_d = iW-bS; - y2_d = m*(iW-bS)+b; + if(m * (iW - bS) + b >= y_offset && m * (iW - bS) + b <= iH - bS) + { + if(p1IsSet) + { + x2_d = iW - bS; + y2_d = m * (iW - bS) + b; p2IsSet = true; - }else{ - x1_d = iW-bS; - y1_d = m*(iW-bS)+b; + } + else + { + x1_d = iW - bS; + y1_d = m * (iW - bS) + b; p1IsSet = true; } } // Schnittpunkt mit unterer Bildkante? ( y = iH-bS ) - if( (iH-bS-b)/m >= 0-bS && (iH-bS-b)/m <= iW-bS ){ - if( p1IsSet ){ - x2_d = (iH-bS-b)/m; - y2_d = iH-bS; + if((iH - bS - b) / m >= 0 - bS && (iH - bS - b) / m <= iW - bS) + { + if(p1IsSet) + { + x2_d = (iH - bS - b) / m; + y2_d = iH - bS; p2IsSet = true; - }else{ - x1_d = (iH-bS-b)/m; - y1_d = iH-bS; + } + else + { + x1_d = (iH - bS - b) / m; + y1_d = iH - bS; p1IsSet = true; } } // Schnittpunkt mit linker Bildkante? ( x = 0-bS ) - if( m*(-bS)+b >= y_offset && m*(-bS)+b <= iH-bS ){ - if( p1IsSet ){ - x2_d = -bS; - y2_d = m*(-bS)+b; + if(m * (-bS) + b >= y_offset && m * (-bS) + b <= iH - bS) + { + if(p1IsSet) + { + x2_d = -bS; + y2_d = m * (-bS) + b; p2IsSet = true; - }else{ - x1_d = -bS; - y1_d = m*(-bS)+b; + } + else + { + x1_d = -bS; + y1_d = m * (-bS) + b; p1IsSet = true; } } // Schauen, ob beide Endpunkte der Geraden gesetzt wurden - if( p1IsSet && p2IsSet ) + if(p1IsSet && p2IsSet) { - painter->drawLine(QPointF(x1_d,y1_d),QPointF(x2_d,y2_d)); + painter->drawLine(QPointF(x1_d, y1_d), QPointF(x2_d, y2_d)); return 1; } return 0; } -void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) +void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - bool debug = false; - if (!mControlWidget->getCalibGridFix() && mControlWidget->getCalibGridShow()) + if(!mControlWidget->getCalibGridFix() && mControlWidget->getCalibGridShow()) { - setFlag(ItemIsMovable); // noetig, damit mouseEvent leftmousebutton weitergegeben wird, aber drag mach ich selber + setFlag( + ItemIsMovable); // noetig, damit mouseEvent leftmousebutton weitergegeben wird, aber drag mach ich selber } else { setFlag(ItemIsMovable, false); } - int tX3D = mControlWidget->getCalibGrid3DTransX(); - int tY3D = mControlWidget->getCalibGrid3DTransY(); - int tZ3D = mControlWidget->getCalibGrid3DTransZ(); + int tX3D = mControlWidget->getCalibGrid3DTransX(); + int tY3D = mControlWidget->getCalibGrid3DTransY(); + int tZ3D = mControlWidget->getCalibGrid3DTransZ(); int resolution = mControlWidget->getCalibGrid3DResolution(); // confirmation prompt if the vanish points are inside the image - bool vanishPointIsInsideImage = false; - bool vanishPointYIsInsideImage = false; - bool vanishPointXIsInsideImage = false; + bool vanishPointIsInsideImage = false; + bool vanishPointYIsInsideImage = false; + bool vanishPointXIsInsideImage = false; cv::Point2f vanishPointY, vanishPointX; - double x,y; - if( mMainWindow->getImage() && extCalib->isSetExtrCalib() ) + double x, y; + if(mMainWindow->getImage() && extCalib->isSetExtrCalib()) { - // create 2 parallel lines in x-direction - cv::Point3f a3d = cv::Point3f(-500,-500,0), - b3d = cv::Point3f(500,-500,0), - c3d = cv::Point3f(-500,500,0), - d3d = cv::Point3f(500,500,0); - cv::Point2f a2d = extCalib->getImagePoint(a3d), - b2d = extCalib->getImagePoint(b3d), - c2d = extCalib->getImagePoint(c3d), - d2d = extCalib->getImagePoint(d3d); - - if( debug ) + cv::Point3f a3d = cv::Point3f(-500, -500, 0), b3d = cv::Point3f(500, -500, 0), c3d = cv::Point3f(-500, 500, 0), + d3d = cv::Point3f(500, 500, 0); + cv::Point2f a2d = extCalib->getImagePoint(a3d), b2d = extCalib->getImagePoint(b3d), + c2d = extCalib->getImagePoint(c3d), d2d = extCalib->getImagePoint(d3d); + + if(debug) { debout << "A3d x=" << a3d.x << ", y=" << a3d.y << ", z=" << a3d.z << std::endl; debout << "B3d x=" << b3d.x << ", y=" << b3d.y << ", z=" << b3d.z << std::endl; @@ -262,31 +280,27 @@ void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option debout << "C2d x=" << c2d.x << ", y=" << c2d.y << std::endl; } // y = m*x+n - float m1 = (b2d.y-a2d.y)/(b2d.x-a2d.x), - m2 = (d2d.y-c2d.y)/(d2d.x-c2d.x), - n1 = a2d.y-m1*a2d.x, - n2 = c2d.y-m2*c2d.x; - if( debug ) debout << "m1=" << m1 << ", m2=" << m2 << ", n1=" << n1 << ", n2=" << n2 << std::endl; + float m1 = (b2d.y - a2d.y) / (b2d.x - a2d.x), m2 = (d2d.y - c2d.y) / (d2d.x - c2d.x), n1 = a2d.y - m1 * a2d.x, + n2 = c2d.y - m2 * c2d.x; + if(debug) + debout << "m1=" << m1 << ", m2=" << m2 << ", n1=" << n1 << ", n2=" << n2 << std::endl; - x = (n2-n1)/(m1-m2); - y = ((m1*x+n1)+(m2*x+n2))/2.0; + x = (n2 - n1) / (m1 - m2); + y = ((m1 * x + n1) + (m2 * x + n2)) / 2.0; - vanishPointY = cv::Point2f(x,y); + vanishPointY = cv::Point2f(x, y); - if( debug ) debout << "Vanish Point (x): (x=" << x << ", y=" << y << ")" << std::endl; + if(debug) + debout << "Vanish Point (x): (x=" << x << ", y=" << y << ")" << std::endl; // create 2 parallel lines in y-direction - a3d = cv::Point3f(-500,-500,0), - b3d = cv::Point3f(-500,500,0), - c3d = cv::Point3f(500,-500,0), - d3d = cv::Point3f(500,500,0); - a2d = extCalib->getImagePoint(a3d), - b2d = extCalib->getImagePoint(b3d), - c2d = extCalib->getImagePoint(c3d), - d2d = extCalib->getImagePoint(d3d); - - if( debug ) + a3d = cv::Point3f(-500, -500, 0), b3d = cv::Point3f(-500, 500, 0), c3d = cv::Point3f(500, -500, 0), + d3d = cv::Point3f(500, 500, 0); + a2d = extCalib->getImagePoint(a3d), b2d = extCalib->getImagePoint(b3d), c2d = extCalib->getImagePoint(c3d), + d2d = extCalib->getImagePoint(d3d); + + if(debug) { debout << "A3d x=" << a3d.x << ", y=" << a3d.y << ", z=" << a3d.z << std::endl; debout << "B3d x=" << b3d.x << ", y=" << b3d.y << ", z=" << b3d.z << std::endl; @@ -299,67 +313,73 @@ void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option debout << "D2d x=" << d2d.x << ", y=" << d2d.y << std::endl; } // y = m*x+n - m1 = (b2d.y-a2d.y)/(b2d.x-a2d.x), - m2 = (d2d.y-c2d.y)/(d2d.x-c2d.x), - n1 = a2d.y-m1*a2d.x, - n2 = c2d.y-m2*c2d.x; + m1 = (b2d.y - a2d.y) / (b2d.x - a2d.x), m2 = (d2d.y - c2d.y) / (d2d.x - c2d.x), n1 = a2d.y - m1 * a2d.x, + n2 = c2d.y - m2 * c2d.x; - if( debug ) debout << "m1=" << m1 << ", m2=" << m2 << ", n1=" << n1 << ", n2=" << n2 << std::endl; + if(debug) + debout << "m1=" << m1 << ", m2=" << m2 << ", n1=" << n1 << ", n2=" << n2 << std::endl; - x = (n2-n1)/(m1-m2); - y = ((m1*x+n1)+(m2*x+n2))/2.0; - vanishPointX = cv::Point2f(x,y); + x = (n2 - n1) / (m1 - m2); + y = ((m1 * x + n1) + (m2 * x + n2)) / 2.0; + vanishPointX = cv::Point2f(x, y); - if( debug ) debout << "Vanish Point: (x=" << x << ", y=" << y << ")" << std::endl; + if(debug) + debout << "Vanish Point: (x=" << x << ", y=" << y << ")" << std::endl; vanishPointYIsInsideImage = !extCalib->isOutsideImage(vanishPointY); vanishPointXIsInsideImage = !extCalib->isOutsideImage(vanishPointX); - if( vanishPointYIsInsideImage ) + if(vanishPointYIsInsideImage) { - if( debug ) debout << "Vanish Point 1 is inside the image!" << std::endl; + if(debug) + debout << "Vanish Point 1 is inside the image!" << std::endl; } - if( vanishPointXIsInsideImage ) + if(vanishPointXIsInsideImage) { - if( debug ) debout << "Vanish Point 2 is inside the image!" << std::endl; + if(debug) + debout << "Vanish Point 2 is inside the image!" << std::endl; } //////////////////////////////// // Drawing Vanish Points // //////////////////////////////// - if( mControlWidget->getCalibExtrVanishPointsShow() ) + if(mControlWidget->getCalibExtrVanishPointsShow()) { painter->setPen(Qt::yellow); - painter->drawLine(QPointF(vanishPointY.x-10,vanishPointY.y-10),QPointF(vanishPointY.x+10,vanishPointY.y+10)); - painter->drawLine(QPointF(vanishPointY.x-10,vanishPointY.y+10),QPointF(vanishPointY.x+10,vanishPointY.y-10)); + painter->drawLine( + QPointF(vanishPointY.x - 10, vanishPointY.y - 10), QPointF(vanishPointY.x + 10, vanishPointY.y + 10)); + painter->drawLine( + QPointF(vanishPointY.x - 10, vanishPointY.y + 10), QPointF(vanishPointY.x + 10, vanishPointY.y - 10)); painter->setPen(Qt::red); - painter->drawPoint(vanishPointY.x,vanishPointY.y); - painter->drawText(vanishPointY.x-20,vanishPointY.y-10,"Vanishing Point (y)"); + painter->drawPoint(vanishPointY.x, vanishPointY.y); + painter->drawText(vanishPointY.x - 20, vanishPointY.y - 10, "Vanishing Point (y)"); painter->setPen(Qt::yellow); - painter->drawLine(QPointF(vanishPointX.x-10,vanishPointX.y-10),QPointF(vanishPointX.x+10,vanishPointX.y+10)); - painter->drawLine(QPointF(vanishPointX.x-10,vanishPointX.y+10),QPointF(vanishPointX.x+10,vanishPointX.y-10)); + painter->drawLine( + QPointF(vanishPointX.x - 10, vanishPointX.y - 10), QPointF(vanishPointX.x + 10, vanishPointX.y + 10)); + painter->drawLine( + QPointF(vanishPointX.x - 10, vanishPointX.y + 10), QPointF(vanishPointX.x + 10, vanishPointX.y - 10)); painter->setPen(Qt::red); - painter->drawPoint(vanishPointX.x,vanishPointX.y); - painter->drawText(vanishPointX.x-20,vanishPointX.y-10,"Vanishing Point (x)"); - + painter->drawPoint(vanishPointX.x, vanishPointX.y); + painter->drawText(vanishPointX.x - 20, vanishPointX.y - 10, "Vanishing Point (x)"); } } - if (mControlWidget->getCalibGridShow()) + if(mControlWidget->getCalibGridShow()) { - QImage *img = mMainWindow->getImage(); + QImage * img = mMainWindow->getImage(); QTransform matrixPaint; - QPointF pnt1, pnt2; // floating point - int bS = mMainWindow->getImageBorderSize(); - if( debug ) debout << "Border-Size: " << bS << std::endl; + QPointF pnt1, pnt2; // floating point + int bS = mMainWindow->getImageBorderSize(); + if(debug) + debout << "Border-Size: " << bS << std::endl; int iW, iH; int maxExp; - if (img) + if(img) { iW = img->width(); iH = img->height(); @@ -369,33 +389,41 @@ void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option iW = (int) mMainWindow->getScene()->width(); iH = (int) mMainWindow->getScene()->height(); } - maxExp = iH>iW?iH:iW; + maxExp = iH > iW ? iH : iW; - if( debug ) debout << "Image-Size: " << iW << "x" << iH << std::endl; + if(debug) + debout << "Image-Size: " << iW << "x" << iH << std::endl; - if( mControlWidget->getCalibGridDimension() == 1 ) + if(mControlWidget->getCalibGridDimension() == 1) { - double sc = mControlWidget->getCalibGridScale()/10.; - double tX = mControlWidget->getCalibGridTransX()/10.; - double tY = mControlWidget->getCalibGridTransY()/10.; - double ro = mControlWidget->getCalibGridRotate()/10.; + double sc = mControlWidget->getCalibGridScale() / 10.; + double tX = mControlWidget->getCalibGridTransX() / 10.; + double tY = mControlWidget->getCalibGridTransY() / 10.; + double ro = mControlWidget->getCalibGridRotate() / 10.; // transformation nicht des koordinatensystems wie bei coorditem sondern bei grid der painter // grid painter->save(); // wie opengl matrix aber auch pen etc auf stack - matrixPaint.translate(tX, tY); // hier ist translate zusaetzlich auf matrix, bei translate-fkt von item ist absolut + matrixPaint.translate( + tX, tY); // hier ist translate zusaetzlich auf matrix, bei translate-fkt von item ist absolut matrixPaint.rotate(ro); - painter->setWorldTransform(matrixPaint, true); // true sagt, dass relativ und nicht absolut (also zusaetzlich zur uebergeordneten matrizen) + painter->setWorldTransform( + matrixPaint, + true); // true sagt, dass relativ und nicht absolut (also zusaetzlich zur uebergeordneten matrizen) painter->setPen(Qt::red); - for (int i=(int)-((maxExp+100)/sc); i<2*(maxExp/sc); i++) + for(int i = (int) -((maxExp + 100) / sc); i < 2 * (maxExp / sc); i++) { - pnt1.setX(i*sc);pnt1.setY(-maxExp-100); - pnt2.setX(i*sc);pnt2.setY(2*maxExp); + pnt1.setX(i * sc); + pnt1.setY(-maxExp - 100); + pnt2.setX(i * sc); + pnt2.setY(2 * maxExp); painter->drawLine(pnt1, pnt2); - pnt1.setX(-maxExp-100);pnt1.setY(i*sc); - pnt2.setX(2*maxExp);pnt2.setY(i*sc); + pnt1.setX(-maxExp - 100); + pnt1.setY(i * sc); + pnt2.setX(2 * maxExp); + pnt2.setY(i * sc); painter->drawLine(pnt1, pnt2); } painter->restore(); // matr etc von stack @@ -403,191 +431,217 @@ void GridItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option // weisses polygon, was ueberragende bereiche von grid ueberdeckt QPointF points[] = { QPointF(-bS, -bS), - QPointF(iW-bS,-bS), - QPointF(iW-bS,iH-bS), - QPointF(iW+3*(maxExp+200)-bS,iH-bS), - QPointF(iW+3*(maxExp+200)-bS,-2*maxExp-100-bS), - QPointF(-2*maxExp-400-bS,-2*maxExp-100-bS), - QPointF(-2*maxExp-400-bS,iH+3*(maxExp+200)-bS), - QPointF(iW+3*(maxExp+200)-bS,iH+3*(maxExp+200)-bS), - QPointF(iW+3*(maxExp+200)-bS,iH-bS), - QPointF(-bS,iH-bS) - }; + QPointF(iW - bS, -bS), + QPointF(iW - bS, iH - bS), + QPointF(iW + 3 * (maxExp + 200) - bS, iH - bS), + QPointF(iW + 3 * (maxExp + 200) - bS, -2 * maxExp - 100 - bS), + QPointF(-2 * maxExp - 400 - bS, -2 * maxExp - 100 - bS), + QPointF(-2 * maxExp - 400 - bS, iH + 3 * (maxExp + 200) - bS), + QPointF(iW + 3 * (maxExp + 200) - bS, iH + 3 * (maxExp + 200) - bS), + QPointF(iW + 3 * (maxExp + 200) - bS, iH - bS), + QPointF(-bS, iH - bS)}; painter->setPen(Qt::NoPen); painter->setBrush(Qt::white); bool drawPolygon = true; - if( drawPolygon ) + if(drawPolygon) { painter->drawPolygon(points, 10); } - - }else + } + else { - if( extCalib->isSetExtrCalib() ){ - + if(extCalib->isSetExtrCalib()) + { double min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN; - int y_offset = -bS; + int y_offset = -bS; - if( vanishPointXIsInsideImage ){ - y_offset = vanishPointX.y+100; + if(vanishPointXIsInsideImage) + { + y_offset = vanishPointX.y + 100; } - if( vanishPointYIsInsideImage ){ - y_offset = vanishPointY.y+100; + if(vanishPointYIsInsideImage) + { + y_offset = vanishPointY.y + 100; } - if( debug ) std::cout << "y_offset: " << y_offset << std::endl; + if(debug) + std::cout << "y_offset: " << y_offset << std::endl; cv::Point3f points[4]; // top left corner - points[0] = extCalib->get3DPoint(cv::Point2f(0-bS,y_offset),tZ3D); + points[0] = extCalib->get3DPoint(cv::Point2f(0 - bS, y_offset), tZ3D); // top right corner - points[1] = extCalib->get3DPoint(cv::Point2f(iW,y_offset),tZ3D); + points[1] = extCalib->get3DPoint(cv::Point2f(iW, y_offset), tZ3D); // bottom left corner - points[2] = extCalib->get3DPoint(cv::Point2f(0-bS,iH),tZ3D); + points[2] = extCalib->get3DPoint(cv::Point2f(0 - bS, iH), tZ3D); // bottom right corner - points[3] = extCalib->get3DPoint(cv::Point2f(iW,iH),tZ3D); + points[3] = extCalib->get3DPoint(cv::Point2f(iW, iH), tZ3D); - if( debug ) debout << "iW: " << iW << " iH: " << iH << " bS: " << bS << " y_offset: " << y_offset << " tZ3D: " << tZ3D << std::endl; + if(debug) + debout << "iW: " << iW << " iH: " << iH << " bS: " << bS << " y_offset: " << y_offset + << " tZ3D: " << tZ3D << std::endl; painter->setPen(Qt::green); - for(int i=0;i<4;i++) + for(int i = 0; i < 4; i++) { x = points[i].x; y = points[i].y; - if (debug) debout << "x: " << x << " y: " << y << std::endl; + if(debug) + debout << "x: " << x << " y: " << y << std::endl; max_x = x > max_x ? x : max_x; min_x = x < min_x ? x : min_x; max_y = y > max_y ? y : max_y; min_y = y < min_y ? y : min_y; - if( debug ) std::cout << ">>>" << points[i].x << ", " << points[i].y << ", " << points[i].z << std::endl; + if(debug) + std::cout << ">>>" << points[i].x << ", " << points[i].y << ", " << points[i].z << std::endl; } - if( debug ) std::cout << "X: min=" << min_x << " min:" << max_x << std::endl; - if( debug ) std::cout << "Y: min=" << min_y << " max:" << max_y << std::endl; + if(debug) + std::cout << "X: min=" << min_x << " min:" << max_x << std::endl; + if(debug) + std::cout << "Y: min=" << min_y << " max:" << max_y << std::endl; - cv::Point3f ursprung(0,0,0); + cv::Point3f ursprung(0, 0, 0); cv::Point3f xl, xr, yo, yu; cv::Point2f p[4]; - QPointF point[4]; + QPointF point[4]; painter->setPen(Qt::red); - if constexpr ( false && vanishPointIsInsideImage ) + if constexpr(false && vanishPointIsInsideImage) { bool simpleMethod = true; - if( simpleMethod ){ + if(simpleMethod) + { // Draw simple Grid around origin point - for(int i=0; i<=2500; i+=resolution) + for(int i = 0; i <= 2500; i += resolution) { - p[0] = extCalib->getImagePoint(cv::Point3f(tX3D+2500,tY3D+i,tZ3D)); - p[1] = extCalib->getImagePoint(cv::Point3f(tX3D,tY3D+i,tZ3D)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); - p[0] = extCalib->getImagePoint(cv::Point3f(tX3D+i,tY3D+2500,tZ3D)); - p[1] = extCalib->getImagePoint(cv::Point3f(tX3D+i,tY3D,tZ3D)); - painter->drawLine(QPointF(p[0].x,p[0].y),QPointF(p[1].x,p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(tX3D + 2500, tY3D + i, tZ3D)); + p[1] = extCalib->getImagePoint(cv::Point3f(tX3D, tY3D + i, tZ3D)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); + p[0] = extCalib->getImagePoint(cv::Point3f(tX3D + i, tY3D + 2500, tZ3D)); + p[1] = extCalib->getImagePoint(cv::Point3f(tX3D + i, tY3D, tZ3D)); + painter->drawLine(QPointF(p[0].x, p[0].y), QPointF(p[1].x, p[1].y)); } - }else + } + else { // Draw line by line - for(int i=min_y*5; i<max_y*5; i+=resolution) + for(int i = min_y * 5; i < max_y * 5; i += resolution) { - for(int j=min_x*5; j<max_x*5; j+=resolution) + for(int j = min_x * 5; j < max_x * 5; j += resolution) { - p[0] = extCalib->getImagePoint(cv::Point3f(tX3D+i,tY3D+j,tZ3D)); - p[1] = extCalib->getImagePoint(cv::Point3f(tX3D+i+resolution,tY3D+j,tZ3D)); + p[0] = extCalib->getImagePoint(cv::Point3f(tX3D + i, tY3D + j, tZ3D)); + p[1] = extCalib->getImagePoint(cv::Point3f(tX3D + i + resolution, tY3D + j, tZ3D)); - point[0] = QPointF(p[0].x,p[0].y); - point[1] = QPointF(p[1].x,p[1].y); + point[0] = QPointF(p[0].x, p[0].y); + point[1] = QPointF(p[1].x, p[1].y); - p[0] = extCalib->getImagePoint(cv::Point3f(tX3D+i,tY3D+j,tZ3D)); - p[1] = extCalib->getImagePoint(cv::Point3f(tX3D+i,tY3D+j+resolution,tZ3D)); + p[0] = extCalib->getImagePoint(cv::Point3f(tX3D + i, tY3D + j, tZ3D)); + p[1] = extCalib->getImagePoint(cv::Point3f(tX3D + i, tY3D + j + resolution, tZ3D)); - point[2] = QPointF(p[0].x,p[0].y); - point[3] = QPointF(p[1].x,p[1].y); + point[2] = QPointF(p[0].x, p[0].y); + point[3] = QPointF(p[1].x, p[1].y); - if( ( point[0].x() > -bS && point[0].x() < (iW+bS) && point[0].y() > -bS && point[0].y() < (iH+bS) ) || - ( point[1].x() > -bS && point[1].x() < (iW+bS) && point[1].y() > -bS && point[1].y() < (iH+bS) ) || - ( point[3].x() > -bS && point[3].x() < (iW+bS) && point[2].y() > -bS && point[2].y() < (iH+bS) ) || - ( point[2].x() > -bS && point[2].x() < (iW+bS) && point[3].y() > -bS && point[3].y() < (iH+bS) ) ) + if((point[0].x() > -bS && point[0].x() < (iW + bS) && point[0].y() > -bS && + point[0].y() < (iH + bS)) || + (point[1].x() > -bS && point[1].x() < (iW + bS) && point[1].y() > -bS && + point[1].y() < (iH + bS)) || + (point[3].x() > -bS && point[3].x() < (iW + bS) && point[2].y() > -bS && + point[2].y() < (iH + bS)) || + (point[2].x() > -bS && point[2].x() < (iW + bS) && point[3].y() > -bS && + point[3].y() < (iH + bS))) { - float a = sqrt( pow(point[1].x()-point[0].x(), 2) + pow(point[1].y()-point[0].y(), 2) ), - b = sqrt( pow(point[3].x()-point[2].x(), 2) + pow(point[3].y()-point[2].y(), 2) ), - c = sqrt( pow(point[1].x()-point[3].x(), 2) + pow(point[1].y()-point[3].y(), 2) ), - s = (a+b+c) / 2.0; - if( sqrt(s*(s-a)*(s-b)*(s-c)) > 15 ) + float a = sqrt( + pow(point[1].x() - point[0].x(), 2) + + pow(point[1].y() - point[0].y(), 2)), + b = sqrt( + pow(point[3].x() - point[2].x(), 2) + + pow(point[3].y() - point[2].y(), 2)), + c = sqrt( + pow(point[1].x() - point[3].x(), 2) + + pow(point[1].y() - point[3].y(), 2)), + s = (a + b + c) / 2.0; + if(sqrt(s * (s - a) * (s - b) * (s - c)) > 15) { - painter->drawLine(point[0],point[1]); - painter->drawLine(point[2],point[3]); + painter->drawLine(point[0], point[1]); + painter->drawLine(point[2], point[3]); } } } } } - - }else + } + else { - - int swapX = mControlWidget->getCalibCoord3DSwapX() ? -1 : 1; int swapY = mControlWidget->getCalibCoord3DSwapY() ? -1 : 1; - int grid_height = tZ3D-mControlWidget->getCalibCoord3DTransZ(); // Da extCalibration immer vom Koordinatensystemursprung ausgeht (Das Grid soll aber unabhngig davon gezeichnet werden) - - if( debug ) debout << "Grid x: " << tX3D << " y: " << tY3D << " z: " << tZ3D << " y_offset: " - << y_offset << " bS: " << bS << " iW: " << iW << " iH: " << iH - << " min_x: " << min_x << " max_x: " << max_x << " min_y: " << min_y << " max_y: " << max_y << std::endl; - - // horizontal lines from the left to the right on height tZ3D the lines start from origin point (tY3D) - // until max_y or if tY3D < min_y it starts with min_y because otherwise it is outside the image - - for(int i = -mControlWidget->getCalibCoord3DTransY()+tY3D; i < (swapY > 0 ? max_y : -min_y); i+=resolution) + int grid_height = + tZ3D - + mControlWidget + ->getCalibCoord3DTransZ(); // Da extCalibration immer vom Koordinatensystemursprung ausgeht + // (Das Grid soll aber unabhngig davon gezeichnet werden) + + if(debug) + debout << "Grid x: " << tX3D << " y: " << tY3D << " z: " << tZ3D << " y_offset: " << y_offset + << " bS: " << bS << " iW: " << iW << " iH: " << iH << " min_x: " << min_x + << " max_x: " << max_x << " min_y: " << min_y << " max_y: " << max_y << std::endl; + + // horizontal lines from the left to the right on height tZ3D the lines start from origin point + // (tY3D) until max_y or if tY3D < min_y it starts with min_y because otherwise it is outside the + // image + + for(int i = -mControlWidget->getCalibCoord3DTransY() + tY3D; i < (swapY > 0 ? max_y : -min_y); + i += resolution) { // Bildpunkte zu den Endpunkten der Linie holen - p[0] = extCalib->getImagePoint(cv::Point3f(min_x,swapY*i,grid_height)); - p[1] = extCalib->getImagePoint(cv::Point3f(max_x,swapY*i,grid_height)); - drawLine(painter,p,y_offset); + p[0] = extCalib->getImagePoint(cv::Point3f(min_x, swapY * i, grid_height)); + p[1] = extCalib->getImagePoint(cv::Point3f(max_x, swapY * i, grid_height)); + drawLine(painter, p, y_offset); } // see above but now the lines start from origin point (tY3D) until min_y // y- - for(int i = -mControlWidget->getCalibCoord3DTransY()+tY3D-resolution; i > (swapY > 0 ? min_y : -max_y); i-=resolution) + for(int i = -mControlWidget->getCalibCoord3DTransY() + tY3D - resolution; + i > (swapY > 0 ? min_y : -max_y); + i -= resolution) { // Bildpunkte zu den Endpunkten der Linie holen - p[0] = extCalib->getImagePoint(cv::Point3f(min_x,swapY*i,grid_height)); - p[1] = extCalib->getImagePoint(cv::Point3f(max_x,swapY*i,grid_height)); - drawLine(painter,p,y_offset); + p[0] = extCalib->getImagePoint(cv::Point3f(min_x, swapY * i, grid_height)); + p[1] = extCalib->getImagePoint(cv::Point3f(max_x, swapY * i, grid_height)); + drawLine(painter, p, y_offset); } // vertical lines from the top to the bottom on height tZ3D the lines start from origin point(tX3D) - // until max_x of if tX3D < minx it starts with min_x because otherwise the lines are outside the image - // x+ - for(int i = -mControlWidget->getCalibCoord3DTransX()+tX3D; i < (swapX > 0 ? max_x : -min_x); i+=resolution) + // until max_x of if tX3D < minx it starts with min_x because otherwise the lines are outside the + // image x+ + for(int i = -mControlWidget->getCalibCoord3DTransX() + tX3D; i < (swapX > 0 ? max_x : -min_x); + i += resolution) { // Bildpunkte zu den Endpunkten der Linie holen - p[0] = extCalib->getImagePoint(cv::Point3f(swapX*i,min_y,grid_height)); - p[1] = extCalib->getImagePoint(cv::Point3f(swapX*i,max_y,grid_height)); - drawLine(painter,p,y_offset); + p[0] = extCalib->getImagePoint(cv::Point3f(swapX * i, min_y, grid_height)); + p[1] = extCalib->getImagePoint(cv::Point3f(swapX * i, max_y, grid_height)); + drawLine(painter, p, y_offset); } // see above but now the lines start from origin point until min_x // x- - for(int i = -mControlWidget->getCalibCoord3DTransX()+tX3D-resolution; i > (swapX > 0 ? min_x : -max_x); i-=resolution) + for(int i = -mControlWidget->getCalibCoord3DTransX() + tX3D - resolution; + i > (swapX > 0 ? min_x : -max_x); + i -= resolution) { // Bildpunkte zu den Endpunkten der Linie holen - p[0] = extCalib->getImagePoint(cv::Point3f(swapX*i,min_y,grid_height)); - p[1] = extCalib->getImagePoint(cv::Point3f(swapX*i,max_y,grid_height)); - drawLine(painter,p,y_offset); + p[0] = extCalib->getImagePoint(cv::Point3f(swapX * i, min_y, grid_height)); + p[1] = extCalib->getImagePoint(cv::Point3f(swapX * i, max_y, grid_height)); + drawLine(painter, p, y_offset); } - - } } - } - } } diff --git a/src/helper.cpp b/src/helper.cpp index 163a536a5238c29a9729d7c0326dece94feb6035..1335b620f0523c0010a92c792cb10614b25b02a7 100644 --- a/src/helper.cpp +++ b/src/helper.cpp @@ -22,57 +22,78 @@ #include <opencv2/opencv.hpp> -QString proFileName; ///< Path to the project (.pet) file; used for saving relative paths via getFileList and getExistingFile +QString proFileName; ///< Path to the project (.pet) file; used for saving relative paths via getFileList and + ///< getExistingFile QString commandLineOptionsString = QObject::tr( -"<p><code>petrack [-help|-?] [[-project] project.pet] </code><br>" -" <code>[-sequence imageSequenceOrVideo]</code><br>" -" <code>[-autoSave|-autosave imgFldOrVideo|proj.pet|trackerFile]</code></code><br>" -" <code>[-autoTrack|-autotrack trackerFile]</code><br>" -" <code>[-autoReadMarkerID|-autoreadmarkerid markerIdFile]</code><br>"" <code>[-autoReadHeight|-autoreadheight heightFile]</code><br>" -" <code>[-autoPlay|-autoplay trackerFile]</code></p>" -"<dl><dt><kbd>-help|-?</kbd></dt><dd>shows help information for command line options</dd>" -"<dt><kbd>-project</kbd></dt><dd>optional option to set project file; otherwise the argument without option flag is used as project file</dd>" -"<dt><kbd>-sequence imageSequenceOrVideo</kbd></dt><dd>loads image sequence or video; option overwrites <kbd>SRC</kbd> attribute in project file</dd>" -"<dt><kbd>-autoSave|-autosave imgFldOrVideo|proj.pet|trackerFile</kbd></dt><dd>if the argument ends with <kbd>pet</kbd>, a project file will be written to <kbd>proj.pet</kbd> at the end; if the argument ends with <kbd>txt,dat </kbd>or<kbd> trav</kbd>, the trajectories will be written in a format according to the suffix of <kbd>trackerFile</kbd>; otherwise <kbd>imgFldOrVideo</kbd> is the folder to store the image sequence or a name of a video file for the direct export; in all cases <kbd>PeTrack</kbd> ends after finishing the work</dd>" -"<dt><kbd>-autoTrack|-autotrack trackerFile</kbd></dt><dd>calculates automatically the trajectories of marked pedestrians and stores the result to <kbd>trackerFile</kbd></dd>" -"<dt><kbd>-autoReadMarkerID|-autoreadmarkerid markerFile</kbd></dt><dd> automatically reads the <kbd>txt-file</kbd> including personID and markerID and applies the markerIDs to the corresponding person. If -autoTrack is not used, saving trackerFiles using -autoSaveTracker is recommended.</dd>" -"<dt><kbd>-autoReadHeight|-autoreadheight heightFile</kbd></dt><dd> automatically reads the <kbd>trackerFile</kbd> including markerID and individual height and applies the heights to the corresponding person</dd>" -"<dt><kbd>-autoPlay|-autoplay trackerFile</kbd></dt><dd>plays the video or image sequence and stores the trajectories to <kbd>trackerFile</kbd></dd></dl>" -"<p>Example:<br>To generate trajectories from a single image sequence starting with <kbd>frame000.jpg</kbd>" -"with settings stored in the project file <kbd>project.pet</kbd>, export tracker file <kbd>trackerFile</kbd>" -"and exit with saving the project to <kbd>project.pet</kbd> again:</p>" -"<p><code>petrack.exe -project project.pet -sequence frame000.jpg</code><br>" -" <code>-autoTrack trackerFile -autoSave project.pet</code></p>"); - - + "<p><code>petrack [-help|-?] [[-project] project.pet] </code><br>" + " <code>[-sequence imageSequenceOrVideo]</code><br>" + " <code>[-autoSave|-autosave " + "imgFldOrVideo|proj.pet|trackerFile]</code></code><br>" + " <code>[-autoTrack|-autotrack trackerFile]</code><br>" + " <code>[-autoReadMarkerID|-autoreadmarkerid " + "markerIdFile]</code><br>" + " <code>[-autoReadHeight|-autoreadheight " + "heightFile]</code><br>" + " <code>[-autoPlay|-autoplay trackerFile]</code></p>" + "<dl><dt><kbd>-help|-?</kbd></dt><dd>shows help information for command line options</dd>" + "<dt><kbd>-project</kbd></dt><dd>optional option to set project file; otherwise the argument without option flag " + "is used as project file</dd>" + "<dt><kbd>-sequence imageSequenceOrVideo</kbd></dt><dd>loads image sequence or video; option overwrites " + "<kbd>SRC</kbd> attribute in project file</dd>" + "<dt><kbd>-autoSave|-autosave imgFldOrVideo|proj.pet|trackerFile</kbd></dt><dd>if the argument ends with " + "<kbd>pet</kbd>, a project file will be written to <kbd>proj.pet</kbd> at the end; if the argument ends with " + "<kbd>txt,dat </kbd>or<kbd> trav</kbd>, the trajectories will be written in a format according to the suffix of " + "<kbd>trackerFile</kbd>; otherwise <kbd>imgFldOrVideo</kbd> is the folder to store the image sequence or a name of " + "a video file for the direct export; in all cases <kbd>PeTrack</kbd> ends after finishing the work</dd>" + "<dt><kbd>-autoTrack|-autotrack trackerFile</kbd></dt><dd>calculates automatically the trajectories of marked " + "pedestrians and stores the result to <kbd>trackerFile</kbd></dd>" + "<dt><kbd>-autoReadMarkerID|-autoreadmarkerid markerFile</kbd></dt><dd> automatically reads the " + "<kbd>txt-file</kbd> including personID and markerID and applies the markerIDs to the corresponding person. If " + "-autoTrack is not used, saving trackerFiles using -autoSaveTracker is recommended.</dd>" + "<dt><kbd>-autoReadHeight|-autoreadheight heightFile</kbd></dt><dd> automatically reads the <kbd>trackerFile</kbd> " + "including markerID and individual height and applies the heights to the corresponding person</dd>" + "<dt><kbd>-autoPlay|-autoplay trackerFile</kbd></dt><dd>plays the video or image sequence and stores the " + "trajectories to <kbd>trackerFile</kbd></dd></dl>" + "<p>Example:<br>To generate trajectories from a single image sequence starting with <kbd>frame000.jpg</kbd>" + "with settings stored in the project file <kbd>project.pet</kbd>, export tracker file <kbd>trackerFile</kbd>" + "and exit with saving the project to <kbd>project.pet</kbd> again:</p>" + "<p><code>petrack.exe -project project.pet -sequence frame000.jpg</code><br>" + " <code>-autoTrack trackerFile -autoSave " + "project.pet</code></p>"); void copyToQImage(QImage &qImg, cv::Mat &img) // war static functin in animatioln class { - if (qImg.height() != img.rows || qImg.width() != img.cols) //!qImg || ( or qImg has no object behind pointer + if(qImg.height() != img.rows || qImg.width() != img.cols) //! qImg || ( or qImg has no object behind pointer { - qImg = QImage(QSize(img.cols,img.rows),QImage::Format_RGB888); + qImg = QImage(QSize(img.cols, img.rows), QImage::Format_RGB888); } int channels = img.channels(); - if (channels == 3) + if(channels == 3) { // Needs Qt 5.14 for QImage::Format_BGR888 (saves the color transformation into RGB888) - qImg = QImage((const unsigned char*) (img.data),img.cols,img.rows, static_cast<int>(img.step), QImage::Format_BGR888).copy(); + qImg = QImage( + (const unsigned char *) (img.data), + img.cols, + img.rows, + static_cast<int>(img.step), + QImage::Format_BGR888) + .copy(); } - else if (channels == 1) + else if(channels == 1) { // This loop is optimized so it has to calculate the least amount of indexes // Optimizing the access to the pointer data is useless (no difference in performance when tested) - for (int y = 0; y < img.rows; y++) + for(int y = 0; y < img.rows; y++) { // Pointer to the data information in the QImage for just one column // set pointer to value before, because ++p is faster than p++ - for (int x = 0; x < img.cols; x++) + for(int x = 0; x < img.cols; x++) { cv::Scalar colour = img.at<uchar>(cv::Point(x, y)); - qImg.setPixel(x,y,colour.val[0]); + qImg.setPixel(x, y, colour.val[0]); } } } @@ -84,7 +105,7 @@ void copyToQImage(QImage &qImg, cv::Mat &img) // war static functin in animatiol void copyToQImage(QImage *qImg, IplImage *iplImg) { Mat tempMat = cvarrToMat(iplImg); - copyToQImage(qImg,tempMat); + copyToQImage(qImg, tempMat); } #endif @@ -111,46 +132,46 @@ rect wird veraendert, roi nicht */ cv::Mat getRoi(cv::Mat &img, const QRect &roi, cv::Rect &rect, bool evenPixelNumber) { - rect.x = roi.x(); - rect.y = roi.y(); - rect.width = roi.width(); + rect.x = roi.x(); + rect.y = roi.y(); + rect.width = roi.width(); rect.height = roi.height(); - if (evenPixelNumber) + if(evenPixelNumber) { // roi.width and roi.height must be even - if (rect.width % 2 > 0) + if(rect.width % 2 > 0) --rect.width; - if (rect.height % 2 > 0) + if(rect.height % 2 > 0) --rect.height; } // roi.width and roi.height must be >=0 - if (rect.x < 0) + if(rect.x < 0) { rect.width += rect.x; rect.x = 0; } - else if (rect.x > img.cols) + else if(rect.x > img.cols) { rect.width = 0; - rect.x = img.cols; + rect.x = img.cols; } - if (rect.x+rect.width > img.cols) + if(rect.x + rect.width > img.cols) { - rect.width -= (rect.x+rect.width-img.cols); + rect.width -= (rect.x + rect.width - img.cols); } - if (rect.y < 0) + if(rect.y < 0) { rect.height += rect.y; rect.y = 0; } - else if (rect.y > img.rows) + else if(rect.y > img.rows) { rect.height = 0; - rect.y = img.rows; + rect.y = img.rows; } - if (rect.y+rect.height > img.rows) + if(rect.y + rect.height > img.rows) { - rect.height -= (rect.y+rect.height-img.rows); + rect.height -= (rect.y + rect.height - img.rows); } return img(rect); diff --git a/src/imageItem.cpp b/src/imageItem.cpp index fe30658e54af3981975d200210b720b382adbac8..6690990ba8ee98f9fff9506febc855d2430ea626 100644 --- a/src/imageItem.cpp +++ b/src/imageItem.cpp @@ -18,22 +18,22 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include "imageItem.h" + +#include "control.h" +#include "petrack.h" + #include <QGraphicsScene> -#include <QPainter> #include <QGraphicsSceneHoverEvent> +#include <QPainter> #include <cmath> -#include "imageItem.h" -#include "petrack.h" -#include "control.h" - -ImageItem::ImageItem(QWidget *wParent, QGraphicsItem * parent) - : QGraphicsItem(parent) +ImageItem::ImageItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) { - mMainWindow = (class Petrack*) wParent; + mMainWindow = (class Petrack *) wParent; mControlWidget = mMainWindow->getControlWidget(); - mImage = nullptr; - mCoordItem = nullptr; + mImage = nullptr; + mCoordItem = nullptr; setCursor(Qt::CrossCursor); setAcceptHoverEvents(true); } @@ -48,17 +48,18 @@ ImageItem::ImageItem(QWidget *wParent, QGraphicsItem * parent) */ QRectF ImageItem::boundingRect() const { - if (mImage) + if(mImage) { return QRectF(0, 0, mImage->width(), mImage->height()); - }else + } + else return QRectF(0, 0, 0, 0); } - -void ImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) + +void ImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - if (mImage) - painter->drawImage(0,0,*mImage); + if(mImage) + painter->drawImage(0, 0, *mImage); } void ImageItem::setImage(QImage *img) @@ -66,9 +67,11 @@ void ImageItem::setImage(QImage *img) mImage = img; QTransform matrix; - matrix.translate(1, 1); // FEHLER IN QT ????? noetig, damit trotz recognitionroiitem auch image auch ohne border komplett neu gezeichnet wird // wird 2 zeilen weiter zurueckgesetzt, aber mit 0, 0 geht es nicht + matrix.translate( + 1, 1); // FEHLER IN QT ????? noetig, damit trotz recognitionroiitem auch image auch ohne border komplett neu + // gezeichnet wird // wird 2 zeilen weiter zurueckgesetzt, aber mit 0, 0 geht es nicht setTransform(matrix); - matrix.translate(-mMainWindow->getImageBorderSize()-1, -mMainWindow->getImageBorderSize()-1); + matrix.translate(-mMainWindow->getImageBorderSize() - 1, -mMainWindow->getImageBorderSize() - 1); setTransform(matrix); // value nicht setzen, da mgl mehrere videos mit gleichem objektiv erzeugt @@ -78,35 +81,36 @@ void ImageItem::setImage(QImage *img) mControlWidget->setCalibCyMax(mImage->height() /*mImage->height()/2.+50*/); // trans nicht setzen, da mgl mehrere videos mit gleicher scene und gleichem koord sinnvoll - mControlWidget->setCalibCoordTransXMin(-10*mMainWindow->getImageBorderSize()); - mControlWidget->setCalibCoordTransYMin(-10*mMainWindow->getImageBorderSize()); - mControlWidget->setCalibCoordTransXMax(10*(mImage->width()-mMainWindow->getImageBorderSize())); - mControlWidget->setCalibCoordTransYMax(10*(mImage->height()-mMainWindow->getImageBorderSize())); + mControlWidget->setCalibCoordTransXMin(-10 * mMainWindow->getImageBorderSize()); + mControlWidget->setCalibCoordTransYMin(-10 * mMainWindow->getImageBorderSize()); + mControlWidget->setCalibCoordTransXMax(10 * (mImage->width() - mMainWindow->getImageBorderSize())); + mControlWidget->setCalibCoordTransYMax(10 * (mImage->height() - mMainWindow->getImageBorderSize())); mMainWindow->updateSceneRect(); } void ImageItem::setCoordItem(QGraphicsItem *ci) -{ +{ mCoordItem = ci; } // in x und y richtung identisch, da vorher intrinsische kamerakalibrierung geschehen ist double ImageItem::getCmPerPixel() { - if (mCoordItem) + if(mCoordItem) { - // das sollte nur einmal berechne werden, wenn einfliessende daten sich aendern - QPointF p1 = mapToItem(mCoordItem, QPointF(0.,0.)); - QPointF p2 = mapToItem(mCoordItem, QPointF(1.,0.)); - return mControlWidget->getCalibCoordUnit() * sqrt(pow(p1.x()-p2.x(),2) + pow(p1.y()-p2.y(),2)) / 100.; - // durch 100., da coordsys so gezeichnet, dass 1 bei 100 liegt + // das sollte nur einmal berechne werden, wenn einfliessende daten sich aendern + QPointF p1 = mapToItem(mCoordItem, QPointF(0., 0.)); + QPointF p2 = mapToItem(mCoordItem, QPointF(1., 0.)); + return mControlWidget->getCalibCoordUnit() * sqrt(pow(p1.x() - p2.x(), 2) + pow(p1.y() - p2.y(), 2)) / 100.; + // durch 100., da coordsys so gezeichnet, dass 1 bei 100 liegt } else return 0.; } // Liefert zum Pixelpunkt (px,py) die Anzahl der Zentimeter in x- und y-Richtung -QPointF ImageItem::getCmPerPixel(float px, float py, float h){ - // ToDo: +QPointF ImageItem::getCmPerPixel(float px, float py, float h) +{ + // ToDo: // 3D Punkte an (px-0.5, py) und (px+0.5, py) berechnen und Auswirkung in x-Richtung // und (px, py-0.5) und (px, py+0.5) berechnen und Auswirkung in y-Richtung untersuchen // @@ -115,25 +119,32 @@ QPointF ImageItem::getCmPerPixel(float px, float py, float h){ bool debug = false; - cv::Point3f p3x1 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px-0.5,py),h); - cv::Point3f p3x2 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px+0.5,py),h); + cv::Point3f p3x1 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px - 0.5, py), h); + cv::Point3f p3x2 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px + 0.5, py), h); - cv::Point3f p3y1 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px,py-0.5),h); - cv::Point3f p3y2 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px,py+0.5),h); + cv::Point3f p3y1 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px, py - 0.5), h); + cv::Point3f p3y2 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px, py + 0.5), h); - if( debug ) debout << "Punkte: " << p3x1.x << ", " << p3x1.y << ", " << p3x1.z << std::endl; - if( debug ) debout << "Punkte: " << p3x2.x << ", " << p3x2.y << ", " << p3x2.z << std::endl; - if( debug ) debout << "Punkte: " << p3y1.x << ", " << p3y1.y << ", " << p3y1.z << std::endl; - if( debug ) debout << "Punkte: " << p3y2.x << ", " << p3y2.y << ", " << p3y2.z << std::endl; + if(debug) + debout << "Punkte: " << p3x1.x << ", " << p3x1.y << ", " << p3x1.z << std::endl; + if(debug) + debout << "Punkte: " << p3x2.x << ", " << p3x2.y << ", " << p3x2.z << std::endl; + if(debug) + debout << "Punkte: " << p3y1.x << ", " << p3y1.y << ", " << p3y1.z << std::endl; + if(debug) + debout << "Punkte: " << p3y2.x << ", " << p3y2.y << ", " << p3y2.z << std::endl; - double x_dir = norm(p3x1-p3x2); - double y_dir = norm(p3y1-p3y2); + double x_dir = norm(p3x1 - p3x2); + double y_dir = norm(p3y1 - p3y2); - if( debug ) debout << "x_dir: " << x_dir << ", y_dir: " << y_dir << " Durchschnitt: " << (0.5*(x_dir+y_dir)) << std::endl; + if(debug) + debout << "x_dir: " << x_dir << ", y_dir: " << y_dir << " Durchschnitt: " << (0.5 * (x_dir + y_dir)) + << std::endl; - QPointF res(x_dir,y_dir); + QPointF res(x_dir, y_dir); - if( debug ) debout << "CmPerPixel (x,y): " << res << std::endl; + if(debug) + debout << "CmPerPixel (x,y): " << res << std::endl; return res; } @@ -143,84 +154,96 @@ QPointF ImageItem::getCmPerPixel(float px, float py, float h){ /// zur Grundflaeche [0-90] 90 => senkrecht unter der Kamera /// Punktkoordinaten beinhalten die Border ///* -double ImageItem::getAngleToGround(float px, float py, float height){ - +double ImageItem::getAngleToGround(float px, float py, float height) +{ bool debug = false; - cv::Point3f cam( - mControlWidget->getCalibCoord3DTransX() - mControlWidget->getCalibExtrTrans1(), - - mControlWidget->getCalibCoord3DTransY() - mControlWidget->getCalibExtrTrans2(), - - mControlWidget->getCalibCoord3DTransZ() - mControlWidget->getCalibExtrTrans3() ); + cv::Point3f cam( + -mControlWidget->getCalibCoord3DTransX() - mControlWidget->getCalibExtrTrans1(), + -mControlWidget->getCalibCoord3DTransY() - mControlWidget->getCalibExtrTrans2(), + -mControlWidget->getCalibCoord3DTransZ() - mControlWidget->getCalibExtrTrans3()); - cv::Point3f posInImage = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(px-mMainWindow->getImageBorderSize(),py-mMainWindow->getImageBorderSize()),height); + cv::Point3f posInImage = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(px - mMainWindow->getImageBorderSize(), py - mMainWindow->getImageBorderSize()), height); - if( debug ) debout << "Camera: " << cam.x << ", " << cam.y << ", " << cam.z << std::endl; - if( debug ) debout << "posInImage: " << posInImage.x << ", " << posInImage.y << ", " << posInImage.z << std::endl; + if(debug) + debout << "Camera: " << cam.x << ", " << cam.y << ", " << cam.z << std::endl; + if(debug) + debout << "posInImage: " << posInImage.x << ", " << posInImage.y << ", " << posInImage.z << std::endl; - cv::Point3f a(cam.x-posInImage.x,cam.y-posInImage.y,cam.z-posInImage.z), - b(0,0,1); + cv::Point3f a(cam.x - posInImage.x, cam.y - posInImage.y, cam.z - posInImage.z), b(0, 0, 1); - if( debug ) debout << "a: (" << a.x << ", " << a.y << ", " << a.z << ")" << std::endl; - if( debug ) debout << "b: (" << b.x << ", " << b.y << ", " << b.z << ")" << std::endl; + if(debug) + debout << "a: (" << a.x << ", " << a.y << ", " << a.z << ")" << std::endl; + if(debug) + debout << "b: (" << b.x << ", " << b.y << ", " << b.z << ")" << std::endl; - return asin( (a.x*b.x+a.y*b.y+a.z*b.z) / (abs(sqrt(pow(a.x,2)+pow(a.y,2)+pow(a.z,2)))*abs(sqrt(pow(b.x,2)+pow(b.y,2)+pow(b.z,2))))) * 180 / PI; + return asin( + (a.x * b.x + a.y * b.y + a.z * b.z) / (abs(sqrt(pow(a.x, 2) + pow(a.y, 2) + pow(a.z, 2))) * + abs(sqrt(pow(b.x, 2) + pow(b.y, 2) + pow(b.z, 2))))) * + 180 / PI; } QPointF ImageItem::getPosImage(QPointF pos, float height) { - bool debug = false; + bool debug = false; cv::Point2f p2d; - if( mImage ) + if(mImage) { - if( mControlWidget->getCalibCoordDimension() == 0 ) // Tab coordinate system is on 3D + if(mControlWidget->getCalibCoordDimension() == 0) // Tab coordinate system is on 3D { - p2d = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(pos.x(),pos.y(),height)); + p2d = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(pos.x(), pos.y(), height)); pos.setX(p2d.x); pos.setY(p2d.y); - }else + } + else { ////////////// - //Fehlerhaft funktioniert nicht wie gewollt + // Fehlerhaft funktioniert nicht wie gewollt ////////////// // Old 2D mapping of Pixelpoints to RealPositions - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; pos.setY(-pos.y()); - pos /= mControlWidget->getCalibCoordUnit()/100.; // durch 100., da coordsys so gezeichnet, dass 1 bei 100 liegt - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + pos /= mControlWidget->getCalibCoordUnit() / + 100.; // durch 100., da coordsys so gezeichnet, dass 1 bei 100 liegt + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; - pos = mapFromItem(mCoordItem, pos);// Einheit anpassen... - if (mControlWidget->coordUseIntrinsic->checkState() == Qt::Checked) + pos = mapFromItem(mCoordItem, pos); // Einheit anpassen... + if(mControlWidget->coordUseIntrinsic->checkState() == Qt::Checked) { pos.rx() -= mControlWidget->getCalibCxValue(); pos.ry() -= mControlWidget->getCalibCyValue(); } else { - pos.rx() -= mImage->width()/2.-.5; // Bildmitte - pos.ry() -= mImage->height()/2.-.5; // Bildmitte + pos.rx() -= mImage->width() / 2. - .5; // Bildmitte + pos.ry() -= mImage->height() / 2. - .5; // Bildmitte } - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; - pos = (mControlWidget->coordAltitude->value()/(mControlWidget->coordAltitude->value()-height))*pos; //((a-height)/a)*pos; - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; - if (mControlWidget->coordUseIntrinsic->checkState() == Qt::Checked) + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + pos = (mControlWidget->coordAltitude->value() / (mControlWidget->coordAltitude->value() - height)) * + pos; //((a-height)/a)*pos; + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + if(mControlWidget->coordUseIntrinsic->checkState() == Qt::Checked) { pos.rx() += mControlWidget->getCalibCxValue(); pos.ry() += mControlWidget->getCalibCyValue(); } else { - pos.rx() += mImage->width()/2.-.5; // Bildmitte - pos.ry() += mImage->height()/2.-.5; // Bildmitte + pos.rx() += mImage->width() / 2. - .5; // Bildmitte + pos.ry() += mImage->height() / 2. - .5; // Bildmitte } - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; - + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; } - } return pos; - - } // eingabe pos als pixelkoordinate des bildes @@ -229,73 +252,90 @@ QPointF ImageItem::getPosImage(QPointF pos, float height) // wenn kein Bild vorliegt, wird eingabeposition durchgereicht - kommt nicht vor, da kein mouseevent QPointF ImageItem::getPosReal(QPointF pos, double height) { - if (mImage) + if(mImage) { bool debug = false; - int bS = mMainWindow->getImageBorderSize(); + int bS = mMainWindow->getImageBorderSize(); - if( debug ) debout << "Point pos.x: " << pos.x() << " pos.y: " << pos.y() << " height: " << height << std::endl; + if(debug) + debout << "Point pos.x: " << pos.x() << " pos.y: " << pos.y() << " height: " << height << std::endl; // Switch between 2D and 3D CameraCalibration/Position calculation - if( mControlWidget->getCalibCoordDimension() == 0 ) + if(mControlWidget->getCalibCoordDimension() == 0) { // New 3D mapping of Pixelpoints to RealPositions - cv::Point3f p3d = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(pos.x()-bS,pos.y()-bS),height); - - cv::Point2f p2d = debug ? mMainWindow->getExtrCalibration()->getImagePoint(p3d) : cv::Point2f(0,0); - - if( debug ) debout << "########## INFO ###############" << std::endl; - if( debug ) debout << "Org. 2D Point: (" << pos.x() << ", " << pos.y() << ") Hoehe: "<< height << std::endl; - if( debug ) debout << "Est. 3D Point: (" << p3d.x << ", " << p3d.y << ", " << p3d.z << ")" << std::endl; - if( debug ) debout << "Est. 2D Point: (" << p2d.x << ", " << p2d.y << ")" << std::endl; - if( debug ) debout << "######## END INFO #############" << std::endl; + cv::Point3f p3d = + mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(pos.x() - bS, pos.y() - bS), height); + + cv::Point2f p2d = debug ? mMainWindow->getExtrCalibration()->getImagePoint(p3d) : cv::Point2f(0, 0); + + if(debug) + debout << "########## INFO ###############" << std::endl; + if(debug) + debout << "Org. 2D Point: (" << pos.x() << ", " << pos.y() << ") Hoehe: " << height << std::endl; + if(debug) + debout << "Est. 3D Point: (" << p3d.x << ", " << p3d.y << ", " << p3d.z << ")" << std::endl; + if(debug) + debout << "Est. 2D Point: (" << p2d.x << ", " << p2d.y << ")" << std::endl; + if(debug) + debout << "######## END INFO #############" << std::endl; // ToDo: Getting the floor point of the Person! (Only the x/y-coordinates?) - pos = QPointF(p3d.x,p3d.y); - + pos = QPointF(p3d.x, p3d.y); } else { - if( debug ) debout << "########## INFO ###############" << std::endl; - if( debug ) debout << "Org. 2D Point: (" << pos.x() << ", " << pos.y() << ") Hoehe: "<< height << std::endl; + if(debug) + debout << "########## INFO ###############" << std::endl; + if(debug) + debout << "Org. 2D Point: (" << pos.x() << ", " << pos.y() << ") Hoehe: " << height << std::endl; // statt mControlWidget->getCalibFx() muesste spaeter wert stehen, der im verzerrten Bild fX=fY angibt - //a = mControlWidget->getCalibFxValue()*getMeterPerPixel(); - //a = mControlWidget->coordAltitude->value(); + // a = mControlWidget->getCalibFxValue()*getMeterPerPixel(); + // a = mControlWidget->coordAltitude->value(); // -.5 da pixel von 0..1023 (in skala bis 1024 anfaengt) laufen - if (mControlWidget->coordUseIntrinsic->checkState() == Qt::Checked) + if(mControlWidget->coordUseIntrinsic->checkState() == Qt::Checked) { pos.rx() -= mControlWidget->getCalibCxValue(); pos.ry() -= mControlWidget->getCalibCyValue(); } else { - pos.rx() -= mImage->width()/2.-.5; // Bildmitte - pos.ry() -= mImage->height()/2.-.5; // Bildmitte + pos.rx() -= mImage->width() / 2. - .5; // Bildmitte + pos.ry() -= mImage->height() / 2. - .5; // Bildmitte } - if( debug ) debout << "CoordAltitude: " << mControlWidget->coordAltitude->value() << std::endl; - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; - pos = ((mControlWidget->coordAltitude->value()-height)/mControlWidget->coordAltitude->value())*pos; //((a-height)/a)*pos; - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; - if (mControlWidget->coordUseIntrinsic->checkState() == Qt::Checked) + if(debug) + debout << "CoordAltitude: " << mControlWidget->coordAltitude->value() << std::endl; + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + pos = ((mControlWidget->coordAltitude->value() - height) / mControlWidget->coordAltitude->value()) * + pos; //((a-height)/a)*pos; + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + if(mControlWidget->coordUseIntrinsic->checkState() == Qt::Checked) { pos.rx() += mControlWidget->getCalibCxValue(); pos.ry() += mControlWidget->getCalibCyValue(); } else { - pos.rx() += mImage->width()/2.-.5; // Bildmitte - pos.ry() += mImage->height()/2.-.5; // Bildmitte + pos.rx() += mImage->width() / 2. - .5; // Bildmitte + pos.ry() += mImage->height() / 2. - .5; // Bildmitte } // Old 2D mapping of Pixelpoints to RealPositions - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; - pos = mapToItem(mCoordItem, pos);// Einheit anpassen... - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; - pos *= mControlWidget->getCalibCoordUnit()/100.; // durch 100., da coordsys so gezeichnet, dass 1 bei 100 liegt - if( debug ) debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + pos = mapToItem(mCoordItem, pos); // Einheit anpassen... + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; + pos *= mControlWidget->getCalibCoordUnit() / + 100.; // durch 100., da coordsys so gezeichnet, dass 1 bei 100 liegt + if(debug) + debout << "x: " << pos.x() << " y: " << pos.y() << std::endl; pos.setY(-pos.y()); - if( debug ) debout << "Est. 3D Point: (" << pos.x() << ", " << pos.y() << ", " << height << ")" << std::endl; - if( debug ) debout << "######## END INFO #############" << std::endl; - + if(debug) + debout << "Est. 3D Point: (" << pos.x() << ", " << pos.y() << ", " << height << ")" << std::endl; + if(debug) + debout << "######## END INFO #############" << std::endl; } } return pos; @@ -316,21 +356,26 @@ void ImageItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) // sets pixel coord on image for further use bool debug = false; - if( debug ) + if(debug) { - QPointF cmPerPixel = getCmPerPixel(event->pos().x(),event->pos().y(),mMainWindow->getStatusPosRealHeight()); - double angleToGround = getAngleToGround(event->pos().x(),event->pos().y(), mMainWindow->getStatusPosRealHeight()); - debout << "At position: " << event->pos().x() << ", " << event->pos().y() << " cm per pixel: x: " << cmPerPixel.x() << ", y: " << cmPerPixel.y() << ", angle: " << angleToGround << std::endl; - - QPointF posReal = getPosReal(QPointF(event->pos().x(),event->pos().y()), mMainWindow->getStatusPosRealHeight()); - QPointF posImage = getPosImage(posReal,mMainWindow->getStatusPosRealHeight()); + QPointF cmPerPixel = getCmPerPixel(event->pos().x(), event->pos().y(), mMainWindow->getStatusPosRealHeight()); + double angleToGround = + getAngleToGround(event->pos().x(), event->pos().y(), mMainWindow->getStatusPosRealHeight()); + debout << "At position: " << event->pos().x() << ", " << event->pos().y() + << " cm per pixel: x: " << cmPerPixel.x() << ", y: " << cmPerPixel.y() << ", angle: " << angleToGround + << std::endl; + + QPointF posReal = + getPosReal(QPointF(event->pos().x(), event->pos().y()), mMainWindow->getStatusPosRealHeight()); + QPointF posImage = getPosImage(posReal, mMainWindow->getStatusPosRealHeight()); debout << "Pos(real): " << posReal << " Pos(image): " << posImage << std::endl; // Pixel-Koordinaten unter der Kamera bestimmen - QPointF pixUnderCam = getPosImage(QPointF( - -mControlWidget->getCalibCoord3DTransX()-mControlWidget->getCalibExtrTrans1(), - -mControlWidget->getCalibCoord3DTransY()-mControlWidget->getCalibExtrTrans2()), - 0); + QPointF pixUnderCam = getPosImage( + QPointF( + -mControlWidget->getCalibCoord3DTransX() - mControlWidget->getCalibExtrTrans1(), + -mControlWidget->getCalibCoord3DTransY() - mControlWidget->getCalibExtrTrans2()), + 0); pixUnderCam.setX(pixUnderCam.x() + mMainWindow->getImageBorderSize()); pixUnderCam.setY(pixUnderCam.y() + mMainWindow->getImageBorderSize()); @@ -338,20 +383,18 @@ void ImageItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) debout << "Pixel unter der Camera: " << pixUnderCam.x() << ", " << pixUnderCam.y() << std::endl; cv::Point2f pixUnderCam2f = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f( - -mControlWidget->getCalibCoord3DTransX()-mControlWidget->getCalibExtrTrans1(), - -mControlWidget->getCalibCoord3DTransY()-mControlWidget->getCalibExtrTrans2(), - 0)); + -mControlWidget->getCalibCoord3DTransX() - mControlWidget->getCalibExtrTrans1(), + -mControlWidget->getCalibCoord3DTransY() - mControlWidget->getCalibExtrTrans2(), + 0)); pixUnderCam2f.x += mMainWindow->getImageBorderSize(); pixUnderCam2f.y += mMainWindow->getImageBorderSize(); debout << "Pixel unter der Camera: " << pixUnderCam2f.x << ", " << pixUnderCam2f.y << std::endl; - } - - //QPointF pos = event->pos(); + // QPointF pos = event->pos(); mMainWindow->setMousePosOnImage(event->pos()); QGraphicsItem::hoverMoveEvent(event); diff --git a/src/logoItem.cpp b/src/logoItem.cpp index b6d3cce78c6fcb030cfa97f0ac53a5cf8b659091..eaf13f2db8fd494b6748c3bfae25d374f45ca0e9 100644 --- a/src/logoItem.cpp +++ b/src/logoItem.cpp @@ -18,14 +18,14 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QGraphicsScene> -#include <QPainter> -#include <QApplication> -#include <QTimer> - #include "logoItem.h" + #include "petrack.h" +#include <QApplication> +#include <QGraphicsScene> +#include <QPainter> +#include <QTimer> #include <ctime> // minimale Zeit zwischen zwei Blendenstufen in Millisekunden @@ -36,15 +36,15 @@ Fader::Fader() mTimer = nullptr; } -void Fader::fadeOut(LogoItem* lI, int frames) +void Fader::fadeOut(LogoItem *lI, int frames) { mLogoItem = lI; - if (frames < 1) + if(frames < 1) mFrames = 1; else mFrames = frames; - mStep = 1./mFrames; - if (mTimer) // wenn fadeOut schon mal aufgerufen wurde; so wird nur ein QTimer maximal angelegt + mStep = 1. / mFrames; + if(mTimer) // wenn fadeOut schon mal aufgerufen wurde; so wird nur ein QTimer maximal angelegt delete mTimer; mTimer = new QTimer(this); connect(mTimer, SIGNAL(timeout()), this, SLOT(fadeOutStep())); @@ -55,13 +55,14 @@ void Fader::fadeOutStep() { static clock_t lastTime = clock(); - if (((double)(clock()-lastTime))/CLOCKS_PER_SEC > FRAME_INTERVAL*.001) // beschleunigen, wenn zu langsam ausgeblendet wird - mStep*=2; + if(((double) (clock() - lastTime)) / CLOCKS_PER_SEC > + FRAME_INTERVAL * .001) // beschleunigen, wenn zu langsam ausgeblendet wird + mStep *= 2; lastTime = clock(); - if (mLogoItem->getOpacity()>0.) + if(mLogoItem->getOpacity() > 0.) { - mLogoItem->setOpacity(mLogoItem->getOpacity()-mStep); + mLogoItem->setOpacity(mLogoItem->getOpacity() - mStep); mLogoItem->scene()->update(); // ein neuzeichnen wird erwuenscht und irgendwann bei processEvents gemacht qApp->processEvents(); } @@ -72,13 +73,11 @@ void Fader::fadeOutStep() } } -LogoItem::LogoItem(QWidget *wParent, QGraphicsItem * parent) - : QGraphicsItem(parent) +LogoItem::LogoItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) { - mOpacity = 1.0; - mMainWindow = (class Petrack*) wParent; - mImage = new QImage(":/logo"); // in icons.qrc definiert - + mOpacity = 1.0; + mMainWindow = (class Petrack *) wParent; + mImage = new QImage(":/logo"); // in icons.qrc definiert } QRectF LogoItem::boundingRect() const @@ -90,18 +89,18 @@ void LogoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio { int w; int h; - if (mMainWindow->getImage()) + if(mMainWindow->getImage()) { - w = (mMainWindow->getImage()->width())/2 - (mImage->width())/2 - mMainWindow->getImageBorderSize(); - h = (mMainWindow->getImage()->height())/2 - (mImage->height())/2 - mMainWindow->getImageBorderSize(); + w = (mMainWindow->getImage()->width()) / 2 - (mImage->width()) / 2 - mMainWindow->getImageBorderSize(); + h = (mMainWindow->getImage()->height()) / 2 - (mImage->height()) / 2 - mMainWindow->getImageBorderSize(); } else { - w = 0; + w = 0; h = 0; } painter->setOpacity(mOpacity); - painter->drawImage(w,h,*mImage); + painter->drawImage(w, h, *mImage); } // logo wird langsam ausgeblendet diff --git a/src/main.cpp b/src/main.cpp index caea62af096907ae25f4fd09cd4de5c79dd6bfe9..fa9f87c8b2d392aea5507b007fb1af9ff5c7bdea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,27 +18,27 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include "IO.h" +#include "compilerInformation.h" +#include "helper.h" +#include "petrack.h" +#include "tracker.h" + #include <QApplication> -#include <QtWidgets> #include <QMessageBox> #include <QStyleFactory> +#include <QtWidgets> #include <csignal> #include <cstdio> #include <sstream> #include <string> -#include "petrack.h" -#include "helper.h" -#include "tracker.h" -#include "IO.h" -#include "compilerInformation.h" - // Aufrufbeispiel: // release/petrack.exe -sequence ../../einzelbilder/wert0001.png -autoSave dir|ttt.avi -static QApplication * gApp = nullptr; -void quit(int sig_number) +static QApplication *gApp = nullptr; +void quit(int sig_number) { gApp->quit(); return; @@ -46,18 +46,18 @@ void quit(int sig_number) int main(int argc, char *argv[]) { - Q_INIT_RESOURCE(icons); QApplication app(argc, argv); -// Reihenfolge beim Beenden von Petrack (signal abouttoquit() von qapplication nicht hinbekommen): -// - petrack:closeevent() -// - app.exec() am ende dieser Programmzeilen wird beendet -// - Funktion, die mit qAddPostRoutine an Qt uebergeben wird -// - SIGTERM kann nicht von QT abgefangen werden, sondern muss mit signal behandelt werden + // Reihenfolge beim Beenden von Petrack (signal abouttoquit() von qapplication nicht hinbekommen): + // - petrack:closeevent() + // - app.exec() am ende dieser Programmzeilen wird beendet + // - Funktion, die mit qAddPostRoutine an Qt uebergeben wird + // - SIGTERM kann nicht von QT abgefangen werden, sondern muss mit signal behandelt werden gApp = &app; - signal(SIGINT, quit); // used to catch ctrl-C and get rid of error "QObject::killTimers: timers cannot be stopped from another thread" + signal(SIGINT, quit); // used to catch ctrl-C and get rid of error "QObject::killTimers: timers cannot be stopped + // from another thread" app.setStyle(QStyleFactory::create("Fusion")); // added for Qt5 @@ -66,25 +66,25 @@ int main(int argc, char *argv[]) // -sequence *.png: um animation zu laden (ueberschreibt projekt) // -autoSave file oder ordner: um automatisches herausschreiben von sequenz in ordner zu machen QStringList arg = app.arguments(); - QString sequence; - QString project; - QString autoSaveDest; - bool autoSave = false; - QString autoTrackDest; - QString autoPlayDest; - bool autoTrack = false; - bool autoPlay = false; + QString sequence; + QString project; + QString autoSaveDest; + bool autoSave = false; + QString autoTrackDest; + QString autoPlayDest; + bool autoTrack = false; + bool autoPlay = false; QString autoReadHeightFile; - bool autoReadHeight = false; + bool autoReadHeight = false; QString autoReadMarkerFile; - bool autoReadMarkerID = false; + bool autoReadMarkerID = false; QString autoSaveTrackerFile; - bool autoSaveTracker = false; + bool autoSaveTracker = false; - for (int i = 1; i < arg.size(); ++i) // i=0 ist Programmname + for(int i = 1; i < arg.size(); ++i) // i=0 ist Programmname { - if (arg.at(i) == "-help" || arg.at(i) == "-?") + if(arg.at(i) == "-help" || arg.at(i) == "-?") { QTextDocument doc; doc.setHtml(commandLineOptionsString); @@ -92,52 +92,54 @@ int main(int argc, char *argv[]) QMessageBox::about(nullptr, QObject::tr("Command line options"), commandLineOptionsString); return 0; // 0 means exit success // 1? } - else if (arg.at(i) == "-project") + else if(arg.at(i) == "-project") project = arg.at(++i); - else if (arg.at(i) == "-sequence") + else if(arg.at(i) == "-sequence") sequence = arg.at(++i); - else if ((arg.at(i) == "-autoSave") || (arg.at(i) == "-autosave")) + else if((arg.at(i) == "-autoSave") || (arg.at(i) == "-autosave")) { - autoSave = true; + autoSave = true; autoSaveDest = arg.at(++i); } - else if ((arg.at(i) == "-autoTrack") || (arg.at(i) == "-autotrack")) + else if((arg.at(i) == "-autoTrack") || (arg.at(i) == "-autotrack")) { autoTrack = true; // hat tracker_file bestimmte Dateiendung txt oder trc, dann wird nur genau diese exportiert, sonst beide autoTrackDest = arg.at(++i); } - else if ((arg.at(i) == "-autoPlay") || (arg.at(i) == "-autoplay")) - { // nur abspielen und keine aenderungen an control track and reco, um zB groessenbestimmung nachtraeglich vorzunehmen, nachdem haendisch kontrolliert + else if((arg.at(i) == "-autoPlay") || (arg.at(i) == "-autoplay")) + { // nur abspielen und keine aenderungen an control track and reco, um zB groessenbestimmung nachtraeglich + // vorzunehmen, nachdem haendisch kontrolliert autoPlay = true; // hat tracker_file bestimmte Dateiendung txt oder trc, dann wird nur genau diese exportiert, sonst beide autoPlayDest = arg.at(++i); } - else if (arg.at(i).right(4) == ".pet") + else if(arg.at(i).right(4) == ".pet") { // -project option ueberschreibt *.pet uebergabe ohne option!! - if (project.isEmpty()) + if(project.isEmpty()) project = arg.at(i); } - else if ((arg.at(i) == "-autoReadMarkerID") || (arg.at(i) == "-autoreadmarkerid")) + else if((arg.at(i) == "-autoReadMarkerID") || (arg.at(i) == "-autoreadmarkerid")) { - // -autoreadmarkerid followed by txt-file including personIDs and markerIDs - // reads the txt-file and applies the markerIds to persons with corresponding personIDs - autoReadMarkerID = true; - autoReadMarkerFile = arg.at(++i); + // -autoreadmarkerid followed by txt-file including personIDs and markerIDs + // reads the txt-file and applies the markerIds to persons with corresponding personIDs + autoReadMarkerID = true; + autoReadMarkerFile = arg.at(++i); } - else if ((arg.at(i) == "-autoReadHeight") || (arg.at(i) == "-autoreadheight")) + else if((arg.at(i) == "-autoReadHeight") || (arg.at(i) == "-autoreadheight")) { // -autoreadheight followed by txt-file including markerIDs and individual heights // reads the txt-file and applies the heights to persons with corresponding markerIDs - autoReadHeight = true; + autoReadHeight = true; autoReadHeightFile = arg.at(++i); } - else if ((arg.at(i) == "-autoSaveTracker") || (arg.at(i) == "-autosavetracker")) + else if((arg.at(i) == "-autoSaveTracker") || (arg.at(i) == "-autosavetracker")) { - // -autoSaveTracker followed by Trackerfile which can either have the ending *.txt or *.trc. If no ending is given, both files will be created - autoSaveTracker = true; - autoSaveTrackerFile = arg.at(++i); + // -autoSaveTracker followed by Trackerfile which can either have the ending *.txt or *.trc. If no ending is + // given, both files will be created + autoSaveTracker = true; + autoSaveTrackerFile = arg.at(++i); } else { @@ -163,53 +165,55 @@ int main(int argc, char *argv[]) petrack.show(); // damit bei reiner Hilfe nicht angezeigt wird, erst hier der aufruf // erst nachher ausfuehren, damit reihenfolge der command line argumente keine rolle spielt - if (!project.isEmpty()) + if(!project.isEmpty()) { - if (sequence.isEmpty()) + if(sequence.isEmpty()) petrack.openProject(project); else petrack.openProject(project, false); } - if (!sequence.isEmpty()) // nach project so dass dies datei in project ueberschreibt + if(!sequence.isEmpty()) // nach project so dass dies datei in project ueberschreibt petrack.openSequence(sequence); - if (autoSave && (autoSaveDest.right(4) != ".pet")) + if(autoSave && (autoSaveDest.right(4) != ".pet")) { - if ((autoSaveDest.right(4) == ".txt")||(autoSaveDest.right(5) == ".trav")||(autoSaveDest.right(4) == ".dat")) - petrack.exportTracker(autoSaveDest); // projekt wird geladen und nur Trajektoprien herausgeschrieben (zB wenn sich .pet (altitude) oder .trc aendert (delrec)) + if((autoSaveDest.right(4) == ".txt") || (autoSaveDest.right(5) == ".trav") || (autoSaveDest.right(4) == ".dat")) + petrack.exportTracker(autoSaveDest); // projekt wird geladen und nur Trajektoprien herausgeschrieben (zB + // wenn sich .pet (altitude) oder .trc aendert (delrec)) else - petrack.saveSequence(true, false, autoSaveDest); // true spielt keine rolle, sondern wird durch dateiendung bestimmt - return EXIT_SUCCESS; // 0 means exit success// Programm beenden nach speichern! // 1? + petrack.saveSequence( + true, false, autoSaveDest); // true spielt keine rolle, sondern wird durch dateiendung bestimmt + return EXIT_SUCCESS; // 0 means exit success// Programm beenden nach speichern! // 1? } // hat tracker_file bestimmte Dateiendung txt oder trc, dann wird nur genau diese exportiert, sonst beide - if (autoTrack) + if(autoTrack) { petrack.trackAll(); - if (autoReadMarkerID) + if(autoReadMarkerID) { auto markerIDs = IO::readMarkerIDFile(autoReadMarkerFile); - if (std::holds_alternative<std::unordered_map<int, int>>(markerIDs)) // heights contains the height map + if(std::holds_alternative<std::unordered_map<int, int>>(markerIDs)) // heights contains the height map { petrack.getTracker()->setMarkerIDs(std::get<std::unordered_map<int, int>>(markerIDs)); petrack.setMarkerIDFileName(autoReadHeightFile); } - else //markerIDs contains an error string + else // markerIDs contains an error string { - debout << "Error: " << std::get<std::string>(markerIDs) << "\n"; - return EXIT_FAILURE; + debout << "Error: " << std::get<std::string>(markerIDs) << "\n"; + return EXIT_FAILURE; } } - if (autoReadHeight) + if(autoReadHeight) { auto markerHeights = IO::readHeightFile(autoReadHeightFile); - if (std::holds_alternative<std::unordered_map<int, float>>(markerHeights)) // heights contains the height map + if(std::holds_alternative<std::unordered_map<int, float>>(markerHeights)) // heights contains the height map { petrack.getTracker()->resetHeight(); petrack.getTracker()->setMarkerHeights(std::get<std::unordered_map<int, float>>(markerHeights)); petrack.setHeightFileName(autoReadHeightFile); } - else //markerHeights contains an error string + else // markerHeights contains an error string { debout << "Error: " << std::get<std::string>(markerHeights) << "\n"; return EXIT_FAILURE; @@ -217,61 +221,61 @@ int main(int argc, char *argv[]) } petrack.exportTracker(autoTrackDest); - if (autoSave && (autoSaveDest.right(4) == ".pet")) + if(autoSave && (autoSaveDest.right(4) == ".pet")) { petrack.saveProject(autoSaveDest); } - return EXIT_SUCCESS; // Programm beenden nach speichern! // 1? + return EXIT_SUCCESS; // Programm beenden nach speichern! // 1? } - if (autoPlay) + if(autoPlay) { petrack.playAll(); petrack.exportTracker(autoPlayDest); - if (autoSave && (autoSaveDest.right(4) == ".pet")) + if(autoSave && (autoSaveDest.right(4) == ".pet")) { petrack.saveProject(autoSaveDest); } - return EXIT_SUCCESS; // Programm beenden nach speichern! // 1? + return EXIT_SUCCESS; // Programm beenden nach speichern! // 1? } - if (!autoTrack && autoReadMarkerID) // TODO autoTrack is always false here, as otherwise already returned + if(!autoTrack && autoReadMarkerID) // TODO autoTrack is always false here, as otherwise already returned { auto markerIDs = IO::readMarkerIDFile(autoReadMarkerFile); - if (std::holds_alternative<std::unordered_map<int, int>>(markerIDs)) // heights contains the height map + if(std::holds_alternative<std::unordered_map<int, int>>(markerIDs)) // heights contains the height map { petrack.getTracker()->setMarkerIDs(std::get<std::unordered_map<int, int>>(markerIDs)); petrack.setMarkerIDFileName(autoReadHeightFile); } - else //heights contains an error string + else // heights contains an error string { debout << "Error: " << std::get<std::string>(markerIDs) << "\n"; return EXIT_FAILURE; } } - if (!autoTrack && autoReadHeight) // TODO autoTrack is always false here, as otherwise already returned + if(!autoTrack && autoReadHeight) // TODO autoTrack is always false here, as otherwise already returned { auto markerHeights = IO::readHeightFile(autoReadHeightFile); - if (std::holds_alternative<std::unordered_map<int, float>>(markerHeights)) // heights contains the height map + if(std::holds_alternative<std::unordered_map<int, float>>(markerHeights)) // heights contains the height map { petrack.getTracker()->resetHeight(); petrack.getTracker()->setMarkerHeights(std::get<std::unordered_map<int, float>>(markerHeights)); petrack.setHeightFileName(autoReadHeightFile); } - else //heights contains an error string + else // heights contains an error string { debout << "Error: " << std::get<std::string>(markerHeights) << "\n"; return EXIT_FAILURE; } } - if (autoSaveTracker) + if(autoSaveTracker) { petrack.exportTracker(autoSaveTrackerFile); } - if (autoSave && (autoSaveDest.right(4) == ".pet")) + if(autoSave && (autoSaveDest.right(4) == ".pet")) { petrack.saveProject(autoSaveDest); return EXIT_SUCCESS; diff --git a/src/markerCasern.cpp b/src/markerCasern.cpp index 91fd19b9015aafc84d7f2a421f1ddad5a71d486e..2c7fe9f1086b60d350f71f7ff530ec19c5e2d7ab 100644 --- a/src/markerCasern.cpp +++ b/src/markerCasern.cpp @@ -18,7 +18,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -//folgende zeile spaeter raus +// folgende zeile spaeter raus #include <opencv2/highgui.hpp> // fuer Aussentreppen, sehr gross, oben @@ -33,96 +33,87 @@ #define SPOT_SIZE_MIN 1 #define SPOT_SIZE_MAX 9 -#include "markerCasern.h" #include "helper.h" +#include "markerCasern.h" #include "tracker.h" -// bei marker koennnte sich fuer jeden spot eine liste gemerkt werden und spaeter ausgleich +// bei marker koennnte sich fuer jeden spot eine liste gemerkt werden und spaeter ausgleich // regressionsgrade legen um optimale linie durch marker zu erhalten -MarkerCasern::MarkerCasern(MyEllipse head) - : mHead(head), - mHasHead(true), - mHasQuadrangle(false), - mCenterIndex(-1), - mColorIndex(-1) -{ -} -MarkerCasern::MarkerCasern() - : mHasHead(false), - mCenterIndex(-1), - mColorIndex(-1) - +MarkerCasern::MarkerCasern(MyEllipse head) : + mHead(head), mHasHead(true), mHasQuadrangle(false), mCenterIndex(-1), mColorIndex(-1) { } +MarkerCasern::MarkerCasern() : mHasHead(false), mCenterIndex(-1), mColorIndex(-1) {} // muesste alles automatisch durch den defaultdestructor gemacht werden! MarkerCasern::~MarkerCasern() { mSpots.clear(); mSpotCount.clear(); } - + // 3 inline functions to get access to class member varaibales only in .h file -bool MarkerCasern::isOverlappingHead(const MyEllipse& e) const +bool MarkerCasern::isOverlappingHead(const MyEllipse &e) const { - if (hasHead()) + if(hasHead()) return mHead.isInside(e.center()) || e.isInside(mHead.center()); else return false; } -bool MarkerCasern::isInsideHead(const Vec2F& p) const +bool MarkerCasern::isInsideHead(const Vec2F &p) const { - if (hasHead()) + if(hasHead()) return mHead.isInside(p); else return false; } // returns spot number in spots list when inside, otherwise returns -1 -int MarkerCasern::isOverlappingSpots(const MyEllipse& e) const +int MarkerCasern::isOverlappingSpots(const MyEllipse &e) const { - for (int i = 0; i < mSpots.size(); ++i) - if ((mSpots[i].isInside(e.center()) || e.isInside(mSpots[i].center())) && // Mittelpkte liegen ineinander - ((e.center()-mSpots[i].center()).length() < 2)) // kein zu grosser Abstand + for(int i = 0; i < mSpots.size(); ++i) + if((mSpots[i].isInside(e.center()) || e.isInside(mSpots[i].center())) && // Mittelpkte liegen ineinander + ((e.center() - mSpots[i].center()).length() < 2)) // kein zu grosser Abstand return i; return -1; } -int MarkerCasern::isInsideSpots(const Vec2F& p) const +int MarkerCasern::isInsideSpots(const Vec2F &p) const { - for (int i = 0; i < mSpots.size(); ++i) - if (mSpots[i].isInside(p)) + for(int i = 0; i < mSpots.size(); ++i) + if(mSpots[i].isInside(p)) return i; return -1; } void MarkerCasern::modifyHead(const MyEllipse &head) { - // man koennte auch spots und heads sammeln und am ende eine ueberpruefung vornehmen!!!!!! + // man koennte auch spots und heads sammeln und am ende eine ueberpruefung vornehmen!!!!!! // median , regressionsgrade // man koennte auch pruefen: // - ob ellips-mittelpkt besser auf linie von markern liegt // - ob die outline eine bestimmte groesse besitzt - if (hasHead()) + if(hasHead()) { - if (mHead.outline()>260 && mHead.outline()<340) // bevorzugte groesse - nur initial koennte andere erzeugt werden - if (fabs(mHead.ratio()-1.5)>fabs(head.ratio()-1.5)) // because white plate is 14x21cm + if(mHead.outline() > 260 && + mHead.outline() < 340) // bevorzugte groesse - nur initial koennte andere erzeugt werden + if(fabs(mHead.ratio() - 1.5) > fabs(head.ratio() - 1.5)) // because white plate is 14x21cm mHead = head; } else { mHasHead = true; - mHead = head; + mHead = head; } } void MarkerCasern::modifySpot(int i, const MyEllipse &spot) { - if (i < mSpots.size()) + if(i < mSpots.size()) { // man koennte auch pruefen: // - ob abstand zur mittellinie geringer // - ob form eher kreisfoermig - if (spot.outline() > mSpots[i].outline()) + if(spot.outline() > mSpots[i].outline()) mSpots[i] = spot; ++mSpotCount[i]; } @@ -140,23 +131,23 @@ void MarkerCasern::deleteSpot(int i) void MarkerCasern::modifyQuadrangle(const Vec2F v[4]) { - if (mHasQuadrangle) + if(mHasQuadrangle) { // seitenverhaeltnis 2:3 koennte auch bedacht werden // angle on opposed edge is nearer to 90 - if ((fabs((v[3]-v[2]).angleBetweenVec(v[0]-v[3])-PI/2.)+ - fabs((v[1]-v[0]).angleBetweenVec(v[2]-v[1])-PI/2.)) < - (fabs((mQuadrangle[3]-mQuadrangle[2]).angleBetweenVec(mQuadrangle[0]-mQuadrangle[3])-PI/2.)+ - fabs((mQuadrangle[1]-mQuadrangle[0]).angleBetweenVec(mQuadrangle[2]-mQuadrangle[1])-PI/2.))) + if((fabs((v[3] - v[2]).angleBetweenVec(v[0] - v[3]) - PI / 2.) + + fabs((v[1] - v[0]).angleBetweenVec(v[2] - v[1]) - PI / 2.)) < + (fabs((mQuadrangle[3] - mQuadrangle[2]).angleBetweenVec(mQuadrangle[0] - mQuadrangle[3]) - PI / 2.) + + fabs((mQuadrangle[1] - mQuadrangle[0]).angleBetweenVec(mQuadrangle[2] - mQuadrangle[1]) - PI / 2.))) { - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) mQuadrangle[i] = v[i]; } } else { mHasQuadrangle = true; - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) mQuadrangle[i] = v[i]; } } @@ -168,19 +159,20 @@ void MarkerCasern::organize(const cv::Mat &img, bool autoWB) int i, j, k; // direkt herausspringen, da nichts zu tun ist - if (mSpots.size() == 0) + if(mSpots.size() == 0) return; // durch mgl wachsen der spots muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen ergeben - for (i = 0; i < mSpots.size(); ++i) - for (j = i+1; j < mSpots.size(); ++j) - if (mSpots[i].isInside(mSpots[j].center()) || mSpots[j].isInside(mSpots[i].center())) + for(i = 0; i < mSpots.size(); ++i) + for(j = i + 1; j < mSpots.size(); ++j) + if(mSpots[i].isInside(mSpots[j].center()) || mSpots[j].isInside(mSpots[i].center())) { modifySpot(i, mSpots[j]); deleteSpot(j); - j=i; // es muss von vorne begonnen werden, da i wachsen koennte und dann vorgaenger von j nun hineinpassen koennten // --j; + j = i; // es muss von vorne begonnen werden, da i wachsen koennte und dann vorgaenger von j nun + // hineinpassen koennten // --j; } - + // nach groesse sortieren und loeschen koennte kreus angreifen zugunsten von zahl // gucken, ob in ellipse wirklich zB bullet drin ist @@ -188,45 +180,46 @@ void MarkerCasern::organize(const cv::Mat &img, bool autoWB) // spots loeschen, die selten erkannt wurden // mind 5 stehen lassen (marker und zahlen - auch von der seite zu sehen) int count = 100, anz = 0; - while (count > 4) + while(count > 4) { ++anz; count = 0; - for (i = 0; i < mSpotCount.size(); ++i) - if (mSpotCount[i] > anz) + for(i = 0; i < mSpotCount.size(); ++i) + if(mSpotCount[i] > anz) count++; } - for (i = 0; i < mSpotCount.size(); ++i) - if (mSpotCount[i] < anz) + for(i = 0; i < mSpotCount.size(); ++i) + if(mSpotCount[i] < anz) { deleteSpot(i); --i; } - // 4 spots heraussuchen, bei denen um center in quadrat. bereich in ellipse der dunkelste Pkt (kleiner value in hsv) gefunden wird - // 4 uebrig lassen, weil entweder nummer an kopfseite sehr dunkel sein kann, wenn zu sehen oder in sehr hellen bereichen kreuz wegfallen wuerde - // da aber immer die 3 marker von mittellinie drin bleiben kann bei suche solch einer linie nur diese entstehen, - // da beide nummern nicht mehr drin sind + // 4 spots heraussuchen, bei denen um center in quadrat. bereich in ellipse der dunkelste Pkt (kleiner value in hsv) + // gefunden wird 4 uebrig lassen, weil entweder nummer an kopfseite sehr dunkel sein kann, wenn zu sehen oder in + // sehr hellen bereichen kreuz wegfallen wuerde da aber immer die 3 marker von mittellinie drin bleiben kann bei + // suche solch einer linie nur diese entstehen, da beide nummern nicht mehr drin sind QColor col; - int cx, cy; - if (mSpots.size() > 4) + int cx, cy; + if(mSpots.size() > 4) { - int r; + int r; QList<int> minValList; - for (i = 0; i < mSpots.size(); ++i) + for(i = 0; i < mSpots.size(); ++i) { cx = myRound(mSpots[i].x()); cy = myRound(mSpots[i].y()); - r = myRound((mSpots[i].r1()+mSpots[i].r2())/2.); // mittlerer radius + r = myRound((mSpots[i].r1() + mSpots[i].r2()) / 2.); // mittlerer radius int minVal = 256; // groesser als komplett weiss (255) // bildrand muss nicht ueberprueft werden, da sie gar nicht erst hereingekommen waeren - for (j = -r; j < r+1; ++j) - for (k = -r; k < r+1; ++k) + for(j = -r; j < r + 1; ++j) + for(k = -r; k < r + 1; ++k) { - col.setRgb(getValue(img,cx+j,cy+k).rgb());//getR(img, cx+j, cy+k), getG(img, cx+j, cy+k), getB(img, cx+j, cy+k)); - if (col.value() < minVal) + col.setRgb(getValue(img, cx + j, cy + k) + .rgb()); // getR(img, cx+j, cy+k), getG(img, cx+j, cy+k), getB(img, cx+j, cy+k)); + if(col.value() < minVal) minVal = col.value(); // Helligkeit } minValList.append(minVal); @@ -234,8 +227,8 @@ void MarkerCasern::organize(const cv::Mat &img, bool autoWB) // loeschen aller zu hellen spots QList<int> minValListSort = minValList; std::sort(minValListSort.begin(), minValListSort.end()); // sortiert aufsteigend - for (i = 0; i < mSpots.size(); ++i) - if (minValList[i] > minValListSort[3]) + for(i = 0; i < mSpots.size(); ++i) + if(minValList[i] > minValListSort[3]) { deleteSpot(i); minValList.removeAt(i); @@ -252,71 +245,80 @@ void MarkerCasern::organize(const cv::Mat &img, bool autoWB) // die am nahesten auf Linie liegenden spots heraussuchen // cross marker spot index setzen // mCenterIndex = -1; wird im constructor gemacht - int centerIndex = -1, lineIndex[3] = {-1, -1, -1}; - double difAbs = 1000, tmp2Abs = 0, tmpAbs = 0, minAbs = 1000; //tmpAbs = 0, tmp2Abs = 0 damit keine warnung - double o1, o2, o3, minOutline = 12; - bool found = false; - for (i = 0; i < mSpots.size(); ++i) - for (j = i+1; j < mSpots.size(); ++j) - for (k = j+1; k < mSpots.size(); ++k) + int centerIndex = -1, lineIndex[3] = {-1, -1, -1}; + double difAbs = 1000, tmp2Abs = 0, tmpAbs = 0, minAbs = 1000; // tmpAbs = 0, tmp2Abs = 0 damit keine warnung + double o1, o2, o3, minOutline = 12; + bool found = false; + for(i = 0; i < mSpots.size(); ++i) + for(j = i + 1; j < mSpots.size(); ++j) + for(k = j + 1; k < mSpots.size(); ++k) { o1 = mSpots[i].outline(); o2 = mSpots[j].outline(); o3 = mSpots[k].outline(); - if (((o1 > minOutline && o2 > minOutline) || (o1 > minOutline && o3 > minOutline) || (o2 > minOutline && o3 > minOutline)) && // mind 2 groesser - ((tmpAbs = mSpots[i].center().distanceToLine(mSpots[j].center(), mSpots[k].center())) < minAbs) && - (tmpAbs < 2)) // abstand und damit fehler sollte nicht groesser als 2 sein, sonst maker loeschen + if(((o1 > minOutline && o2 > minOutline) || (o1 > minOutline && o3 > minOutline) || + (o2 > minOutline && o3 > minOutline)) && // mind 2 groesser + ((tmpAbs = mSpots[i].center().distanceToLine(mSpots[j].center(), mSpots[k].center())) < minAbs) && + (tmpAbs < 2)) // abstand und damit fehler sollte nicht groesser als 2 sein, sonst maker loeschen { // mittigen spot heraussuchen - if (((tmp2Abs=(0.5*(mSpots[i].center()+mSpots[j].center())-mSpots[k].center()).length()) < 2) && - (tmp2Abs < difAbs) && - ((mSpots[i].center()-mSpots[j].center()).length() > 13) && // damit nicht farbmarker alleine alle 3 marker - (o1 > minOutline && o2 > minOutline)) + if(((tmp2Abs = (0.5 * (mSpots[i].center() + mSpots[j].center()) - mSpots[k].center()).length()) < + 2) && + (tmp2Abs < difAbs) && + ((mSpots[i].center() - mSpots[j].center()).length() > + 13) && // damit nicht farbmarker alleine alle 3 marker + (o1 > minOutline && o2 > minOutline)) { - difAbs = tmp2Abs; + difAbs = tmp2Abs; centerIndex = 2; - found = true; + found = true; } - if (((tmp2Abs=(0.5*(mSpots[j].center()+mSpots[k].center())-mSpots[i].center()).length()) < 2) && - (tmp2Abs < difAbs) && - ((mSpots[j].center()-mSpots[k].center()).length() > 13) && // damit nicht farbmarker alleine alle 3 marker - (o2 > minOutline && o3 > minOutline)) + if(((tmp2Abs = (0.5 * (mSpots[j].center() + mSpots[k].center()) - mSpots[i].center()).length()) < + 2) && + (tmp2Abs < difAbs) && + ((mSpots[j].center() - mSpots[k].center()).length() > + 13) && // damit nicht farbmarker alleine alle 3 marker + (o2 > minOutline && o3 > minOutline)) { - difAbs = tmp2Abs; + difAbs = tmp2Abs; centerIndex = 0; - found = true; + found = true; } - if (((tmp2Abs=(0.5*(mSpots[k].center()+mSpots[i].center())-mSpots[j].center()).length()) < 2) && - (tmp2Abs < difAbs) && - ((mSpots[i].center()-mSpots[k].center()).length() > 13) && // damit nicht farbmarker alleine alle 3 marker - (o1 > minOutline && o3 > minOutline)) + if(((tmp2Abs = (0.5 * (mSpots[k].center() + mSpots[i].center()) - mSpots[j].center()).length()) < + 2) && + (tmp2Abs < difAbs) && + ((mSpots[i].center() - mSpots[k].center()).length() > + 13) && // damit nicht farbmarker alleine alle 3 marker + (o1 > minOutline && o3 > minOutline)) { - difAbs = tmp2Abs; + difAbs = tmp2Abs; centerIndex = 1; - found = true; + found = true; } // wenn mittiger spot nicht mittig, dann keine gueltige marke - if (found) // ueberhaupt eine Mitte gefunden + if(found) // ueberhaupt eine Mitte gefunden { - found = false; + found = false; lineIndex[0] = i; lineIndex[1] = j; lineIndex[2] = k; - minAbs = tmpAbs; + minAbs = tmpAbs; } } } // delete spots not laing on the line - for (i = 0; i < mSpots.size(); ++i) + for(i = 0; i < mSpots.size(); ++i) { - if (i != lineIndex[0] && i != lineIndex[1] && i != lineIndex[2]) + if(i != lineIndex[0] && i != lineIndex[1] && i != lineIndex[2]) { deleteSpot(i); --i; - --lineIndex[0]; --lineIndex[1]; --lineIndex[2]; + --lineIndex[0]; + --lineIndex[1]; + --lineIndex[2]; } // set index for cross marker - else if ((centerIndex > -1) && (i == lineIndex[centerIndex])) + else if((centerIndex > -1) && (i == lineIndex[centerIndex])) { mCenterIndex = lineIndex[centerIndex]; } @@ -324,48 +326,50 @@ void MarkerCasern::organize(const cv::Mat &img, bool autoWB) // ab hier nur noch 0 oder 3 spots!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // bei 0 muss keine farbe mehr bestimmt werden - if (mSpots.size() == 0) + if(mSpots.size() == 0) return; - // farbe bestimmen (richtiger marker koennte auch durch form oder dem abstand des hellsten pkt in groesserer umgebung vom mittelpkt bestimmt werden) - bool colSet = false; + // farbe bestimmen (richtiger marker koennte auch durch form oder dem abstand des hellsten pkt in groesserer + // umgebung vom mittelpkt bestimmt werden) + bool colSet = false; QColor colOther; // farbe des anderen spots - for (i = 0; i < mSpots.size(); ++i) - if (i != mCenterIndex) + for(i = 0; i < mSpots.size(); ++i) + if(i != mCenterIndex) { cx = myRound(mSpots[i].x()); cy = myRound(mSpots[i].y()); - if (!colSet) + if(!colSet) { colSet = true; - mCol.setRgb(getValue(img,cx,cy).rgb()); + mCol.setRgb(getValue(img, cx, cy).rgb()); mColorIndex = i; } else { - colOther.setRgb(getValue(img,cx,cy).rgb()); + colOther.setRgb(getValue(img, cx, cy).rgb()); mOtherIndex = i; } // bildrand muss nicht ueberprueft werden, da sie gar nicht erst hereingekommen waeren - for (j = -1; j < 2; ++j) // 3x3 feld wird ueberprueft - for (k = -1; k < 2; ++k) + for(j = -1; j < 2; ++j) // 3x3 feld wird ueberprueft + for(k = -1; k < 2; ++k) { - col.setRgb(getValue(img,cx+j,cy+k).rgb()); - // faktor, um die mitte hoeher zu gewichten, da bei fd der schwarze rand mit dem weiss gemischt oft hell ist - if (col.value()/(1. + .5*(abs(j)+abs(k))) > mCol.value()) // wenn Helligkeit maximal + col.setRgb(getValue(img, cx + j, cy + k).rgb()); + // faktor, um die mitte hoeher zu gewichten, da bei fd der schwarze rand mit dem weiss gemischt oft + // hell ist + if(col.value() / (1. + .5 * (abs(j) + abs(k))) > mCol.value()) // wenn Helligkeit maximal { - if (i != mColorIndex) + if(i != mColorIndex) { - colOther = mCol; + colOther = mCol; mOtherIndex = mColorIndex; } - mCol = col; + mCol = col; mColorIndex = i; } } } - if (autoWB) + if(autoWB) { // weissabgleich // 1. Dynamik der Helligkeit @@ -374,45 +378,53 @@ void MarkerCasern::organize(const cv::Mat &img, bool autoWB) // weisswert und durchschnittlichen weisswert bestimmen // 2 bereiche neben farbmarker in weisser flaeche auf kopfpappe - int wcx = myRound(mSpots[mColorIndex].x()+0.356*(mSpots[mColorIndex].y()-mSpots[mOtherIndex].y())); - int wcy = myRound(mSpots[mColorIndex].y()+0.356*(mSpots[mColorIndex].x()-mSpots[mOtherIndex].x())); - QColor white(0,0,0); // hellster fleck + int wcx = myRound(mSpots[mColorIndex].x() + 0.356 * (mSpots[mColorIndex].y() - mSpots[mOtherIndex].y())); + int wcy = myRound(mSpots[mColorIndex].y() + 0.356 * (mSpots[mColorIndex].x() - mSpots[mOtherIndex].x())); + QColor white(0, 0, 0); // hellster fleck - int avgWhiteR=0, avgWhiteG=0, avgWhiteB=0; // durchschnittlichen weisswert - for (j = -1; j < 2; ++j) // 3x3 feld um ocx,ocy wird ueberprueft - for (k = -1; k < 2; ++k) + int avgWhiteR = 0, avgWhiteG = 0, avgWhiteB = 0; // durchschnittlichen weisswert + for(j = -1; j < 2; ++j) // 3x3 feld um ocx,ocy wird ueberprueft + for(k = -1; k < 2; ++k) { - QColor color = getValue(img,wcx+j,wcy+k); - avgWhiteR+=color.red(); - avgWhiteG+=color.green(); - avgWhiteB+=color.blue(); - col.setRgb(getValue(img,wcx+j,wcy+k).rgb()); - if (col.value() > white.value()) // wenn Helligkeit groesser + QColor color = getValue(img, wcx + j, wcy + k); + avgWhiteR += color.red(); + avgWhiteG += color.green(); + avgWhiteB += color.blue(); + col.setRgb(getValue(img, wcx + j, wcy + k).rgb()); + if(col.value() > white.value()) // wenn Helligkeit groesser white = col; } - wcx = myRound(mSpots[mColorIndex].x()-0.356*(mSpots[mColorIndex].y()-mSpots[mOtherIndex].y())); - wcy = myRound(mSpots[mColorIndex].y()-0.356*(mSpots[mColorIndex].x()-mSpots[mOtherIndex].x())); - for (j = -1; j < 2; ++j) // 3x3 feld um ocx,ocy wird ueberprueft - for (k = -1; k < 2; ++k) + wcx = myRound(mSpots[mColorIndex].x() - 0.356 * (mSpots[mColorIndex].y() - mSpots[mOtherIndex].y())); + wcy = myRound(mSpots[mColorIndex].y() - 0.356 * (mSpots[mColorIndex].x() - mSpots[mOtherIndex].x())); + for(j = -1; j < 2; ++j) // 3x3 feld um ocx,ocy wird ueberprueft + for(k = -1; k < 2; ++k) { - QColor color = getValue(img,wcx+j,wcy+k); - avgWhiteR+=color.red(); - avgWhiteG+=color.green(); - avgWhiteB+=color.blue(); - col.setRgb(getValue(img,wcx+j,wcy+k).rgb()); - if (col.value() > white.value()) // wenn Helligkeit groesser + QColor color = getValue(img, wcx + j, wcy + k); + avgWhiteR += color.red(); + avgWhiteG += color.green(); + avgWhiteB += color.blue(); + col.setRgb(getValue(img, wcx + j, wcy + k).rgb()); + if(col.value() > white.value()) // wenn Helligkeit groesser white = col; } - avgWhiteR/=18; avgWhiteG/=18; avgWhiteB/=18; + avgWhiteR /= 18; + avgWhiteG /= 18; + avgWhiteB /= 18; - if ((avgWhiteR !=0) && (avgWhiteG !=0) && (avgWhiteB !=0)) + if((avgWhiteR != 0) && (avgWhiteG != 0) && (avgWhiteB != 0)) { - mCol.setRgb((int) MIN(((255./avgWhiteR)*mCol.red()), 255.), (int) MIN(((255./avgWhiteG)*mCol.green()), 255.), (int) MIN(((255./avgWhiteB)*mCol.blue()), 255.)); - colOther.setRgb((int) MIN(((255./avgWhiteR)*colOther.red()), 255.), (int) MIN(((255./avgWhiteG)*colOther.green()), 255.), (int) MIN(((255./avgWhiteB)*colOther.blue()), 255.)); + mCol.setRgb( + (int) MIN(((255. / avgWhiteR) * mCol.red()), 255.), + (int) MIN(((255. / avgWhiteG) * mCol.green()), 255.), + (int) MIN(((255. / avgWhiteB) * mCol.blue()), 255.)); + colOther.setRgb( + (int) MIN(((255. / avgWhiteR) * colOther.red()), 255.), + (int) MIN(((255. / avgWhiteG) * colOther.green()), 255.), + (int) MIN(((255. / avgWhiteB) * colOther.blue()), 255.)); } else - debout << "weiss ist zu dunkel!!!!!!!!!!!!!!"<<std::endl; + debout << "weiss ist zu dunkel!!!!!!!!!!!!!!" << std::endl; // eigentlich muesset saettigung ueber histogramm angepasst werden!! } @@ -420,21 +432,21 @@ void MarkerCasern::organize(const cv::Mat &img, bool autoWB) // wenn auf markern farbe nahezu identisch // weisst dies auf einen schwarzen marker hin, // dann wird der marker genommen, der den groessten radius hat - if (abs(mCol.value()-colOther.value()) < 30) //&& abs(mCol.saturation()-colOther.saturation()) < 40 + if(abs(mCol.value() - colOther.value()) < 30) //&& abs(mCol.saturation()-colOther.saturation()) < 40 { double maxRadius = 0, rad; - int maxIdx = -1; - for (i = 0; i < mSpots.size(); ++i) - if (i != mCenterIndex) + int maxIdx = -1; + for(i = 0; i < mSpots.size(); ++i) + if(i != mCenterIndex) { - rad = (mSpots[i].r1()+mSpots[i].r2())/2.; - if (rad > maxRadius) + rad = (mSpots[i].r1() + mSpots[i].r2()) / 2.; + if(rad > maxRadius) { maxRadius = rad; - maxIdx = i; + maxIdx = i; } } - if (mColorIndex != maxIdx) + if(mColorIndex != maxIdx) { mOtherIndex = mColorIndex; mColorIndex = maxIdx; @@ -446,7 +458,7 @@ void MarkerCasern::organize(const cv::Mat &img, bool autoWB) MyEllipse MarkerCasern::getCenterSpot() const { - if (mCenterIndex == -1) + if(mCenterIndex == -1) return mHead; // good fallback ? else return mSpots[mCenterIndex]; @@ -454,7 +466,7 @@ MyEllipse MarkerCasern::getCenterSpot() const MyEllipse MarkerCasern::getColorSpot() const { - if (mColorIndex == -1) + if(mColorIndex == -1) return mHead; // good fallback ? else return mSpots[mColorIndex]; @@ -464,31 +476,31 @@ void MarkerCasern::draw(cv::Mat &img) const { int i; - //head - if (hasHead()) + // head + if(hasHead()) head().draw(img, 255, 0, 255); - //marker - for (i = 0; i < mSpots.size(); ++i) + // marker + for(i = 0; i < mSpots.size(); ++i) { - if (i == mCenterIndex) + if(i == mCenterIndex) mSpots[i].draw(img, 255, 0, 0); else mSpots[i].draw(img, 0, 0, 255); } - if (hasHead() && mSpots.size() == 0) + if(hasHead() && mSpots.size() == 0) { MyEllipse e(head().center().x(), head().center().y(), 4, 4, 0); e.draw(img, 255, 0, 0); } // quadrangle - if (hasQuadrangle()) + if(hasQuadrangle()) { std::vector<cv::Point> pt; - for (i = 0; i < 4; ++i) - pt.push_back(cv::Point(mQuadrangle[i].x(),mQuadrangle[i].y())); - // draw the square as a closed polyline - cv::polylines(img,pt,true,CV_RGB(0,255,0),1,cv::LINE_AA,0); + for(i = 0; i < 4; ++i) + pt.push_back(cv::Point(mQuadrangle[i].x(), mQuadrangle[i].y())); + // draw the square as a closed polyline + cv::polylines(img, pt, true, CV_RGB(0, 255, 0), 1, cv::LINE_AA, 0); } } @@ -496,7 +508,7 @@ void MarkerCasern::draw(cv::Mat &img) const // img is 1 channel black/white // gibt zurueck, ob ellipse mgl als spot oder kopf eingefuegt wurde oder zur modifizierung mgl beigetragen hat -bool MarkerCasernList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool blackInside) +bool MarkerCasernList::mayAddEllipse(const cv::Mat &img, const MyEllipse &e, bool blackInside) { int i; @@ -504,51 +516,55 @@ bool MarkerCasernList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, boo int cy = myRound(e.center().y()); // maybe spot - if (blackInside && // marker have to be black inside - (e.r1()>SPOT_SIZE_MIN && e.r1()<SPOT_SIZE_MAX && e.r2()>SPOT_SIZE_MIN && e.r2()<SPOT_SIZE_MAX && e.ratio()<2.) && // ellipse size - ((cx < img.cols-3) && (cx > 1) && (cy < img.rows-3) && (cy > 1))) // && // not near the image border + if(blackInside && // marker have to be black inside + (e.r1() > SPOT_SIZE_MIN && e.r1() < SPOT_SIZE_MAX && e.r2() > SPOT_SIZE_MIN && e.r2() < SPOT_SIZE_MAX && + e.ratio() < 2.) && // ellipse size + ((cx < img.cols - 3) && (cx > 1) && (cy < img.rows - 3) && (cy > 1))) // && // not near the image border { int s = -1; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if ((s = at(i).isOverlappingSpots(e)) > -1) + if((s = at(i).isOverlappingSpots(e)) > -1) { // value(i) - returns T // [i] - returns T& // at(i) - returns const T& (*this)[i].modifySpot(s, e); break; - } else if (at(i).isOverlappingHead(e)) + } + else if(at(i).isOverlappingHead(e)) { (*this)[i].addSpot(e); break; } } - if (s == -1) + if(s == -1) { MarkerCasern m; m.addSpot(e); append(m); } return true; - // maybe head - } else if (!blackInside && // head has to be white inside - e.r1()>HEAD_SIZE_MIN && e.r1()<HEAD_SIZE_MAX && e.r2()>HEAD_SIZE_MIN && e.r2()<HEAD_SIZE_MAX && e.ratio()<3.) // was 12..50 + // maybe head + } + else if( + !blackInside && // head has to be white inside + e.r1() > HEAD_SIZE_MIN && e.r1() < HEAD_SIZE_MAX && e.r2() > HEAD_SIZE_MIN && e.r2() < HEAD_SIZE_MAX && + e.ratio() < 3.) // was 12..50 { bool doesExist = false; - int j; - for (i = 0; i < size() && !doesExist; ++i) + int j; + for(i = 0; i < size() && !doesExist; ++i) { - if (at(i).isOverlappingHead(e)) + if(at(i).isOverlappingHead(e)) { (*this)[i].modifyHead(e); doesExist = true; } - else if (!at(i).hasHead()) + else if(!at(i).hasHead()) { - - for (j = 0; j < at(i).spots().size(); ++j) - if (e.isInside(at(i).spots()[j].center())) + for(j = 0; j < at(i).spots().size(); ++j) + if(e.isInside(at(i).spots()[j].center())) { (*this)[i].modifyHead(e); doesExist = true; @@ -556,7 +572,7 @@ bool MarkerCasernList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, boo } } } - if (!doesExist) + if(!doesExist) append(MarkerCasern(e)); return true; } @@ -564,15 +580,15 @@ bool MarkerCasernList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, boo } // gibt zurueck, ob Quadrangle mgl eingefuegt wurde oder zur modifizierung beigetragen hat -bool MarkerCasernList::mayAddQuadrangle(const Vec2F v[4]) //Vec2F p1, Vec2F p2, Vec2F p3, Vec2F p4 +bool MarkerCasernList::mayAddQuadrangle(const Vec2F v[4]) // Vec2F p1, Vec2F p2, Vec2F p3, Vec2F p4 { - Vec2F midPoint = (v[0]+v[1]+v[2]+v[3])*0.25; - for (int i = 0; i < size(); ++i) + Vec2F midPoint = (v[0] + v[1] + v[2] + v[3]) * 0.25; + for(int i = 0; i < size(); ++i) { - if (at(i).hasHead() && at(i).head().isInside(midPoint)) + if(at(i).hasHead() && at(i).head().isInside(midPoint)) { (*this)[i].modifyQuadrangle(v); - return true; //break; + return true; // break; } } return false; @@ -584,31 +600,33 @@ void MarkerCasernList::organize(const cv::Mat &img, bool autoWB) int i, j, k, s; // delete marker without head and organize every marker - for (i = 0; i < size(); ) + for(i = 0; i < size();) { - if (at(i).hasHead()) + if(at(i).hasHead()) { - // durch mgl wachsen der head ellipsen muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen ergeben - // passiert sehr selten!! - for (j = i+1; j < size(); ++j) + // durch mgl wachsen der head ellipsen muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen + // ergeben passiert sehr selten!! + for(j = i + 1; j < size(); ++j) { - if (at(i).isOverlappingHead(at(j).head())) + if(at(i).isOverlappingHead(at(j).head())) { (*this)[i].modifyHead(at(j).head()); - for (k = 0; k < at(j).spots().size(); ++k) + for(k = 0; k < at(j).spots().size(); ++k) { - if ((s = at(i).isOverlappingSpots(at(j).spots()[k])) > -1) + if((s = at(i).isOverlappingSpots(at(j).spots()[k])) > -1) { (*this)[i].modifySpot(s, at(j).spots()[k]); break; - } else if (at(i).isOverlappingHead(at(j).spots()[k])) + } + else if(at(i).isOverlappingHead(at(j).spots()[k])) { (*this)[i].addSpot(at(j).spots()[k]); break; } } removeAt(j); - j=i; // muss von vorne begonnen werden, da head wachsen koennte und nun vorgaenger von j hineinpassen //--j; + j = i; // muss von vorne begonnen werden, da head wachsen koennte und nun vorgaenger von j + // hineinpassen //--j; } } (*this)[i++].organize(img, autoWB); @@ -618,11 +636,9 @@ void MarkerCasernList::organize(const cv::Mat &img, bool autoWB) } } -//draw ... Qt - void MarkerCasernList::draw(cv::Mat &img) const { - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) at(i).draw(img); } @@ -630,13 +646,13 @@ void MarkerCasernList::toCrossList(QList<TrackPoint> *crossList, bool ignoreWith { Vec2F v1, v2; - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) { - if (at(i).hasHead()) + if(at(i).hasHead()) { - if (at(i).spots().size() == 0) + if(at(i).spots().size() == 0) { - if (!ignoreWithoutMarker) + if(!ignoreWithoutMarker) { v1 = at(i).head().center(); crossList->append(TrackPoint(v1, 0)); // 0 schlechteste qualitaet diff --git a/src/markerHermes.cpp b/src/markerHermes.cpp index 1c15e1aeeb59f9b835225094d4bd3ce36b32e364..dc6e3954052d562ee31d061a049303329ff9b548 100644 --- a/src/markerHermes.cpp +++ b/src/markerHermes.cpp @@ -18,7 +18,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -//folgende zeile spaeter raus +// folgende zeile spaeter raus #include <opencv2/highgui.hpp> // an Treppen koennen grosse unterschiede da sein!!!! @@ -26,95 +26,84 @@ #define HEAD_SIZE_MAX 30 #define SPOT_SIZE_MIN 1 #define SPOT_SIZE_MAX 9 -#define MIN_CONTRAST 100 // war 150 bei zu geringem Kontrast wird spot geloescht +#define MIN_CONTRAST 100 // war 150 bei zu geringem Kontrast wird spot geloescht -#include "markerHermes.h" #include "helper.h" +#include "markerHermes.h" #include "tracker.h" -// bei marker koennnte sich fuer jeden spot eine liste gemerkt werden und spaeter ausgleich +// bei marker koennnte sich fuer jeden spot eine liste gemerkt werden und spaeter ausgleich // regressionsgrade legen um optimale linie durch marker zu erhalten -MarkerHermes::MarkerHermes(MyEllipse head) - : mHead(head), - mHasHead(true), - mCenterIndex(-1) -{ -} -MarkerHermes::MarkerHermes() - : mHasHead(false), - mCenterIndex(-1) - -{ -} +MarkerHermes::MarkerHermes(MyEllipse head) : mHead(head), mHasHead(true), mCenterIndex(-1) {} +MarkerHermes::MarkerHermes() : mHasHead(false), mCenterIndex(-1) {} // muesste alles automatisch durch den defaultdestructor gemacht werden! MarkerHermes::~MarkerHermes() { mSpots.clear(); mSpotCount.clear(); } - -// 3 inline functions to get access to class member varaibales only in .h file -bool MarkerHermes::isOverlappingHead(const MyEllipse& e) const +bool MarkerHermes::isOverlappingHead(const MyEllipse &e) const { - if (hasHead()) + if(hasHead()) return mHead.isInside(e.center()) || e.isInside(mHead.center()); else return false; } -bool MarkerHermes::isInsideHead(const Vec2F& p) const +bool MarkerHermes::isInsideHead(const Vec2F &p) const { - if (hasHead()) + if(hasHead()) return mHead.isInside(p); else return false; } // returns spot number in spots list when inside, otherwise returns -1 -int MarkerHermes::isOverlappingSpots(const MyEllipse& e) const +int MarkerHermes::isOverlappingSpots(const MyEllipse &e) const { - for (int i = 0; i < mSpots.size(); ++i) - if ((mSpots[i].isInside(e.center()) || e.isInside(mSpots[i].center())) && // Mittelpkte liegen ineinander - ((e.center()-mSpots[i].center()).length() < 2)) // kein zu grosser Abstand + for(int i = 0; i < mSpots.size(); ++i) + if((mSpots[i].isInside(e.center()) || e.isInside(mSpots[i].center())) && // Mittelpkte liegen ineinander + ((e.center() - mSpots[i].center()).length() < 2)) // kein zu grosser Abstand return i; return -1; } -int MarkerHermes::isInsideSpots(const Vec2F& p) const +int MarkerHermes::isInsideSpots(const Vec2F &p) const { - for (int i = 0; i < mSpots.size(); ++i) - if (mSpots[i].isInside(p)) + for(int i = 0; i < mSpots.size(); ++i) + if(mSpots[i].isInside(p)) return i; return -1; } void MarkerHermes::modifyHead(const MyEllipse &head) { - // man koennte auch spots und heads sammeln und am ende eine ueberpruefung vornehmen!!!!!! + // man koennte auch spots und heads sammeln und am ende eine ueberpruefung vornehmen!!!!!! // median , regressionsgrade // man koennte auch pruefen: // - ob ellips-mittelpkt besser auf linie von markern liegt // - ob die outline eine bestimmte groesse besitzt - if (hasHead()) + if(hasHead()) { - if (mHead.outline()>205 && mHead.outline()<268) // bevorzugte groesse - nur initial koennte andere erzeugt werden - if (fabs(mHead.ratio()-1.5)>fabs(head.ratio()-1.5)) // because white plate is 14x21cm like a real head + if(mHead.outline() > 205 && + mHead.outline() < 268) // bevorzugte groesse - nur initial koennte andere erzeugt werden + if(fabs(mHead.ratio() - 1.5) > fabs(head.ratio() - 1.5)) // because white plate is 14x21cm like a real head mHead = head; } else { mHasHead = true; - mHead = head; + mHead = head; } } void MarkerHermes::modifySpot(int i, const MyEllipse &spot) { - if (i < mSpots.size()) + if(i < mSpots.size()) { // man koennte auch pruefen: // - ob abstand zur mittellinie geringer // - ob form eher kreisfoermig - if (spot.outline() > mSpots[i].outline()) + if(spot.outline() > mSpots[i].outline()) mSpots[i] = spot; ++mSpotCount[i]; } @@ -136,19 +125,20 @@ void MarkerHermes::organize(const cv::Mat &img, bool /*autoWB*/) int i, j, k; // direkt herausspringen, da nichts zu tun ist - if (mSpots.size() == 0) + if(mSpots.size() == 0) return; // durch mgl wachsen der spots muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen ergeben - for (i = 0; i < mSpots.size(); ++i) - for (j = i+1; j < mSpots.size(); ++j) - if (mSpots[i].isInside(mSpots[j].center()) || mSpots[j].isInside(mSpots[i].center())) + for(i = 0; i < mSpots.size(); ++i) + for(j = i + 1; j < mSpots.size(); ++j) + if(mSpots[i].isInside(mSpots[j].center()) || mSpots[j].isInside(mSpots[i].center())) { modifySpot(i, mSpots[j]); deleteSpot(j); - j=i; // es muss von vorne begonnen werden, da i wachsen koennte und dann vorgaenger von j nun hineinpassen koennten // --j; + j = i; // es muss von vorne begonnen werden, da i wachsen koennte und dann vorgaenger von j nun + // hineinpassen koennten // --j; } - + // nach groesse sortieren und loeschen koennte kreuz angreifen zugunsten von zahl // gucken, ob in ellipse wirklich zB bullet drin ist @@ -158,36 +148,37 @@ void MarkerHermes::organize(const cv::Mat &img, bool /*autoWB*/) // nur die spots mit am meisten treffern stehen lassen int maxCount = 0; - for (i = 0; i < mSpotCount.size(); ++i) - if (mSpotCount[i] > maxCount) + for(i = 0; i < mSpotCount.size(); ++i) + if(mSpotCount[i] > maxCount) maxCount = mSpotCount[i]; - for (i = 0; i < mSpotCount.size(); ++i) - if (mSpotCount[i] < maxCount) + for(i = 0; i < mSpotCount.size(); ++i) + if(mSpotCount[i] < maxCount) { deleteSpot(i); --i; } - // 1 spots heraussuchen, bei denen um center in quadrat. bereich in ellipse der dunkelste Pkt (kleiner value in hsv) gefunden wird - // 1 uebrig lassen, weil entweder nummer an kopfseite sehr dunkel sein kann, wenn zu sehen oder in sehr hellen bereichen kreuz wegfallen wuerde + // 1 spots heraussuchen, bei denen um center in quadrat. bereich in ellipse der dunkelste Pkt (kleiner value in hsv) + // gefunden wird 1 uebrig lassen, weil entweder nummer an kopfseite sehr dunkel sein kann, wenn zu sehen oder in + // sehr hellen bereichen kreuz wegfallen wuerde int cx, cy, r; - if (mSpots.size() > 1) + if(mSpots.size() > 1) { QList<int> minValList; - for (i = 0; i < mSpots.size(); ++i) + for(i = 0; i < mSpots.size(); ++i) { - cx = myRound(mSpots[i].x()); - cy = myRound(mSpots[i].y()); - r = myRound((mSpots[i].r1()+mSpots[i].r2())/2.); // mittlerer radius - int minVal = 256; // groesser als komplett weiss (255) + cx = myRound(mSpots[i].x()); + cy = myRound(mSpots[i].y()); + r = myRound((mSpots[i].r1() + mSpots[i].r2()) / 2.); // mittlerer radius + int minVal = 256; // groesser als komplett weiss (255) // bildrand muss nicht ueberprueft werden, da sie gar nicht erst hereingekommen waeren - for (j = -r; j < r+1; ++j) - for (k = -r; k < r+1; ++k) + for(j = -r; j < r + 1; ++j) + for(k = -r; k < r + 1; ++k) { - if (getValue(img, cx+j, cy+k).value() < minVal) - minVal = getValue(img, cx+j, cy+k).value(); // Helligkeit + if(getValue(img, cx + j, cy + k).value() < minVal) + minVal = getValue(img, cx + j, cy + k).value(); // Helligkeit } minValList.append(minVal); } @@ -195,8 +186,8 @@ void MarkerHermes::organize(const cv::Mat &img, bool /*autoWB*/) // loeschen aller zu hellen spots QList<int> minValListSort = minValList; std::sort(minValListSort.begin(), minValListSort.end()); // sortiert aufsteigend - for (i = 0; i < mSpots.size(); ++i) - if (minValList[i] > minValListSort[0]) // nur der dunkelste bleibt uebrig + for(i = 0; i < mSpots.size(); ++i) + if(minValList[i] > minValListSort[0]) // nur der dunkelste bleibt uebrig { deleteSpot(i); minValList.removeAt(i); @@ -206,27 +197,27 @@ void MarkerHermes::organize(const cv::Mat &img, bool /*autoWB*/) // ab hier nur noch 0 oder 1 spots!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // bei 0 muss keine farbe mehr bestimmt werden - if (mSpots.size() == 1) + if(mSpots.size() == 1) { - - cx = myRound(mSpots[0].x()); - cy = myRound(mSpots[0].y()); - r = myRound((mSpots[0].r1()+mSpots[0].r2())/2.); // mittlerer radius - int minVal = 256; // groesser als komplett weiss (255) + cx = myRound(mSpots[0].x()); + cy = myRound(mSpots[0].y()); + r = myRound((mSpots[0].r1() + mSpots[0].r2()) / 2.); // mittlerer radius + int minVal = 256; // groesser als komplett weiss (255) // bildrand muss nicht ueberprueft werden, da sie gar nicht erst hereingekommen waeren - for (j = -r; j < r+1; ++j) - for (k = -r; k < r+1; ++k) - if (getValue(img, cx+j, cy+k).value() < minVal) - minVal = getValue(img, cx+j, cy+k).value(); // Helligkeit + for(j = -r; j < r + 1; ++j) + for(k = -r; k < r + 1; ++k) + if(getValue(img, cx + j, cy + k).value() < minVal) + minVal = getValue(img, cx + j, cy + k).value(); // Helligkeit int maxVal = 0; - for (j = -2*r; j < 2*r+1; ++j) - for (k = -2*r; k < 2*r+1; ++k) - if ((cx+j < img.cols) && (cx+j > -1) && (cy+k < img.rows) && (cy+k > -1)) // bildrand muss ueberprueft werden - if (getValue(img, cx+j, cy+k).value() > maxVal) - maxVal = getValue(img, cx+j, cy+k).value(); // Helligkeit - - if (maxVal-minVal < MIN_CONTRAST) // war 150bei zu geringem Kontrast wird spot geloescht + for(j = -2 * r; j < 2 * r + 1; ++j) + for(k = -2 * r; k < 2 * r + 1; ++k) + if((cx + j < img.cols) && (cx + j > -1) && (cy + k < img.rows) && + (cy + k > -1)) // bildrand muss ueberprueft werden + if(getValue(img, cx + j, cy + k).value() > maxVal) + maxVal = getValue(img, cx + j, cy + k).value(); // Helligkeit + + if(maxVal - minVal < MIN_CONTRAST) // war 150bei zu geringem Kontrast wird spot geloescht { deleteSpot(0); return; @@ -238,7 +229,7 @@ void MarkerHermes::organize(const cv::Mat &img, bool /*autoWB*/) MyEllipse MarkerHermes::getCenterSpot() const { - if (mCenterIndex == -1) + if(mCenterIndex == -1) return mHead; // good fallback ? else return mSpots[mCenterIndex]; @@ -248,18 +239,18 @@ void MarkerHermes::draw(cv::Mat &img) const { int i; - //head - if (hasHead()) + // head + if(hasHead()) head().draw(img, 50, 50, 255); - //marker - for (i = 0; i < mSpots.size(); ++i) + // marker + for(i = 0; i < mSpots.size(); ++i) { - if (i == mCenterIndex) + if(i == mCenterIndex) mSpots[i].draw(img, 150, 150, 0); else mSpots[i].draw(img, 0, 150, 150); } - if (hasHead() && mSpots.size() == 0) + if(hasHead() && mSpots.size() == 0) { MyEllipse e(head().center().x(), head().center().y(), 4, 4, 0); e.draw(img, 255, 0, 255); @@ -270,7 +261,7 @@ void MarkerHermes::draw(cv::Mat &img) const // img is 1 channel black/white // gibt zurueck, ob ellipse mgl als spot oder kopf eingefuegt wurde oder zur modifizierung mgl beigetragen hat -bool MarkerHermesList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool blackInside) +bool MarkerHermesList::mayAddEllipse(const cv::Mat &img, const MyEllipse &e, bool blackInside) { int i; @@ -278,51 +269,55 @@ bool MarkerHermesList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, boo int cy = myRound(e.center().y()); // maybe spot - if (blackInside && // marker have to be black inside - (e.r1()>SPOT_SIZE_MIN && e.r1()<SPOT_SIZE_MAX && e.r2()>SPOT_SIZE_MIN && e.r2()<SPOT_SIZE_MAX && e.ratio()<2.) && // ellipse size - ((cx < img.cols-3) && (cx > 1) && (cy < img.rows-3) && (cy > 1))) // && // not near the image border + if(blackInside && // marker have to be black inside + (e.r1() > SPOT_SIZE_MIN && e.r1() < SPOT_SIZE_MAX && e.r2() > SPOT_SIZE_MIN && e.r2() < SPOT_SIZE_MAX && + e.ratio() < 2.) && // ellipse size + ((cx < img.cols - 3) && (cx > 1) && (cy < img.rows - 3) && (cy > 1))) // && // not near the image border { int s = -1; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if ((s = at(i).isOverlappingSpots(e)) > -1) + if((s = at(i).isOverlappingSpots(e)) > -1) { // value(i) - returns T // [i] - returns T& // at(i) - returns const T& (*this)[i].modifySpot(s, e); break; - } else if (at(i).isOverlappingHead(e)) + } + else if(at(i).isOverlappingHead(e)) { (*this)[i].addSpot(e); break; } } - if (s == -1) + if(s == -1) { MarkerHermes m; m.addSpot(e); append(m); } return true; - // maybe head - } else if (!blackInside && // head has to be white inside - e.r1()>HEAD_SIZE_MIN && e.r1()<HEAD_SIZE_MAX && e.r2()>HEAD_SIZE_MIN && e.r2()<HEAD_SIZE_MAX && e.ratio()<3.) // was 12..50 + // maybe head + } + else if( + !blackInside && // head has to be white inside + e.r1() > HEAD_SIZE_MIN && e.r1() < HEAD_SIZE_MAX && e.r2() > HEAD_SIZE_MIN && e.r2() < HEAD_SIZE_MAX && + e.ratio() < 3.) // was 12..50 { bool doesExist = false; - int j; - for (i = 0; i < size() && !doesExist; ++i) + int j; + for(i = 0; i < size() && !doesExist; ++i) { - if (at(i).isOverlappingHead(e)) + if(at(i).isOverlappingHead(e)) { (*this)[i].modifyHead(e); doesExist = true; } - else if (!at(i).hasHead()) + else if(!at(i).hasHead()) { - - for (j = 0; j < at(i).spots().size(); ++j) - if (e.isInside(at(i).spots()[j].center())) + for(j = 0; j < at(i).spots().size(); ++j) + if(e.isInside(at(i).spots()[j].center())) { (*this)[i].modifyHead(e); doesExist = true; @@ -330,7 +325,7 @@ bool MarkerHermesList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, boo } } } - if (!doesExist) + if(!doesExist) append(MarkerHermes(e)); return true; } @@ -343,31 +338,33 @@ void MarkerHermesList::organize(const cv::Mat &img, bool autoWB) int i, j, k, s; // delete marker without head and organize every marker - for (i = 0; i < size(); ) + for(i = 0; i < size();) { - if (at(i).hasHead()) + if(at(i).hasHead()) { - // durch mgl wachsen der head ellipsen muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen ergeben - // passiert sehr selten!! - for (j = i+1; j < size(); ++j) + // durch mgl wachsen der head ellipsen muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen + // ergeben passiert sehr selten!! + for(j = i + 1; j < size(); ++j) { - if (at(i).isOverlappingHead(at(j).head())) + if(at(i).isOverlappingHead(at(j).head())) { (*this)[i].modifyHead(at(j).head()); - for (k = 0; k < at(j).spots().size(); ++k) + for(k = 0; k < at(j).spots().size(); ++k) { - if ((s = at(i).isOverlappingSpots(at(j).spots()[k])) > -1) + if((s = at(i).isOverlappingSpots(at(j).spots()[k])) > -1) { (*this)[i].modifySpot(s, at(j).spots()[k]); break; - } else if (at(i).isOverlappingHead(at(j).spots()[k])) + } + else if(at(i).isOverlappingHead(at(j).spots()[k])) { (*this)[i].addSpot(at(j).spots()[k]); break; } } removeAt(j); - j=i; // muss von vorne begonnen werden, da head wachsen koennte und nun vorgaenger von j hineinpassen //--j; + j = i; // muss von vorne begonnen werden, da head wachsen koennte und nun vorgaenger von j + // hineinpassen //--j; } } (*this)[i++].organize(img, autoWB); @@ -377,11 +374,11 @@ void MarkerHermesList::organize(const cv::Mat &img, bool autoWB) } } -//draw ... Qt +// draw ... Qt void MarkerHermesList::draw(cv::Mat &img) const { - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) at(i).draw(img); } @@ -389,13 +386,13 @@ void MarkerHermesList::toCrossList(QList<TrackPoint> *crossList, bool ignoreWith { Vec2F v1, v2; - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) { - if (at(i).hasHead()) + if(at(i).hasHead()) { - if (at(i).spots().size() == 0) + if(at(i).spots().size() == 0) { - if (!ignoreWithoutMarker) + if(!ignoreWithoutMarker) { v1 = at(i).head().center(); crossList->append(TrackPoint(v1, 0)); // 0 schlechteste qualitaet diff --git a/src/markerJapan.cpp b/src/markerJapan.cpp index db483863e48217cce7fcfcebe2fa7eed0f5f7919..e60b0e05fbfb855d6ba3e4fa1997015b719bb8fc 100644 --- a/src/markerJapan.cpp +++ b/src/markerJapan.cpp @@ -18,71 +18,61 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -//folgende zeile spaeter raus +// folgende zeile spaeter raus #include <opencv2/highgui.hpp> #define SPOT_COLOR 0 // HUE==0, hier ROT // fuehrt zu folgendem range: 0-20 + 340-359 // Marker Size is a A4 copy of file (from takahiro from japan, nishinari group) -#include "markerJapan.h" #include "helper.h" +#include "markerJapan.h" #include "tracker.h" -// bei marker koennnte sich fuer jeden spot eine liste gemerkt werden und spaeter ausgleich +// bei marker koennnte sich fuer jeden spot eine liste gemerkt werden und spaeter ausgleich // regressionsgrade legen um optimale linie durch marker zu erhalten -MarkerJapan::MarkerJapan(MyEllipse head) - : mHead(head), - mHasHead(true), - mHasQuadrangle(false), - mCenterIndex(-1), - mColorIndex(-1) -{ -} -MarkerJapan::MarkerJapan() - : mHasHead(false), - mCenterIndex(-1), - mColorIndex(-1) - +MarkerJapan::MarkerJapan(MyEllipse head) : + mHead(head), mHasHead(true), mHasQuadrangle(false), mCenterIndex(-1), mColorIndex(-1) { } +MarkerJapan::MarkerJapan() : mHasHead(false), mCenterIndex(-1), mColorIndex(-1) {} // muesste alles automatisch durch den defaultdestructor gemacht werden! MarkerJapan::~MarkerJapan() { mSpots.clear(); mSpotCount.clear(); } - + // 3 inline functions to get access to class member varaibales only in .h file -bool MarkerJapan::isOverlappingHead(const MyEllipse& e) const +bool MarkerJapan::isOverlappingHead(const MyEllipse &e) const { - if (hasHead()) + if(hasHead()) return mHead.isInside(e.center()) || e.isInside(mHead.center()); else return false; } -bool MarkerJapan::isInsideHead(const Vec2F& p) const +bool MarkerJapan::isInsideHead(const Vec2F &p) const { - if (hasHead()) + if(hasHead()) return mHead.isInside(p); else return false; } // returns spot number in spots list when inside, otherwise returns -1 -int MarkerJapan::isOverlappingSpots(const MyEllipse& e) const +int MarkerJapan::isOverlappingSpots(const MyEllipse &e) const { - for (int i = 0; i < mSpots.size(); ++i) - if ((mSpots[i].isInside(e.center()) || e.isInside(mSpots[i].center())) && // Mittelpkte liegen ineinander - ((e.center()-mSpots[i].center()).length() < 2)) // kein zu grosser Abstand + for(int i = 0; i < mSpots.size(); ++i) + if((mSpots[i].isInside(e.center()) || e.isInside(mSpots[i].center())) && // Mittelpkte liegen ineinander + ((e.center() - mSpots[i].center()).length() < 2)) // kein zu grosser Abstand return i; return -1; } -int MarkerJapan::isInsideSpots(const Vec2F& p) const +int MarkerJapan::isInsideSpots(const Vec2F &p) const { - for (int i = 0; i < mSpots.size(); ++i) - if (mSpots[i].isInside(p)) + for(int i = 0; i < mSpots.size(); ++i) + if(mSpots[i].isInside(p)) return i; return -1; } @@ -94,30 +84,32 @@ void MarkerJapan::modifyHead(const MyEllipse &head, float headSize) // man koennte auch pruefen: // - ob ellips-mittelpkt besser auf linie von markern liegt // - ob die outline eine bestimmte groesse besitzt - float outlineMin = headSize*3.5; //3.92; - float outlineMax = headSize*4.5; //4.967; + float outlineMin = headSize * 3.5; // 3.92; + float outlineMax = headSize * 4.5; // 4.967; - if (hasHead()) + if(hasHead()) { - if (mHead.outline()>outlineMin && mHead.outline()<outlineMax) // bevorzugte groesse - nur initial koennte andere erzeugt werden - if (fabs(mHead.ratio()-1.43)>fabs(head.ratio()-1.43)) // because white plate marker casern is 14x21cm -> 1.5 // for A4 -> 1.4285 + if(mHead.outline() > outlineMin && + mHead.outline() < outlineMax) // bevorzugte groesse - nur initial koennte andere erzeugt werden + if(fabs(mHead.ratio() - 1.43) > + fabs(head.ratio() - 1.43)) // because white plate marker casern is 14x21cm -> 1.5 // for A4 -> 1.4285 mHead = head; } else { mHasHead = true; - mHead = head; + mHead = head; } } void MarkerJapan::modifySpot(int i, const MyEllipse &spot) { - if (i < mSpots.size()) + if(i < mSpots.size()) { // man koennte auch pruefen: // - ob abstand zur mittellinie geringer // - ob form eher kreisfoermig - if (spot.outline() > mSpots[i].outline()) + if(spot.outline() > mSpots[i].outline()) mSpots[i] = spot; ++mSpotCount[i]; } @@ -135,23 +127,23 @@ void MarkerJapan::deleteSpot(int i) void MarkerJapan::modifyQuadrangle(const Vec2F v[4]) { - if (mHasQuadrangle) + if(mHasQuadrangle) { // seitenverhaeltnis 2:3 koennte auch bedacht werden // angle on opposed edge is nearer to 90 - if ((fabs((v[3]-v[2]).angleBetweenVec(v[0]-v[3])-PI/2.)+ - fabs((v[1]-v[0]).angleBetweenVec(v[2]-v[1])-PI/2.)) < - (fabs((mQuadrangle[3]-mQuadrangle[2]).angleBetweenVec(mQuadrangle[0]-mQuadrangle[3])-PI/2.)+ - fabs((mQuadrangle[1]-mQuadrangle[0]).angleBetweenVec(mQuadrangle[2]-mQuadrangle[1])-PI/2.))) + if((fabs((v[3] - v[2]).angleBetweenVec(v[0] - v[3]) - PI / 2.) + + fabs((v[1] - v[0]).angleBetweenVec(v[2] - v[1]) - PI / 2.)) < + (fabs((mQuadrangle[3] - mQuadrangle[2]).angleBetweenVec(mQuadrangle[0] - mQuadrangle[3]) - PI / 2.) + + fabs((mQuadrangle[1] - mQuadrangle[0]).angleBetweenVec(mQuadrangle[2] - mQuadrangle[1]) - PI / 2.))) { - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) mQuadrangle[i] = v[i]; } } else { mHasQuadrangle = true; - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) mQuadrangle[i] = v[i]; } } @@ -163,19 +155,20 @@ void MarkerJapan::organize(const cv::Mat &img, bool autoWB) int i, j, k; // direkt herausspringen, da nichts zu tun ist - if (mSpots.size() == 0) + if(mSpots.size() == 0) return; // durch mgl wachsen der spots muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen ergeben - for (i = 0; i < mSpots.size(); ++i) - for (j = i+1; j < mSpots.size(); ++j) - if (mSpots[i].isInside(mSpots[j].center()) || mSpots[j].isInside(mSpots[i].center())) + for(i = 0; i < mSpots.size(); ++i) + for(j = i + 1; j < mSpots.size(); ++j) + if(mSpots[i].isInside(mSpots[j].center()) || mSpots[j].isInside(mSpots[i].center())) { modifySpot(i, mSpots[j]); deleteSpot(j); - j=i; // es muss von vorne begonnen werden, da i wachsen koennte und dann vorgaenger von j nun hineinpassen koennten // --j; + j = i; // es muss von vorne begonnen werden, da i wachsen koennte und dann vorgaenger von j nun + // hineinpassen koennten // --j; } - + // nach groesse sortieren und loeschen koennte kreus angreifen zugunsten von zahl // gucken, ob in ellipse wirklich zB bullet drin ist @@ -183,41 +176,43 @@ void MarkerJapan::organize(const cv::Mat &img, bool autoWB) // spots loeschen, die selten erkannt wurden // mind 5 stehen lassen (marker und zahlen - auch von der seite zu sehen) int count = 100, anz = 0; - while (count > 4) + while(count > 4) { ++anz; count = 0; - for (i = 0; i < mSpotCount.size(); ++i) - if (mSpotCount[i] > anz) + for(i = 0; i < mSpotCount.size(); ++i) + if(mSpotCount[i] > anz) count++; } - for (i = 0; i < mSpotCount.size(); ++i) - if (mSpotCount[i] < anz) + for(i = 0; i < mSpotCount.size(); ++i) + if(mSpotCount[i] < anz) { deleteSpot(i); --i; } - // 2 spots heraussuchen, bei denen um center in quadrat. bereich in ellipse der dunkelste Pkt (kleiner value in hsv) gefunden wird + // 2 spots heraussuchen, bei denen um center in quadrat. bereich in ellipse der dunkelste Pkt (kleiner value in hsv) + // gefunden wird QColor col; - int cx, cy; - int numberRemaining = 2; - if (mSpots.size() > numberRemaining) + int cx, cy; + int numberRemaining = 2; + if(mSpots.size() > numberRemaining) { - int r; + int r; QList<int> minValList; - for (i = 0; i < mSpots.size(); ++i) + for(i = 0; i < mSpots.size(); ++i) { cx = myRound(mSpots[i].x()); cy = myRound(mSpots[i].y()); - r = 1; // fuehrte dazu, das zuweit gesucht wird und inangrenzenden marker hineingesuct wurde: myRound((mSpots[i].r1()+mSpots[i].r2())/2.); // mittlerer radius + r = 1; // fuehrte dazu, das zuweit gesucht wird und inangrenzenden marker hineingesuct wurde: + // myRound((mSpots[i].r1()+mSpots[i].r2())/2.); // mittlerer radius int minVal = 256; // groesser als komplett weiss (255) // bildrand muss nicht ueberprueft werden, da sie gar nicht erst hereingekommen waeren - for (j = -r; j < r+1; ++j) - for (k = -r; k < r+1; ++k) + for(j = -r; j < r + 1; ++j) + for(k = -r; k < r + 1; ++k) { - col.setRgb(getValue(img,cx+j,cy+k).rgb()); - if (col.value() < minVal) + col.setRgb(getValue(img, cx + j, cy + k).rgb()); + if(col.value() < minVal) minVal = col.value(); // Helligkeit } minValList.append(minVal); @@ -225,9 +220,9 @@ void MarkerJapan::organize(const cv::Mat &img, bool autoWB) // loeschen aller zu hellen spots QList<int> minValListSort = minValList; std::sort(minValListSort.begin(), minValListSort.end()); // sortiert aufsteigend - for (i = 0; i < mSpots.size(); ++i) + for(i = 0; i < mSpots.size(); ++i) { - if (minValList[i] > minValListSort[numberRemaining-1]) + if(minValList[i] > minValListSort[numberRemaining - 1]) { deleteSpot(i); minValList.removeAt(i); @@ -237,68 +232,70 @@ void MarkerJapan::organize(const cv::Mat &img, bool autoWB) } // bei 0 muss keine farbe mehr bestimmt werden - if (mSpots.size() < 2) + if(mSpots.size() < 2) return; - // farbe bestimmen (richtiger marker koennte auch durch form oder dem abstand des hellsten pkt in groesserer umgebung vom mittelpkt bestimmt werden) - bool colSet = false; + // farbe bestimmen (richtiger marker koennte auch durch form oder dem abstand des hellsten pkt in groesserer + // umgebung vom mittelpkt bestimmt werden) + bool colSet = false; QColor colOther; // farbe des anderen spots - for (i = 0; i < mSpots.size(); ++i) - if (i != mCenterIndex) + for(i = 0; i < mSpots.size(); ++i) + if(i != mCenterIndex) { cx = myRound(mSpots[i].x()); cy = myRound(mSpots[i].y()); - if (!colSet) + if(!colSet) { colSet = true; - mCol.setRgb(getValue(img,cx,cy).rgb()); + mCol.setRgb(getValue(img, cx, cy).rgb()); mColorIndex = i; } else { - colOther.setRgb(getValue(img,cx,cy).rgb()); + colOther.setRgb(getValue(img, cx, cy).rgb()); mOtherIndex = i; } // bildrand muss nicht ueberprueft werden, da sie gar nicht erst hereingekommen waeren - for (j = -1; j < 2; ++j) // 3x3 feld wird ueberprueft - for (k = -1; k < 2; ++k) + for(j = -1; j < 2; ++j) // 3x3 feld wird ueberprueft + for(k = -1; k < 2; ++k) { - col.setRgb(getValue(img,cx+j,cy+k).rgb()); - // faktor, um die mitte hoeher zu gewichten, da bei fd der schwarze rand mit dem weiss gemischt oft hell ist - if (col.value()/(1. + .5*(abs(j)+abs(k))) > mCol.value()) // wenn Helligkeit maximal + col.setRgb(getValue(img, cx + j, cy + k).rgb()); + // faktor, um die mitte hoeher zu gewichten, da bei fd der schwarze rand mit dem weiss gemischt oft + // hell ist + if(col.value() / (1. + .5 * (abs(j) + abs(k))) > mCol.value()) // wenn Helligkeit maximal { - if (i != mColorIndex) + if(i != mColorIndex) { - colOther = mCol; + colOther = mCol; mOtherIndex = mColorIndex; } - mCol = col; + mCol = col; mColorIndex = i; } } } - int fromColor = (SPOT_COLOR+340)%360; - int toColor = (SPOT_COLOR+20)%360; + int fromColor = (SPOT_COLOR + 340) % 360; + int toColor = (SPOT_COLOR + 20) % 360; bool corectColor = false; - int hue = mCol.hue(); - if (fromColor > toColor) // geht ueber farbrad 359 hinaus, alo 0..toColor + fromColor..359 + int hue = mCol.hue(); + if(fromColor > toColor) // geht ueber farbrad 359 hinaus, alo 0..toColor + fromColor..359 { - if ((hue <= toColor) || (hue >= fromColor)) + if((hue <= toColor) || (hue >= fromColor)) corectColor = true; } else { - if ((hue >= fromColor) && (hue <= toColor)) + if((hue >= fromColor) && (hue <= toColor)) corectColor = true; } - if (!corectColor) // spots loeschen, wenn nicht die richtige farbe, dadurch wird marker spaeter aussortiert + if(!corectColor) // spots loeschen, wenn nicht die richtige farbe, dadurch wird marker spaeter aussortiert { deleteSpot(0); deleteSpot(1); } - if (autoWB) + if(autoWB) { // weissabgleich // 1. Dynamik der Helligkeit @@ -306,69 +303,78 @@ void MarkerJapan::organize(const cv::Mat &img, bool autoWB) // weisswert und durchschnittlichen weisswert bestimmen // 2 bereiche neben farbmarker in weisser flaeche auf kopfpappe - int wcx = myRound(mSpots[mColorIndex].x()+0.356*(mSpots[mColorIndex].y()-mSpots[mOtherIndex].y())); - int wcy = myRound(mSpots[mColorIndex].y()+0.356*(mSpots[mColorIndex].x()-mSpots[mOtherIndex].x())); - QColor white(0,0,0); // hellster fleck - int avgWhiteR=0, avgWhiteG=0, avgWhiteB=0; // durchschnittlichen weisswert - for (j = -1; j < 2; ++j) // 3x3 feld um ocx,ocy wird ueberprueft - for (k = -1; k < 2; ++k) + int wcx = myRound(mSpots[mColorIndex].x() + 0.356 * (mSpots[mColorIndex].y() - mSpots[mOtherIndex].y())); + int wcy = myRound(mSpots[mColorIndex].y() + 0.356 * (mSpots[mColorIndex].x() - mSpots[mOtherIndex].x())); + QColor white(0, 0, 0); // hellster fleck + int avgWhiteR = 0, avgWhiteG = 0, avgWhiteB = 0; // durchschnittlichen weisswert + for(j = -1; j < 2; ++j) // 3x3 feld um ocx,ocy wird ueberprueft + for(k = -1; k < 2; ++k) { - QColor color = getValue(img,wcx+j,wcy+k); - avgWhiteR+=color.red(); - avgWhiteG+=color.green(); - avgWhiteB+=color.blue(); - col.setRgb(getValue(img,wcx+j,wcy+k).rgb()); - if (col.value() > white.value()) // wenn Helligkeit groesser + QColor color = getValue(img, wcx + j, wcy + k); + avgWhiteR += color.red(); + avgWhiteG += color.green(); + avgWhiteB += color.blue(); + col.setRgb(getValue(img, wcx + j, wcy + k).rgb()); + if(col.value() > white.value()) // wenn Helligkeit groesser white = col; } - wcx = myRound(mSpots[mColorIndex].x()-0.356*(mSpots[mColorIndex].y()-mSpots[mOtherIndex].y())); - wcy = myRound(mSpots[mColorIndex].y()-0.356*(mSpots[mColorIndex].x()-mSpots[mOtherIndex].x())); - for (j = -1; j < 2; ++j) // 3x3 feld um ocx,ocy wird ueberprueft - for (k = -1; k < 2; ++k) + wcx = myRound(mSpots[mColorIndex].x() - 0.356 * (mSpots[mColorIndex].y() - mSpots[mOtherIndex].y())); + wcy = myRound(mSpots[mColorIndex].y() - 0.356 * (mSpots[mColorIndex].x() - mSpots[mOtherIndex].x())); + for(j = -1; j < 2; ++j) // 3x3 feld um ocx,ocy wird ueberprueft + for(k = -1; k < 2; ++k) { - QColor color = getValue(img,wcx+j,wcy+k); - avgWhiteR+=color.red(); - avgWhiteG+=color.green(); - avgWhiteB+=color.blue(); - col.setRgb(getValue(img,wcx+j,wcy+k).rgb()); - if (col.value() > white.value()) // wenn Helligkeit groesser + QColor color = getValue(img, wcx + j, wcy + k); + avgWhiteR += color.red(); + avgWhiteG += color.green(); + avgWhiteB += color.blue(); + col.setRgb(getValue(img, wcx + j, wcy + k).rgb()); + if(col.value() > white.value()) // wenn Helligkeit groesser white = col; } - avgWhiteR/=18; avgWhiteG/=18; avgWhiteB/=18; - - if ((avgWhiteR !=0) && (avgWhiteG !=0) && (avgWhiteB !=0)) + avgWhiteR /= 18; + avgWhiteG /= 18; + avgWhiteB /= 18; + + if((avgWhiteR != 0) && (avgWhiteG != 0) && (avgWhiteB != 0)) { - mCol.setRgb((int) MIN(((255./avgWhiteR)*mCol.red()), 255.), (int) MIN(((255./avgWhiteG)*mCol.green()), 255.), (int) MIN(((255./avgWhiteB)*mCol.blue()), 255.)); - colOther.setRgb((int) MIN(((255./avgWhiteR)*colOther.red()), 255.), (int) MIN(((255./avgWhiteG)*colOther.green()), 255.), (int) MIN(((255./avgWhiteB)*colOther.blue()), 255.)); + mCol.setRgb( + (int) MIN(((255. / avgWhiteR) * mCol.red()), 255.), + (int) MIN(((255. / avgWhiteG) * mCol.green()), 255.), + (int) MIN(((255. / avgWhiteB) * mCol.blue()), 255.)); + colOther.setRgb( + (int) MIN(((255. / avgWhiteR) * colOther.red()), 255.), + (int) MIN(((255. / avgWhiteG) * colOther.green()), 255.), + (int) MIN(((255. / avgWhiteB) * colOther.blue()), 255.)); } else - debout << "Warning: white is to dark!" <<std::endl; + debout << "Warning: white is to dark!" << std::endl; // eigentlich muesset saettigung ueber histogramm angepasst werden!! } - + // wenn auf markern farbe nahezu identisch // weisst dies auf einen schwarzen marker hin, // dann wird der marker genommen, der den groessten radius hat - if (abs(mCol.value()-colOther.value()) < 10) //&& abs(mCol.saturation()-colOther.saturation()) < 40 + if(abs(mCol.value() - colOther.value()) < 10) //&& abs(mCol.saturation()-colOther.saturation()) < 40 { - debout << "Warning: both marker have nearly the same color at "<< mHead.center().x()<<", "<< mHead.center().y()<<"!" << std::endl; + debout << "Warning: both marker have nearly the same color at " << mHead.center().x() << ", " + << mHead.center().y() << "!" << std::endl; } } Vec2F MarkerJapan::getCenter() const { - if (mColorIndex == -1 || mOtherIndex == -1 || mSpots.size() < 2) + if(mColorIndex == -1 || mOtherIndex == -1 || mSpots.size() < 2) return mHead.center(); // good fallback ? else - return (mSpots[0].center()+mSpots[1].center())/2.; + return (mSpots[0].center() + mSpots[1].center()) / 2.; } MyEllipse MarkerJapan::getCenterSpot() const { - if (mCenterIndex == -1) + if(mCenterIndex == -1) return mHead; // good fallback ? else return mSpots[mCenterIndex]; @@ -376,7 +382,7 @@ MyEllipse MarkerJapan::getCenterSpot() const MyEllipse MarkerJapan::getColorSpot() const { - if (mColorIndex == -1) + if(mColorIndex == -1) return mHead; // good fallback ? else return mSpots[mColorIndex]; @@ -386,31 +392,31 @@ void MarkerJapan::draw(cv::Mat &img) const { int i; - //head - if (hasHead()) + // head + if(hasHead()) head().draw(img, 255, 0, 255); - //marker - for (i = 0; i < mSpots.size(); ++i) + // marker + for(i = 0; i < mSpots.size(); ++i) { - if (i == mCenterIndex) + if(i == mCenterIndex) mSpots[i].draw(img, 255, 0, 0); else mSpots[i].draw(img, 0, 0, 255); } - if (hasHead() && mSpots.size() == 0) + if(hasHead() && mSpots.size() == 0) { MyEllipse e(head().center().x(), head().center().y(), 4, 4, 0); e.draw(img, 255, 0, 0); } // quadrangle - if (hasQuadrangle()) + if(hasQuadrangle()) { std::vector<cv::Point> pt; - for (i = 0; i < 4; ++i) - pt.push_back(cv::Point(mQuadrangle[i].x(),mQuadrangle[i].y())); - // draw the square as a closed polyline - cv::polylines(img,pt,true,CV_RGB(0,255,0),1,cv::LINE_AA,0); + for(i = 0; i < 4; ++i) + pt.push_back(cv::Point(mQuadrangle[i].x(), mQuadrangle[i].y())); + // draw the square as a closed polyline + cv::polylines(img, pt, true, CV_RGB(0, 255, 0), 1, cv::LINE_AA, 0); } } @@ -418,7 +424,7 @@ void MarkerJapan::draw(cv::Mat &img) const // img is 1 channel black/white // gibt zurueck, ob ellipse mgl als spot oder kopf eingefuegt wurde oder zur modifizierung mgl beigetragen hat -bool MarkerJapanList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool blackInside) +bool MarkerJapanList::mayAddEllipse(const cv::Mat &img, const MyEllipse &e, bool blackInside) { int i; @@ -426,65 +432,70 @@ bool MarkerJapanList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool int cy = myRound(e.center().y()); // radius fuer japan ellipsen warvorher als Makroangegeben - float HEAD_SIZE_MIN = mHeadSize/2.; + float HEAD_SIZE_MIN = mHeadSize / 2.; float HEAD_SIZE_MAX = mHeadSize; // mHeadSize ist Durchmesser eines kopfes in pixel - float SPOT_SIZE_MIN = mHeadSize/16.; - float SPOT_SIZE_MAX = mHeadSize/4.; - int iHead = -1; + float SPOT_SIZE_MIN = mHeadSize / 16.; + float SPOT_SIZE_MAX = mHeadSize / 4.; + int iHead = -1; // maybe spot - if (blackInside && // marker have to be black inside - (e.r1()>SPOT_SIZE_MIN && e.r1()<SPOT_SIZE_MAX && e.r2()>SPOT_SIZE_MIN && e.r2()<SPOT_SIZE_MAX && e.ratio()<2.) && // ellipse size - ((cx < img.cols-3) && (cx > 1) && (cy < img.rows-3) && (cy > 1))) // && // not near the image border + if(blackInside && // marker have to be black inside + (e.r1() > SPOT_SIZE_MIN && e.r1() < SPOT_SIZE_MAX && e.r2() > SPOT_SIZE_MIN && e.r2() < SPOT_SIZE_MAX && + e.ratio() < 2.) && // ellipse size + ((cx < img.cols - 3) && (cx > 1) && (cy < img.rows - 3) && (cy > 1))) // && // not near the image border { int s = -1; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if ((s = at(i).isOverlappingSpots(e)) > -1) + if((s = at(i).isOverlappingSpots(e)) > -1) { // value(i) - returns T // [i] - returns T& // at(i) - returns const T& (*this)[i].modifySpot(s, e); break; - } else if (at(i).isOverlappingHead(e)) + } + else if(at(i).isOverlappingHead(e)) { (*this)[i].addSpot(e); break; } } - if (s == -1) + if(s == -1) { MarkerJapan m; m.addSpot(e); append(m); } return true; - // maybe head - } else if (!blackInside && // head has to be white inside - e.r1()>HEAD_SIZE_MIN && e.r1()<HEAD_SIZE_MAX && e.r2()>HEAD_SIZE_MIN && e.r2()<HEAD_SIZE_MAX && e.ratio()<3.) // was 12..50 + // maybe head + } + else if( + !blackInside && // head has to be white inside + e.r1() > HEAD_SIZE_MIN && e.r1() < HEAD_SIZE_MAX && e.r2() > HEAD_SIZE_MIN && e.r2() < HEAD_SIZE_MAX && + e.ratio() < 3.) // was 12..50 { bool doesExist = false; - int j; - for (i = 0; i < size(); ++i) // && !doesExist + int j; + for(i = 0; i < size(); ++i) // && !doesExist { - if (!doesExist && at(i).isOverlappingHead(e)) // ueberlappen sich zwei koepfe + if(!doesExist && at(i).isOverlappingHead(e)) // ueberlappen sich zwei koepfe { (*this)[i].modifyHead(e, mHeadSize); doesExist = true; } - else if (!at(i).hasHead()) // marker hat noch keinen kopf + else if(!at(i).hasHead()) // marker hat noch keinen kopf { - for (j = 0; j < at(i).spots().size(); ++j) - if (e.isInside(at(i).spots()[j].center())) + for(j = 0; j < at(i).spots().size(); ++j) + if(e.isInside(at(i).spots()[j].center())) { - if (!doesExist) + if(!doesExist) { (*this)[i].modifyHead(e, mHeadSize); - iHead = i; + iHead = i; doesExist = true; } - else if (iHead != -1) // restlichen spots untersuchen, ob sie auch noch in kopf liegen + else if(iHead != -1) // restlichen spots untersuchen, ob sie auch noch in kopf liegen { (*this)[iHead].addSpot(at(i).spots()[j]); (*this)[i].deleteSpot(j); @@ -494,7 +505,7 @@ bool MarkerJapanList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool } } - if (!doesExist) + if(!doesExist) { append(MarkerJapan(e)); } @@ -504,15 +515,15 @@ bool MarkerJapanList::mayAddEllipse(const cv::Mat &img, const MyEllipse& e, bool } // gibt zurueck, ob Quadrangle mgl eingefuegt wurde oder zur modifizierung beigetragen hat -bool MarkerJapanList::mayAddQuadrangle(const Vec2F v[4]) //Vec2F p1, Vec2F p2, Vec2F p3, Vec2F p4 +bool MarkerJapanList::mayAddQuadrangle(const Vec2F v[4]) // Vec2F p1, Vec2F p2, Vec2F p3, Vec2F p4 { - Vec2F midPoint = (v[0]+v[1]+v[2]+v[3])*0.25; - for (int i = 0; i < size(); ++i) + Vec2F midPoint = (v[0] + v[1] + v[2] + v[3]) * 0.25; + for(int i = 0; i < size(); ++i) { - if (at(i).hasHead() && at(i).head().isInside(midPoint)) + if(at(i).hasHead() && at(i).head().isInside(midPoint)) { (*this)[i].modifyQuadrangle(v); - return true; //break; + return true; // break; } } return false; @@ -524,41 +535,45 @@ void MarkerJapanList::organize(const cv::Mat &img, bool autoWB) int i, j, k, s; // delete marker without head and organize every marker - for (i = 0; i < size(); ) + for(i = 0; i < size();) { - if (at(i).hasHead()) + if(at(i).hasHead()) { - // durch mgl wachsen der head ellipsen muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen ergeben - // passiert sehr selten!! - for (j = i+1; j < size(); ++j) + // durch mgl wachsen der head ellipsen muss ueberprueft werden, ob sich im nachhinnein Ueberlagerungen + // ergeben passiert sehr selten!! + for(j = i + 1; j < size(); ++j) { - if (at(i).isOverlappingHead(at(j).head())) + if(at(i).isOverlappingHead(at(j).head())) { (*this)[i].modifyHead(at(j).head(), mHeadSize); - for (k = 0; k < at(j).spots().size(); ++k) + for(k = 0; k < at(j).spots().size(); ++k) { - if ((s = at(i).isOverlappingSpots(at(j).spots()[k])) > -1) + if((s = at(i).isOverlappingSpots(at(j).spots()[k])) > -1) { (*this)[i].modifySpot(s, at(j).spots()[k]); break; - } else if (at(i).isOverlappingHead(at(j).spots()[k])) + } + else if(at(i).isOverlappingHead(at(j).spots()[k])) { (*this)[i].addSpot(at(j).spots()[k]); break; } } removeAt(j); - j=i; // muss von vorne begonnen werden, da head wachsen koennte und nun vorgaenger von j hineinpassen //--j; + j = i; // muss von vorne begonnen werden, da head wachsen koennte und nun vorgaenger von j + // hineinpassen //--j; } } (*this)[i].organize(img, autoWB); - if (!at(i).hasSpots()) // if after organization no spot is inside had + if(!at(i).hasSpots()) // if after organization no spot is inside had removeAt(i); else // hat mind. 2 spots { // Abstand der Spots bestimmen (nur hier headsize bekannt) float spotDistance = at(i).spots().at(0).center().distanceToPoint(at(i).spots().at(1).center()); - if (spotDistance > 0.8 * mHeadSize) // ein Hoechstabstand soll eingehalten werden, in Japan waren es hier 12 // kein Minimalabstand da bei Schraegsicht abstand kleiner werden kann + if(spotDistance > + 0.8 * mHeadSize) // ein Hoechstabstand soll eingehalten werden, in Japan waren es hier 12 // kein + // Minimalabstand da bei Schraegsicht abstand kleiner werden kann removeAt(i); else i++; @@ -569,11 +584,11 @@ void MarkerJapanList::organize(const cv::Mat &img, bool autoWB) } } -//draw ... Qt +// draw ... Qt void MarkerJapanList::draw(cv::Mat &img) const { - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) at(i).draw(img); } @@ -581,13 +596,13 @@ void MarkerJapanList::toCrossList(QList<TrackPoint> *crossList, bool ignoreWitho { Vec2F v1, v2; - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) { - if (at(i).hasHead()) + if(at(i).hasHead()) { - if (at(i).spots().size() == 0) + if(at(i).spots().size() == 0) { - if (!ignoreWithoutMarker) + if(!ignoreWithoutMarker) { v1 = at(i).getCenter(); crossList->append(TrackPoint(v1, 0)); // 0 schlechteste qualitaet diff --git a/src/moCapController.cpp b/src/moCapController.cpp index e30b9be4a2634cc35faa38104ae868596edac16c..d4405f4e8ee1a90b86715d3c3c0f516e1ea4aceb 100644 --- a/src/moCapController.cpp +++ b/src/moCapController.cpp @@ -18,21 +18,20 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QDomElement> -#include <QMessageBox> - -#include <opencv2/opencv.hpp> - -#include "moCapPerson.h" #include "moCapController.h" + #include "IO.h" #include "helper.h" +#include "moCapPerson.h" +#include <QDomElement> +#include <QMessageBox> +#include <opencv2/opencv.hpp> -bool operator==(const SegmentRenderData& lhs, const SegmentRenderData& rhs){ - return lhs.mColor == rhs.mColor && - lhs.mDirected == rhs.mDirected && - lhs.mLine == rhs.mLine && + +bool operator==(const SegmentRenderData &lhs, const SegmentRenderData &rhs) +{ + return lhs.mColor == rhs.mColor && lhs.mDirected == rhs.mDirected && lhs.mLine == rhs.mLine && lhs.mThickness == rhs.mThickness; } @@ -51,32 +50,38 @@ bool operator==(const SegmentRenderData& lhs, const SegmentRenderData& rhs){ * @param [in]currentFrame current frame of the video * @param [out]renderData array of SegmentRenderData, to which to append the result */ -void MoCapController::transformPersonSkeleton(const MoCapPerson &person, double framerate, int currentFrame, std::vector<SegmentRenderData> &renderData) const +void MoCapController::transformPersonSkeleton( + const MoCapPerson & person, + double framerate, + int currentFrame, + std::vector<SegmentRenderData> &renderData) const { - double currentTime = currentFrame/framerate; + double currentTime = currentFrame / framerate; double sampleIndex = person.getSampleIndex(currentTime); - bool hasPre = person.hasSample(std::floor(sampleIndex)); - bool hasPost = person.hasSample(std::ceil(sampleIndex)); + bool hasPre = person.hasSample(std::floor(sampleIndex)); + bool hasPost = person.hasSample(std::ceil(sampleIndex)); if(!hasPre && !hasPost) { return; - }else if(!hasPre) + } + else if(!hasPre) { debout << "Start of XSens recording reached for file '" << person.getFilename() << "'" << std::endl; return; - }else if(!hasPost) + } + else if(!hasPost) { debout << "End of XSens recording reached for file '" << person.getFilename() << "'" << std::endl; return; } - const SkeletonTree& preSample = person.getSample(std::floor(sampleIndex)); - const SkeletonTree& postSample = person.getSample(std::ceil(sampleIndex)); - double intpart = 0.0; - double weight = modf(sampleIndex, &intpart); + const SkeletonTree &preSample = person.getSample(std::floor(sampleIndex)); + const SkeletonTree &postSample = person.getSample(std::ceil(sampleIndex)); + double intpart = 0.0; + double weight = modf(sampleIndex, &intpart); - const auto prePairs = preSample.getLines(); + const auto prePairs = preSample.getLines(); const auto postPairs = postSample.getLines(); const std::vector<SkeletonLine> interpolatedPairs = interpolate(prePairs, postPairs, weight); @@ -85,80 +90,72 @@ void MoCapController::transformPersonSkeleton(const MoCapPerson &person, double projectedPairs.reserve(prePairs.size()); SkeletonLine neckToHead; - Vec3F neckToHead3D; + Vec3F neckToHead3D; - for(const auto& pair : interpolatedPairs) + for(const auto &pair : interpolatedPairs) { - projectedPairs.emplace_back( - mExtrCalib.getImagePoint(pair.start), - mExtrCalib.getImagePoint(pair.end) - ); + projectedPairs.emplace_back(mExtrCalib.getImagePoint(pair.start), mExtrCalib.getImagePoint(pair.end)); if(pair.start_id == 1 && pair.end_id == 2) { - neckToHead = pair; + neckToHead = pair; neckToHead3D = Vec3F(pair.end - pair.start); } } - for(const auto& pair : projectedPairs) + for(const auto &pair : projectedPairs) { - renderData.push_back({ - /*.mLine =*/ QLine(pair.first.x, pair.first.y, - pair.second.x, pair.second.y), - /*.mColor =*/ mColor, - /*.mThickness =*/ mThickness, - /*.mDirected =*/ false - }); + renderData.push_back( + {/*.mLine =*/QLine(pair.first.x, pair.first.y, pair.second.x, pair.second.y), + /*.mColor =*/mColor, + /*.mThickness =*/mThickness, + /*.mDirected =*/false}); } // Head Direction Arrow - Vec3F headDir_v = preSample.getHeadDir() * (1-weight) + postSample.getHeadDir() * weight; + Vec3F headDir_v = preSample.getHeadDir() * (1 - weight) + postSample.getHeadDir() * weight; headDir_v.normalize(); cv::Point3f headDir = cv::Point3f(headDir_v.x(), headDir_v.y(), headDir_v.z()); headDir *= neckToHead3D.length(); // Start arrow at 75% the way from C7 to top of head - auto arrowBase = neckToHead.start + (neckToHead.end - neckToHead.start) * 0.75; - cv::Point2f arrowHead = mExtrCalib.getImagePoint(arrowBase + headDir); - auto arrowBase2D = mExtrCalib.getImagePoint(arrowBase); - - renderData.push_back({ - /*.mLine =*/ QLine(arrowBase2D.x, arrowBase2D.y, - arrowHead.x, arrowHead.y), - /*.mColor =*/ mColor, - /*.mThickness =*/ mThickness, - /*.mDirected =*/ true - }); + auto arrowBase = neckToHead.start + (neckToHead.end - neckToHead.start) * 0.75; + cv::Point2f arrowHead = mExtrCalib.getImagePoint(arrowBase + headDir); + auto arrowBase2D = mExtrCalib.getImagePoint(arrowBase); + + renderData.push_back( + {/*.mLine =*/QLine(arrowBase2D.x, arrowBase2D.y, arrowHead.x, arrowHead.y), + /*.mColor =*/mColor, + /*.mThickness =*/mThickness, + /*.mDirected =*/true}); } std::vector<SegmentRenderData> MoCapController::getRenderData(int currentFrame, double framerate) const { std::vector<SegmentRenderData> renderData; - for(const auto& person : mStorage.getPersons()){ + for(const auto &person : mStorage.getPersons()) + { transformPersonSkeleton(person, framerate, currentFrame, renderData); } return renderData; } -std::vector<SkeletonLine> -MoCapController::interpolate( - const std::vector<SkeletonLine>& prePairs, - const std::vector<SkeletonLine>& postPairs, - double weight - ) +std::vector<SkeletonLine> MoCapController::interpolate( + const std::vector<SkeletonLine> &prePairs, + const std::vector<SkeletonLine> &postPairs, + double weight) { // Needs: prePairs.size() == postPairs.size() // Needs: prePair and postPair be EXACTLY one sample away from each other std::vector<SkeletonLine> interpolatedPairs; interpolatedPairs.reserve(prePairs.size()); - for(size_t i = 0; i < prePairs.size(); ++i){ - interpolatedPairs.push_back({ - /*.start =*/ prePairs[i].start * (1-weight) + postPairs[i].start * weight, - /*.start_id =*/ prePairs[i].start_id, - /*.end =*/ prePairs[i].end * (1-weight) + postPairs[i].end * weight, - /*.end_id =*/ prePairs[i].end_id - }); + for(size_t i = 0; i < prePairs.size(); ++i) + { + interpolatedPairs.push_back( + {/*.start =*/prePairs[i].start * (1 - weight) + postPairs[i].start * weight, + /*.start_id =*/prePairs[i].start_id, + /*.end =*/prePairs[i].end * (1 - weight) + postPairs[i].end * weight, + /*.end_id =*/prePairs[i].end_id}); } return interpolatedPairs; } @@ -169,8 +166,10 @@ MoCapController::interpolate( * @param visibility must be a bool * @emit showMoCapChanged event when visibility is different from mShowMoCap * */ -void MoCapController::setShowMoCap(bool visibility) { - if(mShowMoCap != visibility) { +void MoCapController::setShowMoCap(bool visibility) +{ + if(mShowMoCap != visibility) + { mShowMoCap = visibility; emit showMoCapChanged(visibility); } @@ -185,10 +184,12 @@ void MoCapController::setShowMoCap(bool visibility) { * */ void MoCapController::setColor(const QColor &color) { - if(!color.isValid()){ + if(!color.isValid()) + { throw std::invalid_argument("Selected color is invalid!"); } - if(mColor != color) { + if(mColor != color) + { mColor = color; emit colorChanged(color); } @@ -203,10 +204,12 @@ void MoCapController::setColor(const QColor &color) * */ void MoCapController::setThickness(int thickness) { - if(thickness <= 0){ + if(thickness <= 0) + { throw std::invalid_argument("Thickness must be greater than 0!"); } - if(mThickness != thickness) { + if(mThickness != thickness) + { mThickness = thickness; emit thicknessChanged(thickness); } @@ -218,7 +221,8 @@ void MoCapController::setThickness(int thickness) * @emit showMoCapChanged, colorChanged, thicknessChanged * Notifies every observer manually to update the attributes * */ -void MoCapController::notifyAllObserver() { +void MoCapController::notifyAllObserver() +{ emit showMoCapChanged(mShowMoCap); emit colorChanged(mColor); emit thicknessChanged(mThickness); @@ -227,9 +231,11 @@ void MoCapController::notifyAllObserver() { /** * @return vector of MoCapPersonMetadata from the persons in mStorage */ -std::vector<MoCapPersonMetadata> MoCapController::getAllMoCapPersonMetadata() const{ +std::vector<MoCapPersonMetadata> MoCapController::getAllMoCapPersonMetadata() const +{ std::vector<MoCapPersonMetadata> metadata; - for(const MoCapPerson &person : mStorage.getPersons()){ + for(const MoCapPerson &person : mStorage.getPersons()) + { metadata.push_back(person.getMetadata()); } return metadata; @@ -242,19 +248,18 @@ std::vector<MoCapPersonMetadata> MoCapController::getAllMoCapPersonMetadata() co * This method deletes every person from the storage whose metadata does not occur in the newMetadata and calls * the IO::readMoCapC3D-method for every new Metadata. */ -void MoCapController::readMoCapFiles(const std::vector<MoCapPersonMetadata> &newMetadata){ - std::vector<MoCapPerson> &persons = mStorage.getPersons(); - auto unselected = [&](auto person){ - return std::find(newMetadata.cbegin(), newMetadata.cend(), person.getMetadata()) == newMetadata.cend(); - }; - persons.erase( - std::remove_if(persons.begin(), persons.end(), unselected), - persons.end() - ); +void MoCapController::readMoCapFiles(const std::vector<MoCapPersonMetadata> &newMetadata) +{ + std::vector<MoCapPerson> &persons = mStorage.getPersons(); + auto unselected = [&](auto person) + { return std::find(newMetadata.cbegin(), newMetadata.cend(), person.getMetadata()) == newMetadata.cend(); }; + persons.erase(std::remove_if(persons.begin(), persons.end(), unselected), persons.end()); std::vector<MoCapPersonMetadata> currentMetadata = getAllMoCapPersonMetadata(); - for(const MoCapPersonMetadata& md: newMetadata){ + for(const MoCapPersonMetadata &md : newMetadata) + { bool isNewMd = std::find(currentMetadata.cbegin(), currentMetadata.cend(), md) == currentMetadata.cend(); - if(isNewMd){ + if(isNewMd) + { IO::readMoCapC3D(mStorage, md); } } @@ -281,8 +286,8 @@ void MoCapController::setXml(QDomElement &elem) elem.setAttribute("SIZE", mThickness); elem.setAttribute("COLOR", mColor.name()); - const auto& persons = mStorage.getPersons(); - for(const auto& person : persons) + const auto &persons = mStorage.getPersons(); + for(const auto &person : persons) { person.setXml(elem); } @@ -301,17 +306,17 @@ void MoCapController::setXml(QDomElement &elem) void MoCapController::getXml(const QDomElement &elem) { // NOTE: Maybe only load the c3d-files once show is activated - if (elem.hasAttribute("SHOW")) + if(elem.hasAttribute("SHOW")) { bool isVisible = elem.attribute("SHOW").toInt(); setShowMoCap(isVisible); } - if (elem.hasAttribute("COLOR")) + if(elem.hasAttribute("COLOR")) { QColor color(elem.attribute("COLOR")); setColor(color); } - if (elem.hasAttribute("SIZE")) + if(elem.hasAttribute("SIZE")) { setThickness(elem.attribute("SIZE").toInt()); } @@ -321,18 +326,19 @@ void MoCapController::getXml(const QDomElement &elem) { for(QDomElement subElem = elem.firstChildElement(); !subElem.isNull(); subElem = subElem.nextSiblingElement()) { - if (subElem.tagName() == "PERSON") + if(subElem.tagName() == "PERSON") { MoCapPersonMetadata metadata; - bool ok; - QString path; - if (subElem.hasAttribute("FILE") && subElem.hasAttribute("SYSTEM")) + bool ok; + QString path; + if(subElem.hasAttribute("FILE") && subElem.hasAttribute("SYSTEM")) { - path = subElem.attribute("FILE"); + path = subElem.attribute("FILE"); const QString file = getExistingFile(path); - path = path.split(";").size() == 2 ? path.split(";").at(1) : "Saved path is invalid" - ""; - int system = subElem.attribute("SYSTEM").toInt(&ok); + path = path.split(";").size() == 2 ? path.split(";").at(1) : + "Saved path is invalid" + ""; + int system = subElem.attribute("SYSTEM").toInt(&ok); if(!ok) { @@ -343,35 +349,38 @@ void MoCapController::getXml(const QDomElement &elem) if(system < 0 || system >= MoCapSystem::END) { std::stringstream ss; - ss << "System index " << system << " of file " << path << " is not associated with an implemented MoCap system."; + ss << "System index " << system << " of file " << path + << " is not associated with an implemented MoCap system."; throw std::invalid_argument(ss.str()); } - metadata.setFilepath(file.toStdString(), - static_cast<MoCapSystem>(system)); + metadata.setFilepath(file.toStdString(), static_cast<MoCapSystem>(system)); } - if (subElem.hasAttribute("TIME_OFFSET")) + if(subElem.hasAttribute("TIME_OFFSET")) { metadata.setOffset(subElem.attribute("TIME_OFFSET").toDouble(&ok)); std::stringstream ss; ss << "Element TIME_OFFSET of file " << path << " does not contain a valid floating-point number!"; - if(!ok) throw std::invalid_argument(ss.str()); + if(!ok) + throw std::invalid_argument(ss.str()); } - if (subElem.hasAttribute("SAMPLE_RATE")) + if(subElem.hasAttribute("SAMPLE_RATE")) { metadata.setSamplerate(subElem.attribute("SAMPLE_RATE").toInt(&ok)); std::stringstream ss; ss << "Element SAMPLE_RATE of file " << path << " does not contain a valid integer!"; - if(!ok) throw std::invalid_argument(ss.str()); + if(!ok) + throw std::invalid_argument(ss.str()); } savedMetadata.push_back(metadata); } } readMoCapFiles(savedMetadata); - }catch(const std::exception& e) + } + catch(const std::exception &e) { std::stringstream ss; - ss <<"Problem reading the C3D-file(s): " << e.what(); + ss << "Problem reading the C3D-file(s): " << e.what(); debout << ss.str() << std::endl; QMessageBox::critical(nullptr, tr("Error"), QString::fromStdString(ss.str())); } diff --git a/src/moCapItem.cpp b/src/moCapItem.cpp index 04c9cc6b6f67ecf9b61841345e53555a4aca74bf..d86816c9c0b9497975605d489a2d28f8d30d088f 100644 --- a/src/moCapItem.cpp +++ b/src/moCapItem.cpp @@ -18,39 +18,49 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include "animation.h" #include "moCapItem.h" + +#include "animation.h" #include "moCapController.h" #include "petrack.h" - /** * @brief Constructor of moCapItem * @throws std::bad_cast when wParent is no Petrack-type or Petrack-child * */ -MoCapItem::MoCapItem(QWidget &wParent, Animation &animation, MoCapController &moCapController, QGraphicsItem *parent) - : QGraphicsItem(parent), mMainWindow(dynamic_cast<Petrack&>(wParent)), mAnimation(animation), mController(moCapController) {} +MoCapItem::MoCapItem(QWidget &wParent, Animation &animation, MoCapController &moCapController, QGraphicsItem *parent) : + QGraphicsItem(parent), + mMainWindow(dynamic_cast<Petrack &>(wParent)), + mAnimation(animation), + mController(moCapController) +{ +} QRectF MoCapItem::boundingRect() const { - if (mMainWindow.getImage()) { - return QRectF(-mMainWindow.getImageBorderSize(), -mMainWindow.getImageBorderSize(), - mMainWindow.getImage()->width(), mMainWindow.getImage()->height()); + if(mMainWindow.getImage()) + { + return QRectF( + -mMainWindow.getImageBorderSize(), + -mMainWindow.getImageBorderSize(), + mMainWindow.getImage()->width(), + mMainWindow.getImage()->height()); } return QRectF(0, 0, 0, 0); } void MoCapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option */, QWidget * /* widget */) { - if (mController.getShowMoCap()) { - std::vector<SegmentRenderData> allRenderData = mController.getRenderData( - mAnimation.getCurrentFrameNum(), - mAnimation.getOriginalFPS() - ); - for(SegmentRenderData &renderData : allRenderData) { + if(mController.getShowMoCap()) + { + std::vector<SegmentRenderData> allRenderData = + mController.getRenderData(mAnimation.getCurrentFrameNum(), mAnimation.getOriginalFPS()); + for(SegmentRenderData &renderData : allRenderData) + { drawLine(painter, renderData); - if(renderData.mDirected) { + if(renderData.mDirected) + { drawArrowHead(painter, renderData); } } @@ -62,8 +72,9 @@ void MoCapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /* opt * @param painter * @param renderData */ -void MoCapItem::drawLine(QPainter *painter, SegmentRenderData &renderData) { - QPen pen {renderData.mColor}; +void MoCapItem::drawLine(QPainter *painter, SegmentRenderData &renderData) +{ + QPen pen{renderData.mColor}; pen.setWidth(renderData.mThickness); painter->setPen(pen); painter->drawLine(renderData.mLine); @@ -76,19 +87,22 @@ void MoCapItem::drawLine(QPainter *painter, SegmentRenderData &renderData) { * @param painter * @param renderData */ -void MoCapItem::drawArrowHead(QPainter *painter, SegmentRenderData &renderData) { +void MoCapItem::drawArrowHead(QPainter *painter, SegmentRenderData &renderData) +{ QPolygonF arrowHead; - auto lineItem = QGraphicsLineItem(renderData.mLine); + auto lineItem = QGraphicsLineItem(renderData.mLine); double angle = std::atan2(-lineItem.line().dy(), lineItem.line().dx()); // angle between x-axis and line in radians - qreal arrowLength = QLineF(lineItem.line()).length() / 5; + qreal arrowLength = QLineF(lineItem.line()).length() / 5; constexpr double arrowHeadAngle = M_PI / 3; // sin(angle + arrowHeadAngle) == x-coordinate of point (e.g. unit circle) // cos(angle + arrowHeadAngle) == y-coordinate of point (e.g. unit circle) - QPointF arrowHeadRight = lineItem.line().p2() - QPointF(sin(angle + arrowHeadAngle) * arrowLength, - cos(angle + arrowHeadAngle) * arrowLength); + QPointF arrowHeadRight = + lineItem.line().p2() - + QPointF(sin(angle + arrowHeadAngle) * arrowLength, cos(angle + arrowHeadAngle) * arrowLength); // turned first position around another arrowHeadAngle - QPointF arrowHeadLeft = lineItem.line().p2() - QPointF(sin(angle + 2 * arrowHeadAngle) * arrowLength, - cos(angle + 2 * arrowHeadAngle) * arrowLength); + QPointF arrowHeadLeft = + lineItem.line().p2() - + QPointF(sin(angle + 2 * arrowHeadAngle) * arrowLength, cos(angle + 2 * arrowHeadAngle) * arrowLength); arrowHead << lineItem.line().p2() << arrowHeadRight << arrowHeadLeft; painter->drawPolygon(arrowHead); } diff --git a/src/moCapPerson.cpp b/src/moCapPerson.cpp index 4717157273e39f1811b107584a97da2e6268c609..aac5c527c0552f54342527c362415ade4bf9fb44 100644 --- a/src/moCapPerson.cpp +++ b/src/moCapPerson.cpp @@ -18,13 +18,13 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QDomElement> - -#include <exception> - #include "moCapPerson.h" + #include "helper.h" +#include <QDomElement> +#include <exception> + /** * @brief Gets index of sample at given time * @@ -46,7 +46,7 @@ void MoCapPerson::setTimeOffset(double timeOffset) mMetadata.setOffset(timeOffset); } -void MoCapPerson::addSkeleton(const SkeletonTree& skeleton) +void MoCapPerson::addSkeleton(const SkeletonTree &skeleton) { mSkeletons.push_back(skeleton); } @@ -66,13 +66,12 @@ const MoCapPersonMetadata &MoCapPerson::getMetadata() const return mMetadata; } -void MoCapPerson::setMetadata(const MoCapPersonMetadata& metadata) +void MoCapPerson::setMetadata(const MoCapPersonMetadata &metadata) { mMetadata = metadata; } - void MoCapPerson::setXml(QDomElement &elem) const { QDomElement subElem; diff --git a/src/moCapPersonMetadata.cpp b/src/moCapPersonMetadata.cpp index 4f39261009c189f2d58fe7a83beb5fb3aa72adf5..0434c6559f666727cb3739bf02dd1aa3ba802c9e 100644 --- a/src/moCapPersonMetadata.cpp +++ b/src/moCapPersonMetadata.cpp @@ -17,15 +17,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QFileInfo> #include "moCapPersonMetadata.h" -MoCapPersonMetadata::MoCapPersonMetadata(std::string filepath, MoCapSystem system, double samplerate, double offset){ +#include <QFileInfo> + +MoCapPersonMetadata::MoCapPersonMetadata(std::string filepath, MoCapSystem system, double samplerate, double offset) +{ setMetadata(filepath, system, samplerate, offset); } -void MoCapPersonMetadata::setMetadata(const std::string &filepath, MoCapSystem system, double samplerate, double offset){ +void MoCapPersonMetadata::setMetadata(const std::string &filepath, MoCapSystem system, double samplerate, double offset) +{ setSamplerate(samplerate); setOffset(offset); setFilepath(filepath, system); @@ -35,22 +38,25 @@ void MoCapPersonMetadata::setMetadata(const std::string &filepath, MoCapSystem s * * @param filename: valid path with (e.g.'.c3d') extension @throws std::ios_base::failure */ -void MoCapPersonMetadata::setFilepath(const std::string &filepath, MoCapSystem system){ - const std::string& extension = moCapFileExtensions.at(system); - QFileInfo info(QString::fromStdString(filepath)); - if (!info.exists()){ +void MoCapPersonMetadata::setFilepath(const std::string &filepath, MoCapSystem system) +{ + const std::string &extension = moCapFileExtensions.at(system); + QFileInfo info(QString::fromStdString(filepath)); + if(!info.exists()) + { std::stringstream msg; - msg << "Invalid Filename '" << filepath << "': does not exist!\n"; + msg << "Invalid Filename '" << filepath << "': does not exist!\n"; throw std::ios_base::failure(msg.str()); } QString suffix = info.suffix(); - if(suffix.toStdString() != extension){ + if(suffix.toStdString() != extension) + { std::stringstream msg; - msg << "Invalid Filename '" << filepath << "': It has no " << extension << " extension!\n"; + msg << "Invalid Filename '" << filepath << "': It has no " << extension << " extension!\n"; throw std::ios_base::failure(msg.str()); } mFilepath = filepath; - mSystem = system; + mSystem = system; } /** @@ -58,39 +64,46 @@ void MoCapPersonMetadata::setFilepath(const std::string &filepath, MoCapSystem s */ void MoCapPersonMetadata::setSamplerate(double samplerate) { - if(samplerate <= 0){ + if(samplerate <= 0) + { throw std::invalid_argument("Samplerate cannot be negative or zero!"); } mSamplerate = samplerate; } -void MoCapPersonMetadata::setOffset(double offset) { +void MoCapPersonMetadata::setOffset(double offset) +{ mOffset = offset; } -const std::string &MoCapPersonMetadata::getFilepath() const { +const std::string &MoCapPersonMetadata::getFilepath() const +{ return mFilepath; } -MoCapSystem MoCapPersonMetadata::getSystem() const { +MoCapSystem MoCapPersonMetadata::getSystem() const +{ return mSystem; } -double MoCapPersonMetadata::getSamplerate() const { +double MoCapPersonMetadata::getSamplerate() const +{ return mSamplerate; } -double MoCapPersonMetadata::getOffset() const { +double MoCapPersonMetadata::getOffset() const +{ return mOffset; } -bool operator==(const MoCapPersonMetadata &lhs, const MoCapPersonMetadata &rhs){ - return (lhs.getFilepath().compare(rhs.getFilepath()) == 0 - && std::abs(lhs.getOffset() - rhs.getOffset()) < 1e-4 - && std::abs(lhs.getSamplerate() - rhs.getSamplerate()) < 1e-4 - && lhs.getSystem() == rhs.getSystem()); +bool operator==(const MoCapPersonMetadata &lhs, const MoCapPersonMetadata &rhs) +{ + return ( + lhs.getFilepath().compare(rhs.getFilepath()) == 0 && std::abs(lhs.getOffset() - rhs.getOffset()) < 1e-4 && + std::abs(lhs.getSamplerate() - rhs.getSamplerate()) < 1e-4 && lhs.getSystem() == rhs.getSystem()); } -bool operator!=(const MoCapPersonMetadata &lhs, const MoCapPersonMetadata &rhs){ - return !(lhs==rhs); +bool operator!=(const MoCapPersonMetadata &lhs, const MoCapPersonMetadata &rhs) +{ + return !(lhs == rhs); } diff --git a/src/moCapSelectionWidget.cpp b/src/moCapSelectionWidget.cpp index d216f82f0b1d7b050c461c2221c3fda33bbfe765..e35b043be920efe6292f89ede35957121c5ab1c0 100644 --- a/src/moCapSelectionWidget.cpp +++ b/src/moCapSelectionWidget.cpp @@ -1,18 +1,17 @@ -#include <QFileDialog> - #include "moCapSelectionWidget.h" -#include "ui_moCapSelectionWidget.h" + #include "openMoCapDialog.h" +#include "ui_moCapSelectionWidget.h" + +#include <QFileDialog> -MoCapSelectionWidget::MoCapSelectionWidget(QWidget *parent, const QMap<QString, MoCapSystem>& moCapSystems) : - QWidget(parent), - mUi(new Ui::MoCapSelectionWidget), - mMoCapSystems(moCapSystems) +MoCapSelectionWidget::MoCapSelectionWidget(QWidget *parent, const QMap<QString, MoCapSystem> &moCapSystems) : + QWidget(parent), mUi(new Ui::MoCapSelectionWidget), mMoCapSystems(moCapSystems) { mUi->setupUi(this); - constexpr int defaultSampleRate = 60; - constexpr double offsetRange = 5; + constexpr int defaultSampleRate = 60; + constexpr double offsetRange = 5; mUi->btnDelete->setIcon(QApplication::style()->standardIcon(QStyle::SP_TrashIcon)); mUi->cbInputSystem->addItems(QStringList(moCapSystems.keys())); @@ -32,11 +31,15 @@ MoCapSelectionWidget::MoCapSelectionWidget(QWidget *parent, const QMap<QString, * @param moCapSystems Map from QString in Combobox to MoCapSystem-Enum * @param metadata Metadata which should be represented by this widget */ -MoCapSelectionWidget::MoCapSelectionWidget(QWidget *parent, const QMap<QString, MoCapSystem> &moCapSystems, const MoCapPersonMetadata &metadata) : +MoCapSelectionWidget::MoCapSelectionWidget( + QWidget * parent, + const QMap<QString, MoCapSystem> &moCapSystems, + const MoCapPersonMetadata & metadata) : MoCapSelectionWidget(parent, moCapSystems) { auto usedMoCapSystem = std::find(moCapSystems.begin(), moCapSystems.end(), metadata.getSystem()); - if(usedMoCapSystem != moCapSystems.end()){ + if(usedMoCapSystem != moCapSystems.end()) + { mUi->cbInputSystem->setCurrentText(usedMoCapSystem.key()); } mUi->sampleRateSpinBox->setValue(metadata.getSamplerate()); @@ -55,15 +58,17 @@ MoCapSelectionWidget::MoCapSelectionWidget(QWidget *parent, const QMap<QString, * * This method is called by a Signal('browse File'-Button). */ -void MoCapSelectionWidget::setFileName(){ +void MoCapSelectionWidget::setFileName() +{ std::stringstream extensionsString; extensionsString << "All MoCap File Types ("; - for(const auto &extension: moCapFileExtensions){ + for(const auto &extension : moCapFileExtensions) + { extensionsString << " *." << extension.second; } extensionsString << ")"; - QString filename = QFileDialog::getOpenFileName(this, tr("Open C3D File"), QDir::currentPath(), - QString::fromStdString(extensionsString.str())); + QString filename = QFileDialog::getOpenFileName( + this, tr("Open C3D File"), QDir::currentPath(), QString::fromStdString(extensionsString.str())); mUi->filePathLabel->clear(); mUi->filePathLabel->setText(filename); mFilledOut = !filename.isEmpty(); @@ -78,10 +83,11 @@ void MoCapSelectionWidget::setFileName(){ */ MoCapPersonMetadata MoCapSelectionWidget::getMetadata() const { - return MoCapPersonMetadata(mUi->filePathLabel->text().toStdString(), - mMoCapSystems[mUi->cbInputSystem->currentText()], - mUi->sampleRateSpinBox->value(), - mUi->offSetSpinBox->value()); + return MoCapPersonMetadata( + mUi->filePathLabel->text().toStdString(), + mMoCapSystems[mUi->cbInputSystem->currentText()], + mUi->sampleRateSpinBox->value(), + mUi->offSetSpinBox->value()); } bool MoCapSelectionWidget::isFilledOut() const diff --git a/src/multiColorMarkerItem.cpp b/src/multiColorMarkerItem.cpp index d2dda2bf373b242558f1af50b7d20f4ade387e13..cd7f4226033d72b95861321badb14ff4779344b6 100644 --- a/src/multiColorMarkerItem.cpp +++ b/src/multiColorMarkerItem.cpp @@ -18,24 +18,24 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> - -#include "petrack.h" -#include "view.h" #include "multiColorMarkerItem.h" + +#include "animation.h" #include "multiColorMarkerWidget.h" +#include "petrack.h" #include "tracker.h" -#include "animation.h" +#include "view.h" + +#include <QtWidgets> // in x und y gleichermassen skaliertes koordinatensystem, // da von einer vorherigen intrinsischen kamerakalibrierung ausgegenagen wird, -// so dass pixel quadratisch -MultiColorMarkerItem::MultiColorMarkerItem(QWidget *wParent, QGraphicsItem * parent) - : QGraphicsItem(parent) +// so dass pixel quadratisch +MultiColorMarkerItem::MultiColorMarkerItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) { - mMainWindow = (class Petrack*) wParent; - mImage = nullptr; + mMainWindow = (class Petrack *) wParent; + mImage = nullptr; } /** @@ -48,40 +48,44 @@ MultiColorMarkerItem::MultiColorMarkerItem(QWidget *wParent, QGraphicsItem * par */ QRectF MultiColorMarkerItem::boundingRect() const { - if (mMainWindow->getImage()) - return QRectF(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), mMainWindow->getImage()->width(), mMainWindow->getImage()->height()); + if(mMainWindow->getImage()) + return QRectF( + -mMainWindow->getImageBorderSize(), + -mMainWindow->getImageBorderSize(), + mMainWindow->getImage()->width(), + mMainWindow->getImage()->height()); else return QRectF(0, 0, 0, 0); } -void MultiColorMarkerItem::setRect(Vec2F& v) +void MultiColorMarkerItem::setRect(Vec2F &v) { mUlc = v; // upper left corner to draw } -void MultiColorMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) +void MultiColorMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - if (!mMask.empty()) + if(!mMask.empty()) { - if ((mImage != nullptr) && ((mImage->width() != mMask.cols) || (mImage->height() != mMask.rows))) + if((mImage != nullptr) && ((mImage->width() != mMask.cols) || (mImage->height() != mMask.rows))) { - delete mImage; // delete null pointer is ok + delete mImage; // delete null pointer is ok mImage = nullptr; // is not been done by delete } - if (mImage == nullptr) // zu Beginn oder wenn sich die Groesse aendert + if(mImage == nullptr) // zu Beginn oder wenn sich die Groesse aendert mImage = new QImage(mMask.cols, mMask.rows, QImage::Format_ARGB32); - int x,y; - auto* data = mMask.data; - auto* yData = data; - int notMaskMask = ((int) !mMainWindow->getMultiColorMarkerWidget()->maskMask->isChecked())*255; // 255 oder 0 + int x, y; + auto *data = mMask.data; + auto *yData = data; + int notMaskMask = ((int) !mMainWindow->getMultiColorMarkerWidget()->maskMask->isChecked()) * 255; // 255 oder 0 - for (y = 0; y < mMask.rows; y++) + for(y = 0; y < mMask.rows; y++) { // Pointer to the data information in the QImage for just one column // set pointer to value before, because ++p is faster than p++ - auto* p = mImage->scanLine(y)-1; - for (x = 0; x < mMask.cols; x++) + auto *p = mImage->scanLine(y) - 1; + for(x = 0; x < mMask.cols; x++) { *(++p) = *data; *(++p) = *data; @@ -89,11 +93,10 @@ void MultiColorMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsIt *(++p) = *data ? notMaskMask : 255; ++data; } - data = (yData += mMask.cols/sizeof(char)); // because sometimes widthStep != width + data = (yData += mMask.cols / sizeof(char)); // because sometimes widthStep != width } - painter->setOpacity(mMainWindow->getMultiColorMarkerWidget()->opacity->value()/100.); - painter->drawImage(mUlc.x(),mUlc.y(), *mImage); - + painter->setOpacity(mMainWindow->getMultiColorMarkerWidget()->opacity->value() / 100.); + painter->drawImage(mUlc.x(), mUlc.y(), *mImage); } } @@ -106,9 +109,9 @@ void MultiColorMarkerItem::setMask(cv::Mat &mask) // original width w and height h must be given cv::Mat MultiColorMarkerItem::createMask(int w, int h) { - if (w>0 && h>0 && (mMask.empty() || (!mMask.empty() && (w != mMask.cols || h != mMask.rows)))) + if(w > 0 && h > 0 && (mMask.empty() || (!mMask.empty() && (w != mMask.cols || h != mMask.rows)))) { - mMask.create(h,w,CV_8UC1); + mMask.create(h, w, CV_8UC1); } return mMask; } diff --git a/src/multiColorMarkerWidget.cpp b/src/multiColorMarkerWidget.cpp index 44874e78e6941418c4f82f9a65f4a318ca11cb53..06a1afebc45a60f2dd2a0d8928fe679053ab9fe2 100644 --- a/src/multiColorMarkerWidget.cpp +++ b/src/multiColorMarkerWidget.cpp @@ -20,10 +20,9 @@ #include "multiColorMarkerWidget.h" -MultiColorMarkerWidget::MultiColorMarkerWidget(QWidget *parent) - : QWidget(parent) +MultiColorMarkerWidget::MultiColorMarkerWidget(QWidget *parent) : QWidget(parent) { - mMainWindow = (class Petrack*) parent; + mMainWindow = (class Petrack *) parent; setupUi(this); mOldMinArea = minArea->value(); mOldMaxArea = maxArea->value(); @@ -73,63 +72,67 @@ void MultiColorMarkerWidget::setXml(QDomElement &elem) void MultiColorMarkerWidget::getXml(QDomElement &elem) { QDomElement subElem; - QString styleString; + QString styleString; for(subElem = elem.firstChildElement(); !subElem.isNull(); subElem = subElem.nextSiblingElement()) { - if (subElem.tagName() == "MASK") + if(subElem.tagName() == "MASK") { - if (subElem.hasAttribute("SHOW")) + if(subElem.hasAttribute("SHOW")) showMask->setCheckState(subElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("OPACITY")) + if(subElem.hasAttribute("OPACITY")) opacity->setValue(subElem.attribute("OPACITY").toInt()); - if (subElem.hasAttribute("MASK")) + if(subElem.hasAttribute("MASK")) maskMask->setCheckState(subElem.attribute("MASK").toInt() ? Qt::Checked : Qt::Unchecked); } - if (subElem.tagName() == "BLACK_DOT") + if(subElem.tagName() == "BLACK_DOT") { - if (subElem.hasAttribute("USE")) + if(subElem.hasAttribute("USE")) useDot->setCheckState(subElem.attribute("USE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("SIZE")) + if(subElem.hasAttribute("SIZE")) dotSize->setValue(subElem.attribute("SIZE").toDouble()); - if (subElem.hasAttribute("IGNORE_WITHOUT")) - ignoreWithoutDot->setCheckState(subElem.attribute("IGNORE_WITHOUT").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("USE_COLOR")) + if(subElem.hasAttribute("IGNORE_WITHOUT")) + ignoreWithoutDot->setCheckState( + subElem.attribute("IGNORE_WITHOUT").toInt() ? Qt::Checked : Qt::Unchecked); + if(subElem.hasAttribute("USE_COLOR")) useColor->setCheckState(subElem.attribute("USE_COLOR").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("RESTRICT_POSITION")) - restrictPosition->setCheckState(subElem.attribute("RESTRICT_POSITION").toInt() ? Qt::Checked : Qt::Unchecked); + if(subElem.hasAttribute("RESTRICT_POSITION")) + restrictPosition->setCheckState( + subElem.attribute("RESTRICT_POSITION").toInt() ? Qt::Checked : Qt::Unchecked); } - if (subElem.tagName() == "CODE_MARKER") + if(subElem.tagName() == "CODE_MARKER") { - if (subElem.hasAttribute("USE")) + if(subElem.hasAttribute("USE")) useCodeMarker->setCheckState(subElem.attribute("USE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("IGNORE_WITHOUT")) - ignoreWithoutDot->setCheckState(subElem.attribute("IGNORE_WITHOUT").toInt() ? Qt::Checked : Qt::Unchecked); + if(subElem.hasAttribute("IGNORE_WITHOUT")) + ignoreWithoutDot->setCheckState( + subElem.attribute("IGNORE_WITHOUT").toInt() ? Qt::Checked : Qt::Unchecked); } - if (subElem.tagName() == "AUTO_CORRECT") + if(subElem.tagName() == "AUTO_CORRECT") { - if (subElem.hasAttribute("USE")) + if(subElem.hasAttribute("USE")) autoCorrect->setCheckState(subElem.attribute("USE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("ONLY_EXPORT")) - autoCorrectOnlyExport->setCheckState(subElem.attribute("ONLY_EXPORT").toInt() ? Qt::Checked : Qt::Unchecked); + if(subElem.hasAttribute("ONLY_EXPORT")) + autoCorrectOnlyExport->setCheckState( + subElem.attribute("ONLY_EXPORT").toInt() ? Qt::Checked : Qt::Unchecked); } - if (subElem.tagName() == "PARAM") + if(subElem.tagName() == "PARAM") { - if (subElem.hasAttribute("CLOSE_RADIUS")) + if(subElem.hasAttribute("CLOSE_RADIUS")) closeRadius->setValue(subElem.attribute("CLOSE_RADIUS").toInt()); - if (subElem.hasAttribute("CLOSE_USED")) + if(subElem.hasAttribute("CLOSE_USED")) useClose->setCheckState(subElem.attribute("CLOSE_USED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("OPEN_RADIUS")) + if(subElem.hasAttribute("OPEN_RADIUS")) openRadius->setValue(subElem.attribute("OPEN_RADIUS").toInt()); - if (subElem.hasAttribute("OPEN_USED")) + if(subElem.hasAttribute("OPEN_USED")) useOpen->setCheckState(subElem.attribute("OPEN_USED").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("MIN_AREA")) + if(subElem.hasAttribute("MIN_AREA")) minArea->setValue(subElem.attribute("MIN_AREA").toInt()); - if (subElem.hasAttribute("MAX_AREA")) + if(subElem.hasAttribute("MAX_AREA")) maxArea->setValue(subElem.attribute("MAX_AREA").toInt()); - if (subElem.hasAttribute("USE_HEAD_SIZE")) + if(subElem.hasAttribute("USE_HEAD_SIZE")) useHeadSize->setCheckState(subElem.attribute("USE_HEAD_SIZE").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("MAX_RATIO")) + if(subElem.hasAttribute("MAX_RATIO")) maxRatio->setValue(subElem.attribute("MAX_RATIO").toDouble()); } } diff --git a/src/openMoCapDialog.cpp b/src/openMoCapDialog.cpp index 96e6d5a283fda128206a7501aa9cd194b29c48fa..75620b484f39b88906fdb9a07f44633cbbfa8631 100644 --- a/src/openMoCapDialog.cpp +++ b/src/openMoCapDialog.cpp @@ -17,31 +17,28 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QFileDialog> +#include "openMoCapDialog.h" #include "analysePlot.h" -#include "openMoCapDialog.h" -#include "ui_openMoCapDialog.h" #include "moCapPersonMetadata.h" - #include "moCapSelectionWidget.h" +#include "ui_openMoCapDialog.h" + +#include <QFileDialog> OpenMoCapDialog::OpenMoCapDialog(QWidget *parent, MoCapController &controller) : - QDialog(parent), - mUi(new Ui::OpenMoCapDialog), - mController(controller), - mParent(parent) + QDialog(parent), mUi(new Ui::OpenMoCapDialog), mController(controller), mParent(parent) { mUi->setupUi(this); - mMoCapSystems = QMap<QString, MoCapSystem>(); setWindowFlags(windowFlags().setFlag(Qt::WindowContextHelpButtonHint, false)); mMoCapSystems.insert("XSensC3D", MoCapSystem::XSensC3D); const auto loadedMetadata = mController.getAllMoCapPersonMetadata(); - for(const auto& metadata : loadedMetadata){ + for(const auto &metadata : loadedMetadata) + { mUi->moCapSelections->layout()->addWidget(new MoCapSelectionWidget(this, mMoCapSystems, metadata)); } @@ -50,28 +47,32 @@ OpenMoCapDialog::OpenMoCapDialog(QWidget *parent, MoCapController &controller) : } - /** * @brief Sets FileAttributes of MoCapController and calls readMoCapFile * * This method is called by a Signal(Ok-Button) and closes the window if no errors occur. */ -void OpenMoCapDialog::clickedOk() { - bool allDataIsValid = true; +void OpenMoCapDialog::clickedOk() +{ + bool allDataIsValid = true; std::vector<MoCapPersonMetadata> metadata; for(int i = 0; i < mUi->moCapSelections->layout()->count(); ++i) { - auto selectionWidget = dynamic_cast<const MoCapSelectionWidget*>(mUi->moCapSelections->layout()->itemAt(i)->widget()); + auto selectionWidget = + dynamic_cast<const MoCapSelectionWidget *>(mUi->moCapSelections->layout()->itemAt(i)->widget()); if(selectionWidget == nullptr || !selectionWidget->isFilledOut()) { continue; } - try{ + try + { MoCapPersonMetadata currentMetadata = selectionWidget->getMetadata(); metadata.push_back(currentMetadata); - }catch(std::exception &e){ + } + catch(std::exception &e) + { allDataIsValid = false; std::stringstream errormsg; errormsg << e.what() << "\n"; @@ -82,10 +83,13 @@ void OpenMoCapDialog::clickedOk() { if(allDataIsValid) { - try { + try + { mController.readMoCapFiles(metadata); this->close(); - } catch (std::exception &e) { + } + catch(std::exception &e) + { std::stringstream errormsg; errormsg << e.what() << "\n"; QMessageBox::critical(mParent, "PeTrack", QString::fromStdString(errormsg.str())); @@ -103,4 +107,3 @@ void OpenMoCapDialog::on_btnAddSelection_clicked() { mUi->moCapSelections->layout()->addWidget(new MoCapSelectionWidget(this, mMoCapSystems)); } - diff --git a/src/pMessageBox.cpp b/src/pMessageBox.cpp index b1e01c7595c712c2c8571a52798b6b2a26f4a636..a875ebc7f6499de20a3dc80f3e37491f4606b227 100644 --- a/src/pMessageBox.cpp +++ b/src/pMessageBox.cpp @@ -20,16 +20,16 @@ #include "pMessageBox.h" +#include "helper.h" + +#include <QApplication> +#include <QDialogButtonBox> #include <QGridLayout> #include <QLabel> -#include <QStyle> -#include <QDialogButtonBox> #include <QPushButton> -#include <QApplication> +#include <QStyle> #include <QTextDocument> -#include "helper.h" - /** * @brief Constructs a PMessageBox * @@ -41,12 +41,22 @@ * @param buttons buttons for the user to click default: only Ok) * @param defaultButton button used when pressing enter */ -PMessageBox::PMessageBox(QWidget *parent, const QString& title, const QString& msg, const QIcon& icon, const QString& informativeText, StandardButtons buttons, StandardButton defaultButton) : QDialog(parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) +PMessageBox::PMessageBox( + QWidget * parent, + const QString & title, + const QString & msg, + const QIcon & icon, + const QString & informativeText, + StandardButtons buttons, + StandardButton defaultButton) : + QDialog( + parent, + Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) { - QGridLayout* layout = new QGridLayout(); + QGridLayout *layout = new QGridLayout(); setLayout(layout); - QFont f = QApplication::font("QMessageBox"); + QFont f = QApplication::font("QMessageBox"); Qt::TextInteractionFlags flags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, nullptr, this)); QLabel *detailedText = new QLabel(this); @@ -59,41 +69,52 @@ PMessageBox::PMessageBox(QWidget *parent, const QString& title, const QString& m layout->addWidget(detailedText, 1, 1); } - QLabel* text = new QLabel(this); + QLabel *text = new QLabel(this); text->setWordWrap(true); text->setTextInteractionFlags(flags); text->setFont(f); text->setText(msg); - layout->addWidget(text, 0,1); + layout->addWidget(text, 0, 1); setWindowTitle(title); - QLabel* infoIcon = new QLabel(this); - int iconSize = style()->pixelMetric(QStyle::PM_MessageBoxIconSize, nullptr, this); + QLabel *infoIcon = new QLabel(this); + int iconSize = style()->pixelMetric(QStyle::PM_MessageBoxIconSize, nullptr, this); infoIcon->setPixmap(icon.pixmap(iconSize, iconSize)); layout->addWidget(infoIcon, 0, 0); QDialogButtonBox *buttonBox = new QDialogButtonBox(buttons, this); layout->addWidget(buttonBox, 2, 1); - if(defaultButton != StandardButton::NoButton){ + if(defaultButton != StandardButton::NoButton) + { QPushButton *def = buttonBox->button(defaultButton); - if(def){ + if(def) + { def->setAutoDefault(false); def->setDefault(true); - }else{ + } + else + { debout << "Warning: Given default button does is non-specified button" << std::endl; } - } // return the clicked button; -1 if none was clicked - connect(buttonBox, &QDialogButtonBox::clicked, this, [=](QAbstractButton *button){ - int ret = buttonBox->standardButton(button); - if(ret == StandardButton::NoButton){ - this->done(-1); - }else{ - this->done(ret); - } - }); + connect( + buttonBox, + &QDialogButtonBox::clicked, + this, + [=](QAbstractButton *button) + { + int ret = buttonBox->standardButton(button); + if(ret == StandardButton::NoButton) + { + this->done(-1); + } + else + { + this->done(ret); + } + }); layout->setSpacing(20); @@ -118,13 +139,15 @@ PMessageBox::PMessageBox(QWidget *parent, const QString& title, const QString& m * @param defaultButton button to press, when pressing enter * @return clicked button */ -int PMessageBox::information(const char*file, - const char*func, - int line, QWidget *parent, - const QString &title, - const QString &text, - PMessageBox::StandardButtons buttons, - PMessageBox::StandardButton defaultButton) +int PMessageBox::information( + const char * file, + const char * func, + int line, + QWidget * parent, + const QString & title, + const QString & text, + PMessageBox::StandardButtons buttons, + PMessageBox::StandardButton defaultButton) { std::cout << func << " in " << file_name(file) << " line " << line << ": Info: " << text << std::endl; @@ -135,16 +158,14 @@ int PMessageBox::information(const char*file, if(buttons & (~StandardButton::Ok)) { throw std::runtime_error( - QString("user-interaction demanded during offscreen mode with message\n%1") - .arg(text).toStdString() - ); + QString("user-interaction demanded during offscreen mode with message\n%1").arg(text).toStdString()); } return StandardButton::NoButton; } - QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); - PMessageBox msg = PMessageBox(parent, title, text, icon, QString(), buttons, defaultButton); + QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); + PMessageBox msg = PMessageBox(parent, title, text, icon, QString(), buttons, defaultButton); return msg.exec(); } @@ -163,14 +184,15 @@ int PMessageBox::information(const char*file, * @param defaultButton button to press, when pressing enter * @return clicked button */ -int PMessageBox::warning(const char* file, - const char* func, - int line, - QWidget *parent, - const QString &title, - const QString &text, - PMessageBox::StandardButtons buttons, - PMessageBox::StandardButton defaultButton) +int PMessageBox::warning( + const char * file, + const char * func, + int line, + QWidget * parent, + const QString & title, + const QString & text, + PMessageBox::StandardButtons buttons, + PMessageBox::StandardButton defaultButton) { std::cout << func << " in " << file_name(file) << " line " << line << ": Warning: " << text << std::endl; @@ -181,16 +203,14 @@ int PMessageBox::warning(const char* file, if(buttons & (~StandardButton::Ok)) { throw std::runtime_error( - QString("user-interaction demanded during offscreen mode with message\n%1") - .arg(text).toStdString() - ); + QString("user-interaction demanded during offscreen mode with message\n%1").arg(text).toStdString()); } return StandardButton::NoButton; } - QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning); - PMessageBox msg = PMessageBox(parent, title, text, icon, QString(), buttons, defaultButton); + QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning); + PMessageBox msg = PMessageBox(parent, title, text, icon, QString(), buttons, defaultButton); return msg.exec(); } @@ -209,14 +229,15 @@ int PMessageBox::warning(const char* file, * @param defaultButton button to press, when pressing enter * @return clicked button */ -int PMessageBox::critical(const char*file, - const char*func, - int line, - QWidget *parent, - const QString &title, - const QString &text, - PMessageBox::StandardButtons buttons, - PMessageBox::StandardButton defaultButton) +int PMessageBox::critical( + const char * file, + const char * func, + int line, + QWidget * parent, + const QString & title, + const QString & text, + PMessageBox::StandardButtons buttons, + PMessageBox::StandardButton defaultButton) { std::cout << func << " in " << file_name(file) << " line " << line << ": Critical: " << text << std::endl; @@ -227,16 +248,14 @@ int PMessageBox::critical(const char*file, if(buttons & (~StandardButton::Ok)) { throw std::runtime_error( - QString("user-interaction demanded during offscreen mode with message\n%1") - .arg(text).toStdString() - ); + QString("user-interaction demanded during offscreen mode with message\n%1").arg(text).toStdString()); } return StandardButton::NoButton; } - QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); - PMessageBox msg = PMessageBox(parent, title, text, icon, QString(), buttons, defaultButton); + QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); + PMessageBox msg = PMessageBox(parent, title, text, icon, QString(), buttons, defaultButton); return msg.exec(); } @@ -255,25 +274,24 @@ int PMessageBox::critical(const char*file, * @param defaultButton button to press, when pressing enter * @return clicked button */ -int PMessageBox::question(const char* /*file*/, - const char* /*func*/, - int /*line*/, - QWidget *parent, - const QString &title, - const QString &text, - PMessageBox::StandardButtons buttons, - PMessageBox::StandardButton defaultButton) +int PMessageBox::question( + const char * /*file*/, + const char * /*func*/, + int /*line*/, + QWidget * parent, + const QString & title, + const QString & text, + PMessageBox::StandardButtons buttons, + PMessageBox::StandardButton defaultButton) { - QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion); - PMessageBox msg = PMessageBox(parent, title, text, icon, QString(), buttons, defaultButton); + QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion); + PMessageBox msg = PMessageBox(parent, title, text, icon, QString(), buttons, defaultButton); // no debout, since question **demands** user interaction; also no support for scripting to come if(QGuiApplication::platformName() == "offscreen") { throw std::runtime_error( - QString("user-interaction demanded during offscreen mode with message\n%1") - .arg(text).toStdString() - ); + QString("user-interaction demanded during offscreen mode with message\n%1").arg(text).toStdString()); } return msg.exec(); @@ -282,13 +300,16 @@ int PMessageBox::question(const char* /*file*/, void PMessageBox::setMinimumWidth(QLabel *textLabel) { QTextDocument doc; - if(Qt::mightBeRichText(textLabel->text())){ + if(Qt::mightBeRichText(textLabel->text())) + { doc.setHtml(textLabel->text()); - }else{ + } + else + { doc.setPlainText(textLabel->text()); } doc.setDefaultFont(textLabel->font()); - doc.setTextWidth(textLabel->fontMetrics().averageCharWidth()*120); + doc.setTextWidth(textLabel->fontMetrics().averageCharWidth() * 120); textLabel->setMinimumWidth(static_cast<int>(doc.idealWidth())); } diff --git a/src/person.cpp b/src/person.cpp index 49d0a53375ee96a9dd1d4901e929dd64b4d65b8e..0d2d8b9ad5ce6c2400e149f80848bbeb4a28e3d3 100644 --- a/src/person.cpp +++ b/src/person.cpp @@ -19,15 +19,16 @@ */ #include "person.h" + #include "helper.h" //#define SHOWELLIPSES // gibt die einzelnen schritte der personen detektion pyramide graphisch aus //#define SAVEELLIPSES // ob alle ellips in datei geschrieben werden sollen //#define PRINT_ERASE_REASON // zeigt an, ob ausgegeben werden soll, aus welchem Grund eine ellipse geloescht wurde -//#define SAVE_IMG_DETECTION_STEPS // setzen, wenn die gezeigten Bilder (SHOWELLIPSES) auch als Bildsequenz weggeschrieben werden soll -//#define SAVE_IMG_FILEBASE "D:/diss/personModel/ownPerson/petrack/density/d4.5_" +//#define SAVE_IMG_DETECTION_STEPS // setzen, wenn die gezeigten Bilder (SHOWELLIPSES) auch als Bildsequenz +// weggeschrieben werden soll #define SAVE_IMG_FILEBASE "D:/diss/personModel/ownPerson/petrack/density/d4.5_" -using namespace::cv; +using namespace ::cv; PersonList::PersonList() { @@ -36,23 +37,23 @@ PersonList::PersonList() #ifndef STEREO_DISABLED // searching for ellipses from isolines in a height field -void PersonList::searchEllipses(pet::StereoContext *sc, QRect &roi, BackgroundFilter* bgFilter) +void PersonList::searchEllipses(pet::StereoContext *sc, QRect &roi, BackgroundFilter *bgFilter) { mSc = sc; - Mat pointCloud = cvarrToMat(mSc->getPointCloud()).clone(); - IplImage *disp = mSc->getDisparity(); - CvSize imgSize; + Mat pointCloud = cvarrToMat(mSc->getPointCloud()).clone(); + IplImage *disp = mSc->getDisparity(); + CvSize imgSize; imgSize.width = disp->width; imgSize.height = disp->height; #ifdef TIME_MEASUREMENT // "==========: " - debout << "go mkless : " << getElapsedTime() <<endl; + debout << "go mkless : " << getElapsedTime() << endl; #endif - int x, y; - float *pcData , *yPcData; + int x, y; + float *pcData, *yPcData; // nicht Fordergrund auf ungueltig -1 setzen bgFilter->maskBg(pointCloud, -1.); @@ -60,293 +61,326 @@ void PersonList::searchEllipses(pet::StereoContext *sc, QRect &roi, BackgroundFi // Bestimmung von Minimum und Maximum von z in Meter float min = FLT_MAX; float max = FLT_MIN; - pcData = (float *) pointCloud.data; - yPcData = pcData; + pcData = (float *) pointCloud.data; + yPcData = pcData; - for (y = 0; y < pointCloud.rows; ++y) + for(y = 0; y < pointCloud.rows; ++y) { - for (x = 0; x < pointCloud.cols; ++x) + for(x = 0; x < pointCloud.cols; ++x) { - if (pcData[2] != -1) + if(pcData[2] != -1) { - if (pcData[2] > max) + if(pcData[2] > max) max = pcData[2]; - else if (pcData[2] < min) + else if(pcData[2] < min) min = pcData[2]; } - pcData+=3; + pcData += 3; } - pcData = (yPcData += pointCloud.cols/sizeof(float)); + pcData = (yPcData += pointCloud.cols / sizeof(float)); } // pcData, min, max sind in Meter !!!!!!!! - if (min>=max) + if(min >= max) { -// cvReleaseMat(&pointCloud); + // cvReleaseMat(&pointCloud); return; } - //debout << "Minimal distance to camera in foreground: " << min*100 << "cm" <<endl; - //debout << "Maximal distance to camera in foreground: " << max*100 << "cm" <<endl; - if (max-min < 1) - debout << "Warning: hight field difference is smaller 1m!" <<endl; -// debout << sc->getCmPerPixel(min) <<endl; -// debout << sc->getCmPerPixel(max) <<endl; -// debout << sc->getZfromDisp(sc->getMin()) <<endl; -// debout << sc->getZfromDisp(sc->getMax()) <<endl; - float l1 = 4.2/mSc->getCmPerPixel(min); - float l2 = 67./mSc->getCmPerPixel(max); -// debout << l1*l1 <<endl; -// debout << l2*l2 <<endl; + // debout << "Minimal distance to camera in foreground: " << min*100 << "cm" <<endl; + // debout << "Maximal distance to camera in foreground: " << max*100 << "cm" <<endl; + if(max - min < 1) + debout << "Warning: hight field difference is smaller 1m!" << endl; + // debout << sc->getCmPerPixel(min) <<endl; + // debout << sc->getCmPerPixel(max) <<endl; + // debout << sc->getZfromDisp(sc->getMin()) <<endl; + // debout << sc->getZfromDisp(sc->getMax()) <<endl; + float l1 = 4.2 / mSc->getCmPerPixel(min); + float l2 = 67. / mSc->getCmPerPixel(max); + // debout << l1*l1 <<endl; + // debout << l2*l2 <<endl; // interpolate z-values inbetween innerhalb zeile float *vorPtr; // zeigt auf den letzten gueltigen Wert vor ungueltigem wert in einer Zeile float *nachPtr; // zeigt auf den ersten gueltigen Wert nach ungueltigen in einer Zeile float *fPtr; - float step; + float step; - pcData = (float *) pointCloud.data; + pcData = (float *) pointCloud.data; yPcData = pcData; - for (y = 0; y < pointCloud.rows; ++y) + for(y = 0; y < pointCloud.rows; ++y) { vorPtr = nachPtr = NULL; - for (x = 0; x < (pointCloud.cols)-1; ++x) + for(x = 0; x < (pointCloud.cols) - 1; ++x) { - if (vorPtr == NULL && pcData[2] != -1 && pcData[5] == -1) // eine unbestimmte gap beginnt + if(vorPtr == NULL && pcData[2] != -1 && pcData[5] == -1) // eine unbestimmte gap beginnt vorPtr = pcData; - else if (vorPtr != NULL && nachPtr == NULL && pcData[2] == -1 && pcData[5] != -1) // eine unbestimmte gap endet - nachPtr = pcData+3; - if (vorPtr != NULL && nachPtr != NULL) // gap bestimmt, fuellung mit interpolerten werten + else if(vorPtr != NULL && nachPtr == NULL && pcData[2] == -1 && pcData[5] != -1) // eine unbestimmte gap + // endet + nachPtr = pcData + 3; + if(vorPtr != NULL && nachPtr != NULL) // gap bestimmt, fuellung mit interpolerten werten { - if ((nachPtr-vorPtr) < 3*DISP_GAP_SIZE_TO_FILL) // nur kleine luecken von weniger als 15 pixel fuellen + if((nachPtr - vorPtr) < + 3 * DISP_GAP_SIZE_TO_FILL) // nur kleine luecken von weniger als 15 pixel fuellen { - step = ((nachPtr[2]-vorPtr[2])/(nachPtr-vorPtr)); // lange zeit war falsch: /9.; // /3 ein /3 durch (fPtr-vorPtr) und nicht (fPtr-vorPtr)/3 in schleife - for (fPtr = vorPtr+3; fPtr < nachPtr; fPtr+=3) + step = + ((nachPtr[2] - vorPtr[2]) / + (nachPtr - vorPtr)); // lange zeit war falsch: /9.; // /3 ein /3 durch (fPtr-vorPtr) und nicht + // (fPtr-vorPtr)/3 in schleife + for(fPtr = vorPtr + 3; fPtr < nachPtr; fPtr += 3) { - //fPtr[0] = ; // x - //fPtr[1] = ; // y - fPtr[2] = vorPtr[2]+(fPtr-vorPtr)*step; + // fPtr[0] = ; // x + // fPtr[1] = ; // y + fPtr[2] = vorPtr[2] + (fPtr - vorPtr) * step; } } vorPtr = nachPtr = NULL; } - pcData+=3; + pcData += 3; } - pcData = (yPcData += pointCloud.cols/sizeof(float)); + pcData = (yPcData += pointCloud.cols / sizeof(float)); } // grauwertbild erstellen zwischen min und max - ungueltige werte auf 255 setzen - IplImage *gray = cvCreateImage(imgSize, IPL_DEPTH_8U, 1); + IplImage * gray = cvCreateImage(imgSize, IPL_DEPTH_8U, 1); unsigned char *grayData = (unsigned char *) gray->imageData; unsigned char *yGrayData = grayData; - pcData = (float *) pointCloud.data; - yPcData = pcData; - float scale = 254./(max-min); + pcData = (float *) pointCloud.data; + yPcData = pcData; + float scale = 254. / (max - min); - for (y = 0; y < pointCloud.rows; ++y) + for(y = 0; y < pointCloud.rows; ++y) { - for (x = 0; x < pointCloud.cols; ++x) + for(x = 0; x < pointCloud.cols; ++x) { - - if (pcData[2] == -1) + if(pcData[2] == -1) *grayData = 255; else - *grayData = scale*(pcData[2]-min); - pcData+=3; + *grayData = scale * (pcData[2] - min); + pcData += 3; ++grayData; } - pcData = (yPcData += pointCloud.cols/sizeof(float)); + pcData = (yPcData += pointCloud.cols / sizeof(float)); grayData = (yGrayData += gray->width); } -// // umkopieren der pointcloud auf matrix mit nur z-werten -// IplImage *zPointCloud = cvCreateImage(cvGetSize(pointCloud),32,1); -// cvSplit(pointCloud, NULL, NULL, zPointCloud, NULL); -// // nun muesste noch -1 auf max gesetzt werden, damit isolinen richtig herum verlaufen!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // // umkopieren der pointcloud auf matrix mit nur z-werten + // IplImage *zPointCloud = cvCreateImage(cvGetSize(pointCloud),32,1); + // cvSplit(pointCloud, NULL, NULL, zPointCloud, NULL); + // // nun muesste noch -1 auf max gesetzt werden, damit isolinen richtig herum + // verlaufen!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! int i, count; - //int threshold; - float threshold; - double angle; - CvSeq *contours, *firstContour; - IplImage *binImg = cvCreateImage(imgSize, IPL_DEPTH_8U, 1);; - CvPoint* PointArray; - CvPoint2D32f* PointArray2D32f; - //CvPoint center; - //CvSize sizeTmp; - //int expansion; + // int threshold; + float threshold; + double angle; + CvSeq * contours, *firstContour; + IplImage *binImg = cvCreateImage(imgSize, IPL_DEPTH_8U, 1); + ; + CvPoint * PointArray; + CvPoint2D32f *PointArray2D32f; + // CvPoint center; + // CvSize sizeTmp; + // int expansion; double contourArea; - //double contourLength; - CvMemStorage* storage = cvCreateMemStorage(0); - float dist; - bool contourInside; // gigt an, ob die contour ueber den rand der bounding box roi hinweggeht + // double contourLength; + CvMemStorage *storage = cvCreateMemStorage(0); + float dist; + bool contourInside; // gigt an, ob die contour ueber den rand der bounding box roi hinweggeht -int frameNum = mSc->getAnimation()->getCurrentFrameNum(); + int frameNum = mSc->getAnimation()->getCurrentFrameNum(); #ifdef SHOWELLIPSES - IplImage *tmpAusgabe = cvCreateImage(imgSize,IPL_DEPTH_8U, 3); // cvCloneImage(gray); // make a copy - IplImage *tmpAusgabe2 = cvCreateImage(imgSize,IPL_DEPTH_8U, 3); // cvCloneImage(gray); // make a copy - IplImage *tmpAusgabe3 = cvCreateImage(imgSize,IPL_DEPTH_8U, 3); // cvCloneImage(gray); // make a copy + IplImage *tmpAusgabe = cvCreateImage(imgSize, IPL_DEPTH_8U, 3); // cvCloneImage(gray); // make a copy + IplImage *tmpAusgabe2 = cvCreateImage(imgSize, IPL_DEPTH_8U, 3); // cvCloneImage(gray); // make a copy + IplImage *tmpAusgabe3 = cvCreateImage(imgSize, IPL_DEPTH_8U, 3); // cvCloneImage(gray); // make a copy cvCvtColor(gray, tmpAusgabe, CV_GRAY2BGR); cvCvtColor(mSc->getRectified(cameraRight), tmpAusgabe2, CV_GRAY2BGR); cvCvtColor(gray, tmpAusgabe3, CV_GRAY2BGR); #endif #ifdef SAVEELLIPSES QFile ellipsFile("ellipses.txt"); - if (!ellipsFile.open(QIODevice::Append | QIODevice::Text)) + if(!ellipsFile.open(QIODevice::Append | QIODevice::Text)) debout << "Error: Cannot open ellipses.txt: " << ellipsFile.errorString(); QTextStream ellipsOut(&ellipsFile); #endif #ifdef TIME_MEASUREMENT // "==========: " - debout << "vor cont : " << getElapsedTime() <<endl; + debout << "vor cont : " << getElapsedTime() << endl; #endif - step = 2.55/((max-min)/STEP_SIZE); // STEP_SIZE cm Schritte, daher 2.55, da min und max in meter - for (threshold = step; threshold < 255-step ; threshold += step) // von kopf zum fuss = von klein nach gross - //for (threshold = 10; threshold < 250 ; threshold += 10) // von kopf zum fuss = von klein nach gross - //for (threshold = min+step; threshold < max-step ; threshold += step) // von kopf zum fuss = von klein nach gross + step = 2.55 / ((max - min) / STEP_SIZE); // STEP_SIZE cm Schritte, daher 2.55, da min und max in meter + for(threshold = step; threshold < 255 - step; threshold += step) // von kopf zum fuss = von klein nach gross + // for (threshold = 10; threshold < 250 ; threshold += 10) // von kopf zum fuss = von klein nach gross + // for (threshold = min+step; threshold < max-step ; threshold += step) // von kopf zum fuss = von klein nach gross { - - dist = min*100+STEP_SIZE*threshold/step; + dist = min * 100 + STEP_SIZE * threshold / step; QList<MyEllipse> el; // jeder level neu anlegen cvThreshold(gray, binImg, threshold, 255, CV_THRESH_BINARY); - //cvThreshold(zPointCloud, binImg, threshold, 255, CV_THRESH_BINARY); + // cvThreshold(zPointCloud, binImg, threshold, 255, CV_THRESH_BINARY); // find contours and store them all as a list - cvFindContours(binImg, storage, &firstContour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); // binImg wird auch veraendert!!! + cvFindContours( + binImg, + storage, + &firstContour, + sizeof(CvContour), + CV_RETR_LIST, + CV_CHAIN_APPROX_SIMPLE); // binImg wird auch veraendert!!! contours = firstContour; // test each contour - while (contours) + while(contours) { - count = contours->total; // This is number point in contour - if (count > 5) // fuer ellips fit mind 6 pkte benoetigt + if(count > 5) // fuer ellips fit mind 6 pkte benoetigt { // in rot contouren in eine drehrichtung, in gruen andere #ifdef SHOWELLIPSES - cvDrawContours(tmpAusgabe,contours,CV_RGB(255,0,0),CV_RGB(0,255,0),0,1,8,cvPoint(0,0)); + cvDrawContours(tmpAusgabe, contours, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), 0, 1, 8, cvPoint(0, 0)); #endif - // IN OPENCV2.1 liefert cvContourArea KEIN VORZEICHEN ZUM ERKENNEN DER DREHRICHTUNG!!!! es ist ein optionaler paramter hinzugefuegt worden!!!! -#if ((CV_MAJOR_VERSION < 2) || ((CV_MAJOR_VERSION == 2) && (CV_MINOR_VERSION < 1))) - contourArea = cvContourArea(contours,CV_WHOLE_SEQ); + // IN OPENCV2.1 liefert cvContourArea KEIN VORZEICHEN ZUM ERKENNEN DER DREHRICHTUNG!!!! es ist ein + // optionaler paramter hinzugefuegt worden!!!! +#if((CV_MAJOR_VERSION < 2) || ((CV_MAJOR_VERSION == 2) && (CV_MINOR_VERSION < 1))) + contourArea = cvContourArea(contours, CV_WHOLE_SEQ); #else - contourArea = cvContourArea(contours,CV_WHOLE_SEQ, true); + contourArea = cvContourArea(contours, CV_WHOLE_SEQ, true); #endif - // if (contours->flags & CV_SEQ_FLAG_HOLE) == 0) - // debout << "Negative contourArea! If not using the absolute size, the flag shows already the direction!" << endl; - - //war: (contourArea>50 && contourArea<8000) // sollte abhaengig von untersuchten groessen gemacht werden - // entspricht: - // < 4.2cm x 4.2cm=18cm^2 = 50 Pixel in maximaler personengroesse - //in maximaler Entfernung zur Kamera + // if (contours->flags & CV_SEQ_FLAG_HOLE) == 0) + // debout << "Negative contourArea! If not using the absolute size, the flag + // shows already the direction!" << endl; + + // war: (contourArea>50 && contourArea<8000) // sollte abhaengig von untersuchten groessen gemacht + // werden + // entspricht: + // < 4.2cm x 4.2cm=18cm^2 = 50 Pixel in maximaler personengroesse + // in maximaler Entfernung zur Kamera //(in ebenen Versuchen entspricht dies 40cm über Bodenhöhe) - //größer als 4500cm^2 = 8000 Pixel + // größer als 4500cm^2 = 8000 Pixel - if (contourArea>l1*l1 && contourArea<l2*l2) + if(contourArea > l1 * l1 && contourArea < l2 * l2) { // Alloc memory for contour point set. - PointArray = (CvPoint*)malloc(count*sizeof(CvPoint)); - PointArray2D32f = (CvPoint2D32f*)malloc(count*sizeof(CvPoint2D32f)); + PointArray = (CvPoint *) malloc(count * sizeof(CvPoint)); + PointArray2D32f = (CvPoint2D32f *) malloc(count * sizeof(CvPoint2D32f)); - //cv::Mat PointMat = cv::Mat(1, count, CV_32SC2, contours); - //debout << cv::contourArea(PointMat) <<endl; // cvContourBoundingRect(...) - //debout << cv::isContourConvex(PointMat) <<endl; - //HoughCircles: Finds circles in a grayscale image using a Hough transform. + // cv::Mat PointMat = cv::Mat(1, count, CV_32SC2, contours); + // debout << cv::contourArea(PointMat) <<endl; // cvContourBoundingRect(...) + // debout << cv::isContourConvex(PointMat) <<endl; + // HoughCircles: Finds circles in a grayscale image using a Hough transform. // Get contour point set. cvCvtSeqToArray(contours, PointArray, CV_WHOLE_SEQ); // Convert CvPoint set to CvBox2D32f set. contourInside = true; - for(i=0; i<count; i++) + for(i = 0; i < count; i++) { - - x = PointArray[i].x; - y = PointArray[i].y; -// // delete point at blob border -// if (!((gray->imageData[x+y*gray->width-1] == 255) || -// (gray->imageData[x+y*gray->width+1] == 255) || -// (gray->imageData[x+(y-1)*gray->width] == 255) || -// (gray->imageData[x+(y+1)*gray->width] == 255))) // nicht am rand -// { - PointArray2D32f[i].x = (float)x; - PointArray2D32f[i].y = (float)y; -// } -// else -// { -// --count; -// debout << "del contour point " << x << " " << y << endl; -// } - if (x < roi.left() || x > roi.right() || y < roi.top() || y > roi.bottom()) - contourInside = false; - + x = PointArray[i].x; + y = PointArray[i].y; + // // delete point at blob border + // if (!((gray->imageData[x+y*gray->width-1] == 255) || + // (gray->imageData[x+y*gray->width+1] == 255) || + // (gray->imageData[x+(y-1)*gray->width] == 255) || + // (gray->imageData[x+(y+1)*gray->width] == 255))) // nicht am rand + // { + PointArray2D32f[i].x = (float) x; + PointArray2D32f[i].y = (float) y; + // } + // else + // { + // --count; + // debout << "del contour point " << x << " " << y << endl; + // } + if(x < roi.left() || x > roi.right() || y < roi.top() || y > roi.bottom()) + contourInside = false; } - // contourLength = 0; - // for(i=1; i<=count; i++) - // { - // contourLength+=sqrt((PointArray[i%count].x-PointArray[i-1].x)*(PointArray[i%count].x-PointArray[i-1].x) + (PointArray[i%count].y-PointArray[i-1].y)*(PointArray[i%count].y-PointArray[i-1].y)); - // } - - if (count > 5 && contourInside) + // contourLength = 0; + // for(i=1; i<=count; i++) + // { + // contourLength+=sqrt((PointArray[i%count].x-PointArray[i-1].x)*(PointArray[i%count].x-PointArray[i-1].x) + // + + // (PointArray[i%count].y-PointArray[i-1].y)*(PointArray[i%count].y-PointArray[i-1].y)); + // } + + if(count > 5 && contourInside) { #ifdef SHOWELLIPSES - cvDrawContours(tmpAusgabe,contours,CV_RGB(255,0,255),CV_RGB(0,255,255),0,1,8,cvPoint(0,0)); // um anzuzeigen welche wirklich genommen wurden + cvDrawContours( + tmpAusgabe, + contours, + CV_RGB(255, 0, 255), + CV_RGB(0, 255, 255), + 0, + 1, + 8, + cvPoint( + 0, + 0)); // um anzuzeigen welche wirklich genommen wurden #endif #if CV_MAJOR_VERSION == 2 - // Fits ellipse to current contour. ------------------------------------------------------------------------------- + // Fits ellipse to current contour. + // ------------------------------------------------------------------------------- CvBox2D32f box; cvFitEllipse(PointArray2D32f, count, &box); #elif CV_MAJOR_VERSION == 3 // neuer: //// Fits ellipse to current contour. -// CvBox2D box = cvFitEllipse2(PointArray2D32f); - Mat mat(count,2,CV_32F); - for(i=0; i<count; i++) + // CvBox2D box = cvFitEllipse2(PointArray2D32f); + Mat mat(count, 2, CV_32F); + for(i = 0; i < count; i++) { - mat.at<float>(i,0) = (float)PointArray[i].x; - mat.at<float>(i,1) = (float)PointArray[i].y; + mat.at<float>(i, 0) = (float) PointArray[i].x; + mat.at<float>(i, 1) = (float) PointArray[i].y; } RotatedRect box = fitEllipse(mat); #endif // Convert ellipse data from float to integer representation. - //center.x = myRound(box.center.x); - //center.y = myRound(box.center.y); - //box.angle = -box.angle; - //sizeTmp.width = myRound(box.size.width*0.5); - //sizeTmp.height = myRound(box.size.height*0.5); - - angle = (box.angle)/180.*PI; - if (box.size.width<box.size.height) // da bei meiner ellipse r1 immer der groesste radius - angle -= PI/2; - - MyEllipse elips(box.center.x, box.center.y, box.size.width*0.5, box.size.height*0.5, angle); - // debout << elips.area() << " " << contourArea << " " << contourLength<< " " << contourLength*contourLength/contourArea<<endl; - //if (elips.area()/contourArea < 1.2) // elips soll aehnliche flaechengroesse haben - //if (contourLength/contourArea < 0.2) // elips soll aehnliche flaechengroesse haben - //if (contourLength*contourLength/contourArea < 40.) // quadratisch, da in flaeche r quadratisch eingeht -// if (elips.r1() < 80) // wird nun beim einfuegen in person mit beruecksichtigt, damit an einer stelle ellipse ueberprueft wird!! - r1 ist immer der groessere radius - um 2 Personen in einer ellipse zu vermeiden -// { - el.append(elips); - //cvEllipse(tmpAusgabe2, center, sizeTmp, box.angle, 0, 360, CV_RGB(255, 0, 0), 1, CV_AA, 0); - //cvEllipseBox(tmpAusgabe3, box, CV_RGB(255, 0, 0)); - -// } -// else -// debout << "del elips, because to big " << box.center.x <<" "<< box.center.y <<endl; - // if (contourLength*contourLength/contourArea >= 40.) - // debout << "l*l/a: " <<box.center.x <<" "<< box.center.y <<endl; + // center.x = myRound(box.center.x); + // center.y = myRound(box.center.y); + // box.angle = -box.angle; + // sizeTmp.width = myRound(box.size.width*0.5); + // sizeTmp.height = myRound(box.size.height*0.5); + + angle = (box.angle) / 180. * PI; + if(box.size.width < box.size.height) // da bei meiner ellipse r1 immer der groesste radius + angle -= PI / 2; + + MyEllipse elips(box.center.x, box.center.y, box.size.width * 0.5, box.size.height * 0.5, angle); + // debout << elips.area() << " " << contourArea << " " << + // contourLength<< " " << + // contourLength*contourLength/contourArea<<endl; + // if (elips.area()/contourArea < 1.2) // elips soll aehnliche flaechengroesse haben + // if (contourLength/contourArea < 0.2) // elips soll aehnliche flaechengroesse haben + // if (contourLength*contourLength/contourArea < 40.) // quadratisch, da in flaeche r + // quadratisch eingeht + // if (elips.r1() < 80) // wird nun beim einfuegen in person mit + // beruecksichtigt, damit an einer stelle ellipse ueberprueft wird!! - r1 + // ist immer der groessere radius - um 2 Personen in einer ellipse zu + // vermeiden + // { + el.append(elips); + // cvEllipse(tmpAusgabe2, center, sizeTmp, box.angle, 0, 360, CV_RGB(255, 0, 0), 1, CV_AA, 0); + // cvEllipseBox(tmpAusgabe3, box, CV_RGB(255, 0, 0)); + + // } + // else + // debout << "del elips, because to big " << box.center.x <<" "<< + // box.center.y <<endl; if (contourLength*contourLength/contourArea + // >= 40.) + // debout << "l*l/a: " <<box.center.x <<" "<< box.center.y + // <<endl; // if (contourLength/contourArea >= 0.2) - // debout << "l/a: " <<box.center.x <<" "<< box.center.y <<endl; + // debout << "l/a: " <<box.center.x <<" "<< box.center.y + // <<endl; // if (elips.area()/contourArea >= 1.2) - // debout << "ea/ca: " <<box.center.x <<" "<< box.center.y <<endl; - + // debout << "ea/ca: " <<box.center.x <<" "<< box.center.y + // <<endl; } std::free(PointArray); std::free(PointArray2D32f); @@ -356,14 +390,14 @@ int frameNum = mSc->getAnimation()->getCurrentFrameNum(); contours = contours->h_next; } #ifdef TIME_MEASUREMENT - // "==========: " - debout << "vor insert: " << getElapsedTime() <<endl; + // "==========: " + debout << "vor insert: " << getElapsedTime() << endl; #endif insertEllipses(el, dist); #ifdef SHOWELLIPSES - for (int i = 0; i < el.size(); ++i) + for(int i = 0; i < el.size(); ++i) { el.at(i).draw(tmpAusgabe3, 0, 255, 0); } @@ -371,56 +405,58 @@ int frameNum = mSc->getAnimation()->getCurrentFrameNum(); #ifdef SAVEELLIPSES // anhaengen der ellipsen in ausgabedatei zur spaeteren analyse // frame hoehe/z x(px) y(px) elips.winkel elips.r1 elips.r2 - for (int i = 0; i < el.size(); ++i) + for(int i = 0; i < el.size(); ++i) { - ellipsOut << frameNum << " " << dist << " " << el.at(i).x() << " " << el.at(i).y() << " " << el.at(i).angle() << " " << el.at(i).r1() << " " << el.at(i).r2() << " " << 0 << endl; + ellipsOut << frameNum << " " << dist << " " << el.at(i).x() << " " << el.at(i).y() << " " + << el.at(i).angle() << " " << el.at(i).r1() << " " << el.at(i).r2() << " " << 0 << endl; } #endif // sprintf(outstr,"c:/%d.png",threshold); // cvSaveImage(outstr, tmpAusgabe); - //cvWaitKey( 0 ); // zahl statt null, wenn nach bestimmter zeit weitergegangen werden soll + // cvWaitKey( 0 ); // zahl statt null, wenn nach bestimmter zeit weitergegangen werden soll // nicht noetig, aber so kann der neu erzeugte speicherplatz reduziert werden // freigabe des speicherplatz erst bei cvClearMemStorage(storage) - if (firstContour) + if(firstContour) cvClearSeq(firstContour); // not free only available for next push } #ifdef TIME_MEASUREMENT // "==========: " - debout << "nach cont : " << getElapsedTime() <<endl; + debout << "nach cont : " << getElapsedTime() << endl; #endif optimize(); #ifdef SHOWELLIPSES - for (int i = 0; i < size(); ++i) - for (int j = at(i).size()-1; j >= 0; --j) // rueckwwaerts, damit hoeher liegende ellipsen oben aufgezeichnet werden + for(int i = 0; i < size(); ++i) + for(int j = at(i).size() - 1; j >= 0; + --j) // rueckwwaerts, damit hoeher liegende ellipsen oben aufgezeichnet werden { - if (j == 0) + if(j == 0) at(i).at(j).draw(tmpAusgabe2, 0, 255, 0); - else if (j == 1) + else if(j == 1) at(i).at(j).draw(tmpAusgabe2, 255, 0, 0); - else if (j == 2) + else if(j == 2) at(i).at(j).draw(tmpAusgabe2, 0, 0, 255); else - at(i).at(j).draw(tmpAusgabe2, 150, 150, j*255/at(i).size()); - //debout << i << " " << j << " " << pl.at(i).at(j).center().x() << " " << pl.at(i).at(j).center().y()<< " " << pl.at(i).at(j).area() <<endl; + at(i).at(j).draw(tmpAusgabe2, 150, 150, j * 255 / at(i).size()); + // debout << i << " " << j << " " << pl.at(i).at(j).center().x() << " " << pl.at(i).at(j).center().y()<< " " + // << pl.at(i).at(j).area() <<endl; } -// char outstr[120]; -// //static int zaehl = 0; -// sprintf(outstr,"D:/data/ko/ko-240-240-240_cam2_isolines/ko-240-240_cam2_isolines_%04d.png",frameNum); -// cvSaveImage(outstr, tmpAusgabe); -// sprintf(outstr,"D:/data/ko/ko-240-240-240_cam2_ellipses/ko-240-240_cam2_ellipses_%04d.png",frameNum); -// cvSaveImage(outstr, tmpAusgabe2); -// sprintf(outstr,"D:/data/ko/ko-240-240-240_cam2_persons/ko-240-240_cam2_persons_%04d.png",frameNum); -// cvSaveImage(outstr, tmpAusgabe3); - - //cvNamedWindow("img", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll - //cvShowImage("img", tmpAusgabe); + // char outstr[120]; + // //static int zaehl = 0; + // sprintf(outstr,"D:/data/ko/ko-240-240-240_cam2_isolines/ko-240-240_cam2_isolines_%04d.png",frameNum); + // cvSaveImage(outstr, tmpAusgabe); + // sprintf(outstr,"D:/data/ko/ko-240-240-240_cam2_ellipses/ko-240-240_cam2_ellipses_%04d.png",frameNum); + // cvSaveImage(outstr, tmpAusgabe2); + // sprintf(outstr,"D:/data/ko/ko-240-240-240_cam2_persons/ko-240-240_cam2_persons_%04d.png",frameNum); + // cvSaveImage(outstr, tmpAusgabe3); + // cvNamedWindow("img", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll + // cvShowImage("img", tmpAusgabe); static QLabel imgLabel; @@ -431,16 +467,16 @@ int frameNum = mSc->getAnimation()->getCurrentFrameNum(); showImg(&imgLabel3, tmpAusgabe3); #ifdef SAVE_IMG_DETECTION_STEPS - static int frame=0; - static char outstr[1024]; - debout << "Images " << frame << " of detection steps are saved to basename " << SAVE_IMG_FILEBASE << " !" << endl; - sprintf(outstr,"%scontour_%03d.png", SAVE_IMG_FILEBASE, frame); - cvSaveImage(outstr, tmpAusgabe); - sprintf(outstr,"%spyramide_%03d.png", SAVE_IMG_FILEBASE, frame); - cvSaveImage(outstr, tmpAusgabe2); - sprintf(outstr,"%sellipses_%03d.png", SAVE_IMG_FILEBASE, frame); - cvSaveImage(outstr, tmpAusgabe3); - frame++; + static int frame = 0; + static char outstr[1024]; + debout << "Images " << frame << " of detection steps are saved to basename " << SAVE_IMG_FILEBASE << " !" << endl; + sprintf(outstr, "%scontour_%03d.png", SAVE_IMG_FILEBASE, frame); + cvSaveImage(outstr, tmpAusgabe); + sprintf(outstr, "%spyramide_%03d.png", SAVE_IMG_FILEBASE, frame); + cvSaveImage(outstr, tmpAusgabe2); + sprintf(outstr, "%sellipses_%03d.png", SAVE_IMG_FILEBASE, frame); + cvSaveImage(outstr, tmpAusgabe3); + frame++; #endif cvReleaseImage(&tmpAusgabe); @@ -448,75 +484,93 @@ int frameNum = mSc->getAnimation()->getCurrentFrameNum(); cvReleaseImage(&tmpAusgabe3); #endif #ifdef SAVEELLIPSES - for (int i = 0; i < size(); ++i) - for (int j = at(i).size()-1; j >= 0; --j) // rueckwwaerts, damit hoeher liegende ellipsen oben aufgezeichnet werden + for(int i = 0; i < size(); ++i) + for(int j = at(i).size() - 1; j >= 0; + --j) // rueckwwaerts, damit hoeher liegende ellipsen oben aufgezeichnet werden { - ellipsOut << frameNum << " " << at(i).getDistTopEllipse()+j*STEP_SIZE << " " << at(i).at(j).x() << " " << at(i).at(j).y() << " " << at(i).at(j).angle() << " " << at(i).at(j).r1() << " " << at(i).at(j).r2() << " " << i+1 << endl; // i+1, damit 0 den rohen ellipsen vorbehaqlten bleibt + ellipsOut << frameNum << " " << at(i).getDistTopEllipse() + j * STEP_SIZE << " " << at(i).at(j).x() << " " + << at(i).at(j).y() << " " << at(i).at(j).angle() << " " << at(i).at(j).r1() << " " + << at(i).at(j).r2() << " " << i + 1 + << endl; // i+1, damit 0 den rohen ellipsen vorbehaqlten bleibt } ellipsFile.close(); #endif -// cvReleaseMat(&pointCloud); - //cvReleaseImage(&zPointCloud); + // cvReleaseMat(&pointCloud); + // cvReleaseImage(&zPointCloud); cvReleaseImage(&gray); cvReleaseImage(&binImg); cvReleaseMemStorage(&storage); #ifdef TIME_MEASUREMENT // "==========: " - debout << "ed search : " << getElapsedTime() <<endl; + debout << "ed search : " << getElapsedTime() << endl; #endif - } // el liste aller ellipsen eines thresholds der hoehe // der thrershold durchlaeuft hoehenfeld von kopf bis fuss // distFromCam in cm -void PersonList::insertEllipses(const QList<MyEllipse> &el, float distFromCam) // nicht mehr: el wird angepasst, so dass nur noch eingefuegte ellipsen drin +void PersonList::insertEllipses( + const QList<MyEllipse> &el, + float distFromCam) // nicht mehr: el wird angepasst, so dass nur noch eingefuegte ellipsen drin { - int i, j; - bool found; + int i, j; + bool found; double minDist, dist; - int minIdx; - int sub; - Vec2F center; - - float r1Max = 60./mSc->getCmPerPixel(.01*distFromCam); // war 80 px am boden ist 60cm // radius der ellips mit maxmalem radius 80 pixel - float r1Min = 10./mSc->getCmPerPixel(.01*distFromCam); // war 15 px in Schulterhohe sei 10cm // laenge der grossen Hauptachse in mittlerer Kopfhöhe - - for (i = 0; i < el.size(); ++i) // ueber uebergebene liste von ellipsen + int minIdx; + int sub; + Vec2F center; + + float r1Max = + 60. / mSc->getCmPerPixel( + .01 * distFromCam); // war 80 px am boden ist 60cm // radius der ellips mit maxmalem radius 80 pixel + float r1Min = + 10. / + mSc->getCmPerPixel( + .01 * + distFromCam); // war 15 px in Schulterhohe sei 10cm // laenge der grossen Hauptachse in mittlerer Kopfhöhe + + for(i = 0; i < el.size(); ++i) // ueber uebergebene liste von ellipsen { - // FOLGENDE ABFRAGE KANN DAZU FUEHREN, DASS IN EINER PYRAMIDE EIN LEVEL NICHT VORKOMMT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if ((el.at(i).ratio() < 4) || (el.at(i).r1() > r1Max)) // war: > 80 // r1 ist immer der groessere radius - um 2 Personen in einer ellipse zu vermeiden + // FOLGENDE ABFRAGE KANN DAZU FUEHREN, DASS IN EINER PYRAMIDE EIN LEVEL NICHT + // VORKOMMT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if((el.at(i).ratio() < 4) || + (el.at(i).r1() > + r1Max)) // war: > 80 // r1 ist immer der groessere radius - um 2 Personen in einer ellipse zu vermeiden { - QList<int> considered; // beruecksichtigte bereits existierende pyramiden fuer diese groessere ellipse - for (j = 0; j < size(); ++j) // ueber existierende Personen, deren ellipsen kleiner sind + QList<int> considered; // beruecksichtigte bereits existierende pyramiden fuer diese groessere ellipse + for(j = 0; j < size(); ++j) // ueber existierende Personen, deren ellipsen kleiner sind { - if (el.at(i).isInside(at(j).last().center())) + if(el.at(i).isInside(at(j).last().center())) { - if (at(j).getActLevel()) // mehrere neue grosse ellipsen beinhalten kleine exist ellipse + if(at(j).getActLevel()) // mehrere neue grosse ellipsen beinhalten kleine exist ellipse { - //debout << at(j).size() << endl; - // die pyramide suchen, wo schon eingefuegt und testen welcher mittelpunkt naeher liegt - Vec2F centerLevelBefore = at(j).at(at(j).size()-2).center(); - if (at(j).last().center().distanceToPoint(centerLevelBefore) > // abstand der letzten beiden pyramidenelememnte (2 muessen drin sein, weil sonst allConsidered es nicht beeinhalten wuerde) - el.at(i).center().distanceToPoint(centerLevelBefore)) + // debout << at(j).size() << endl; + // die pyramide suchen, wo schon eingefuegt und testen welcher mittelpunkt naeher liegt + Vec2F centerLevelBefore = at(j).at(at(j).size() - 2).center(); + if(at(j).last().center().distanceToPoint( + centerLevelBefore) > // abstand der letzten beiden pyramidenelememnte (2 muessen drin + // sein, weil sonst allConsidered es nicht beeinhalten wuerde) + el.at(i).center().distanceToPoint(centerLevelBefore)) { // genommen wird die, deren center naeher an existierender liegen #ifdef PRINT_ERASE_REASON - debout << "Eliminate ellipse because of a second ellipse nearer pyramide: " << (*this)[j].last().center().x() << " " << (*this)[j].last().center().y() << endl; + debout << "Eliminate ellipse because of a second ellipse nearer pyramide: " + << (*this)[j].last().center().x() << " " << (*this)[j].last().center().y() << endl; #endif (*this)[j].removeLast(); (*this)[j].append(el.at(i)); // auch moeglich, aber dann mgl gar nicht: considered += j; // } -//debout << "Fall 4" <<endl; -//debout << (*this)[j].last().center().x() << " " << (*this)[j].last().center().y() << endl; -//QMessageBox Msgbox; //#include <QMessageBox> noetig -//Msgbox.setText("Warten"); -//Msgbox.exec(); -////cvSaveImage("D:/contour.png", tmpAusgabe); -////cvSaveImage("D:/pyramide.png", tmpAusgabe2); -////cvSaveImage("D:/ellipses.png", tmpAusgabe3); - - //debout << "Warning: multiple consideration for " << centerLevelBefore.x() << " " << centerLevelBefore.y() <<endl; + // debout << "Fall 4" <<endl; + // debout << (*this)[j].last().center().x() << " " << (*this)[j].last().center().y() << endl; + // QMessageBox Msgbox; //#include <QMessageBox> noetig + // Msgbox.setText("Warten"); + // Msgbox.exec(); + ////cvSaveImage("D:/contour.png", tmpAusgabe); + ////cvSaveImage("D:/pyramide.png", tmpAusgabe2); + ////cvSaveImage("D:/ellipses.png", tmpAusgabe3); + + // debout << "Warning: multiple consideration for " << centerLevelBefore.x() << " " << + // centerLevelBefore.y() <<endl; } else { @@ -524,65 +578,73 @@ void PersonList::insertEllipses(const QList<MyEllipse> &el, float distFromCam) / } } } - if (considered.size() == 0) // neue contour pyramide + if(considered.size() == 0) // neue contour pyramide { -//debout << "Fall 1" <<endl; + // debout << "Fall 1" <<endl; append(Person(el.at(i), distFromCam)); } - else if (considered.size() == 1) // genau ein passende pyramide + else if(considered.size() == 1) // genau ein passende pyramide { -//debout << "Fall 2" <<endl; + // debout << "Fall 2" <<endl; (*this)[considered.at(0)].append(el.at(i)); (*this)[considered.at(0)].setActLevel(true); } else // mehrere Anwaerter exist kleinerer ellipsen die in neuer grossen liegen { -//debout << "Fall 3" <<endl; + // debout << "Fall 3" <<endl; found = false; // suchen der groessten pyramide - for (j = 0; j < considered.size(); ++j) + for(j = 0; j < considered.size(); ++j) { - // wenn mind. pyramide groesser 2 uebernehmen (2 personen laufen dicht nebeneinander) mit gewisser ausdehnung -// debout << 10./STEP_SIZE <<endl; -// debout << r1Min <<endl; - if ((at(considered.at(j)).size() > 10./STEP_SIZE) && // war 2 - (at(considered.at(j)).last().r1() > r1Min)) // war 15 // erhebung groesser 10 cm bei 5cm level-unterteilung + // wenn mind. pyramide groesser 2 uebernehmen (2 personen laufen dicht nebeneinander) mit gewisser + // ausdehnung + // debout << 10./STEP_SIZE <<endl; + // debout << r1Min <<endl; + if((at(considered.at(j)).size() > 10. / STEP_SIZE) && // war 2 + (at(considered.at(j)).last().r1() > + r1Min)) // war 15 // erhebung groesser 10 cm bei 5cm level-unterteilung { (*this)[considered.at(j)].append(el.at(i)); (*this)[considered.at(j)].setActLevel(true); found = true; -//debout << "Fall a" <<endl; + // debout << "Fall a" <<endl; } } - if (!found) // wenn alle pyramiden kleiner, dann die mit dem naechsten center nehmen und restliche LOESCHEN! + if(!found) // wenn alle pyramiden kleiner, dann die mit dem naechsten center nehmen und restliche + // LOESCHEN! { -//debout << "Fall b" <<endl; + // debout << "Fall b" <<endl; minDist = 1000000.; - minIdx = -1; - for (j = 0; j < considered.size(); ++j) + minIdx = -1; + for(j = 0; j < considered.size(); ++j) { center = at(considered.at(j)).last().center(); - if (at(considered.at(j)).size() > 1) // da elips in pyramide systematisch wandern bei mehr als 1 elips den offset auf letzten mittelpkt draufaddieren - center += center - at(considered.at(j)).at(at(considered.at(j)).size()-2).center(); + if(at(considered.at(j)).size() > 1) // da elips in pyramide systematisch wandern bei mehr als 1 + // elips den offset auf letzten mittelpkt draufaddieren + center += center - at(considered.at(j)).at(at(considered.at(j)).size() - 2).center(); center = at(considered.at(j)).last().center(); - if ((dist = el.at(i).center().distanceToPoint(center)) < minDist) + if((dist = el.at(i).center().distanceToPoint(center)) < minDist) { minDist = dist; - minIdx = j; + minIdx = j; } } (*this)[considered.at(minIdx)].append(el.at(i)); (*this)[considered.at(minIdx)].setActLevel(true); - // alles pyramiden ausser mit minIdx loeschen (sehr unwahrscheinlich, aber es koennte eine andere neue grosse ellipse die nun entfernte beinhgalten - pech gehabt) - sub = 0; // was beim fortlaufenden loeschen abgezogen werden muss, da sich index verschiebt; considered ist immer aufsteigend!!! - for (j = 0; j < considered.size(); ++j) + // alles pyramiden ausser mit minIdx loeschen (sehr unwahrscheinlich, aber es koennte eine andere + // neue grosse ellipse die nun entfernte beinhgalten - pech gehabt) + sub = 0; // was beim fortlaufenden loeschen abgezogen werden muss, da sich index verschiebt; + // considered ist immer aufsteigend!!! + for(j = 0; j < considered.size(); ++j) { - if (j != minIdx) + if(j != minIdx) { #ifdef PRINT_ERASE_REASON - debout << "Eliminate pyramide because other pyramid nearer, with top ellipse: " << (*this)[considered.at(j)-sub].at(0).center().x() << " " << (*this)[considered.at(j)-sub].at(0).center().y() << endl; + debout << "Eliminate pyramide because other pyramid nearer, with top ellipse: " + << (*this)[considered.at(j) - sub].at(0).center().x() << " " + << (*this)[considered.at(j) - sub].at(0).center().y() << endl; #endif - removeAt(considered.at(j)-sub); + removeAt(considered.at(j) - sub); ++sub; } } @@ -592,7 +654,8 @@ void PersonList::insertEllipses(const QList<MyEllipse> &el, float distFromCam) / else { #ifdef PRINT_ERASE_REASON - debout << "Eliminate ellipse because of big aspect ratio and small size: " << el.at(i).center().x() << " " << el.at(i).center().y() << endl; + debout << "Eliminate ellipse because of big aspect ratio and small size: " << el.at(i).center().x() << " " + << el.at(i).center().y() << endl; #endif // debout << i << " " << el.size()<<endl; // el.removeAt(i); @@ -600,30 +663,37 @@ void PersonList::insertEllipses(const QList<MyEllipse> &el, float distFromCam) / // debout << "ratio falsch "<<endl; } } - for (j = 0; j < size(); ++j) // ueber existierende Personen, deren ellipsen kleiner sind + for(j = 0; j < size(); ++j) // ueber existierende Personen, deren ellipsen kleiner sind { (*this)[j].setActLevel(false); } } -// eigentlich muessten alle werte in abhaengigkeit von cm-schritten bei isolinen und auf pixel/cm abgestimmt sein!!!!!!!!!!!!!!!!!!! +// eigentlich muessten alle werte in abhaengigkeit von cm-schritten bei isolinen und auf pixel/cm abgestimmt +// sein!!!!!!!!!!!!!!!!!!! void PersonList::optimize() { - int minPyrLevel = myRound(20/STEP_SIZE) + 1; // mindesthoehe von 20 cm -// debout << minPyrLevel <<endl; - for (int i = 0; i < size(); ++i) // ueber uebergebene liste von ellipsen stacks + int minPyrLevel = myRound(20 / STEP_SIZE) + 1; // mindesthoehe von 20 cm + // debout << minPyrLevel <<endl; + for(int i = 0; i < size(); ++i) // ueber uebergebene liste von ellipsen stacks { -// float r1Max = 34./mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+10)); // war 37.cm // war 60 px // 60px in kopfhoehe sind 37cm in kopfhoehe // radius der ellips mit maxmalem radius 80 pixel -// float areaMin = 22./mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+100)); // 22. = 12.5*sqrt(Pi) wg area = r1*r2*Pi -// areaMin = areaMin*areaMin; -// if (at(i).size() == minPyrLevel-2 && at(i).last().area() >= areaMin && ((*(at(i).getHeadEllipse())).r1() <= r1Max)) -// debout << "15 cm Hoehe fuegt hinzu bei "<< at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; -// if (at(i).size() == minPyrLevel && at(i).last().area() >= areaMin && ((*(at(i).getHeadEllipse())).r1() <= r1Max)) -// debout << "25 cm Hoehe loescht bei "<< at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; - if (at(i).size() < minPyrLevel) // mindesthoehe von 20 cm // war 4 // pyramide eine mindesthoehe // myRound(25 cm / STEP_SIZE) + 1 + // float r1Max = 34./mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+10)); // war 37.cm // war 60 px // + // 60px in kopfhoehe sind 37cm in kopfhoehe // radius der ellips mit maxmalem radius 80 pixel float + // areaMin = 22./mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+100)); // 22. = 12.5*sqrt(Pi) wg area + // = r1*r2*Pi areaMin = areaMin*areaMin; if (at(i).size() == minPyrLevel-2 && at(i).last().area() >= + // areaMin && ((*(at(i).getHeadEllipse())).r1() <= r1Max)) + // debout << "15 cm Hoehe fuegt hinzu bei "<< at(i).at(0).center().x() << " " << + // at(i).at(0).center().y() << endl; + // if (at(i).size() == minPyrLevel && at(i).last().area() >= areaMin && ((*(at(i).getHeadEllipse())).r1() + // <= r1Max)) + // debout << "25 cm Hoehe loescht bei "<< at(i).at(0).center().x() << " " << at(i).at(0).center().y() + // << endl; + if(at(i).size() < minPyrLevel) // mindesthoehe von 20 cm // war 4 // pyramide eine mindesthoehe // myRound(25 cm + // / STEP_SIZE) + 1 { #ifdef PRINT_ERASE_REASON - debout << "Eliminate pyramide because of too small size ("<<at(i).size()<<"), with top ellipse: " << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; + debout << "Eliminate pyramide because of too small size (" << at(i).size() + << "), with top ellipse: " << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; #endif removeAt(i); --i; @@ -631,86 +701,113 @@ void PersonList::optimize() } // ab hier mindestens 4 ellipsen in pyramide (wenn 5 cm schritte, sonst auch weniger) - for (int i = 0; i < size(); ++i) // ueber uebergebene liste von ellipsen stacks - { // r1 ist immer die groessere ausdehnung - //debout << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << " " << at(i).last().area() << endl; - // at(i).getDistTopEllipse()+10) // in cm // 10 cm (eigentlich 10+step_size/2) unterhalb körpergröße - float r1Max = 34./mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+10)); // war 37.cm // war 60 px // 60px in kopfhoehe sind 37cm in kopfhoehe // radius der ellips mit maxmalem radius 80 pixel -// float r2Min = 12./mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+20)); // war 60 px // 60px in kopfhoehe sind 37cm in kopfhoehe // radius der ellips mit maxmalem radius 80 pixel - float areaMin = 22./mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+100)); // 22. = 12.5*sqrt(Pi) wg area = r1*r2*Pi - areaMin = areaMin*areaMin; -// float areaMin2 = 35.45/mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+100)); // 22. = 20*sqrt(Pi) wg area = r1*r2*Pi -// areaMin2 = areaMin2*areaMin2; -// // 1000 px^2 entspricht r1=r2 = 18 px = 12,5cm radius in oberschenkelhöhe bzw 100cm unterhalb kopf -// if (at(i).last().area() < areaMin2 && at(i).last().area() >= areaMin) -// debout << "1250 cm2 loescht bei " << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; - if (at(i).last().area() < areaMin) // war 1000 px // at(i).last().r1() < 15 nicht zu gross waehlen um auch nur kopferkennung in dichten situationen zuzulassen // war: area() < 1000) || // groesste ellips in pyr muss mindestgroesse besitzen + for(int i = 0; i < size(); ++i) // ueber uebergebene liste von ellipsen stacks + { // r1 ist immer die groessere ausdehnung + // debout << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << " " << at(i).last().area() << endl; + // at(i).getDistTopEllipse()+10) // in cm // 10 cm (eigentlich 10+step_size/2) unterhalb körpergröße + float r1Max = + 34. / + mSc->getCmPerPixel( + .01 * (at(i).getDistTopEllipse() + 10)); // war 37.cm // war 60 px // 60px in kopfhoehe sind 37cm in + // kopfhoehe // radius der ellips mit maxmalem radius 80 pixel + // float r2Min = 12./mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+20)); // war 60 px // 60px in + // kopfhoehe sind 37cm in kopfhoehe // radius der ellips mit maxmalem radius 80 pixel + float areaMin = + 22. / mSc->getCmPerPixel(.01 * (at(i).getDistTopEllipse() + 100)); // 22. = 12.5*sqrt(Pi) wg area = r1*r2*Pi + areaMin = areaMin * areaMin; + // float areaMin2 = 35.45/mSc->getCmPerPixel(.01*(at(i).getDistTopEllipse()+100)); // 22. = 20*sqrt(Pi) + // wg area = r1*r2*Pi areaMin2 = areaMin2*areaMin2; + // // 1000 px^2 entspricht r1=r2 = 18 px = 12,5cm radius in oberschenkelhöhe bzw 100cm unterhalb kopf + // if (at(i).last().area() < areaMin2 && at(i).last().area() >= areaMin) + // debout << "1250 cm2 loescht bei " << at(i).at(0).center().x() << " " << at(i).at(0).center().y() + // << endl; + if(at(i).last().area() < areaMin) // war 1000 px // at(i).last().r1() < 15 nicht zu gross waehlen um auch nur + // kopferkennung in dichten situationen zuzulassen // war: area() < 1000) || + // // groesste ellips in pyr muss mindestgroesse besitzen { #ifdef PRINT_ERASE_REASON - debout << "Eliminate pyramide because of too small ("<<at(i).last().area()<<" pixel^2) last ellipse, with top ellipse: " << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; + debout << "Eliminate pyramide because of too small (" << at(i).last().area() + << " pixel^2) last ellipse, with top ellipse: " << at(i).at(0).center().x() << " " + << at(i).at(0).center().y() << endl; #endif removeAt(i); --i; } - else if ((*(at(i).getHeadEllipse())).r1() > r1Max) // war 60px // 60px in kopfhoehe sind 37cm in kopfhoehe // area() > 3000)) // im kopfbereich (ca. at(1)) sollte ellipse nicht so gross sein + else if((*(at(i).getHeadEllipse())).r1() > r1Max) // war 60px // 60px in kopfhoehe sind 37cm in kopfhoehe // + // area() > 3000)) // im kopfbereich (ca. at(1)) sollte + // ellipse nicht so gross sein { #ifdef PRINT_ERASE_REASON - debout << "Eliminate pyramide because of too big head ellipse (norm. 2nd) (big radius: "<<(*(at(i).getHeadEllipse())).r1()<<" pixel), with top ellipse: " << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; + debout << "Eliminate pyramide because of too big head ellipse (norm. 2nd) (big radius: " + << (*(at(i).getHeadEllipse())).r1() << " pixel), with top ellipse: " << at(i).at(0).center().x() + << " " << at(i).at(0).center().y() << endl; #endif removeAt(i); --i; } -// // fuehrte zu zu haeufigen Fehlrausschmissen: -// //minPyrLevel-2 ist die letzte auf jeden fall noch vorkommende ellipse -// // size()<minPyrLevel, damit minPyrLevel-2 letzter index -// else if (at(i).at(minPyrLevel-2).r2() < r2Min) //war at(i)at(2).r1() < 10 // war: 20, um schlanke gebilde wie gehobenen arm auszuschliessen -// { -// //debout << minPyrLevel-1<<" " << r2Min<<endl; -//#ifdef PRINT_ERASE_REASON -// debout << "Eliminate pyramide because of too small third ellipse, with top ellipse: " << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; -//#endif -// removeAt(i); -// --i; -// } - // fuehrte zu fehlerhaften aussortieren bei virtueller scene onePerson wenn person mittig unter kamera war und arme neben sich hatte -// else if (at(i).last().r1()-at(i).at((int) ((at(i).size()-1)*.5)).r1() < 0.01) // der radius der unterste und mittlere ellips muessen sich unterscheiden, so dass objekte die nur in der hoehe aber nicht weiter nach unten gehen zu eleminieren; gesehen bei fehldetektion des hintergrundes an waenden -// { -//#ifdef PRINT_ERASE_REASON -// debout << "Eliminate pyramide because of equal big ellipses, with top ellipse: " << at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; -//#endif -// removeAt(i); -// --i; -// } + // // fuehrte zu zu haeufigen Fehlrausschmissen: + // //minPyrLevel-2 ist die letzte auf jeden fall noch vorkommende ellipse + // // size()<minPyrLevel, damit minPyrLevel-2 letzter index + // else if (at(i).at(minPyrLevel-2).r2() < r2Min) //war at(i)at(2).r1() < 10 // war: 20, um schlanke + // gebilde wie gehobenen arm auszuschliessen + // { + // //debout << minPyrLevel-1<<" " << r2Min<<endl; + //#ifdef PRINT_ERASE_REASON + // debout << "Eliminate pyramide because of too small third ellipse, with top ellipse: " << + // at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; + //#endif + // removeAt(i); + // --i; + // } + // fuehrte zu fehlerhaften aussortieren bei virtueller scene onePerson wenn person mittig unter kamera war und + // arme neben sich hatte + // else if (at(i).last().r1()-at(i).at((int) ((at(i).size()-1)*.5)).r1() < 0.01) // der radius der + // unterste und mittlere ellips muessen sich unterscheiden, so dass objekte die nur in der hoehe aber + // nicht weiter nach unten gehen zu eleminieren; gesehen bei fehldetektion des hintergrundes an waenden + // { + //#ifdef PRINT_ERASE_REASON + // debout << "Eliminate pyramide because of equal big ellipses, with top ellipse: " << + // at(i).at(0).center().x() << " " << at(i).at(0).center().y() << endl; + //#endif + // removeAt(i); + // --i; + // } } } // bestimmt kopfposition in markerlosen Ueberkopfaufnahmen aus Hoehenbild -void PersonList::calcPersonPos(const Mat &img, QRect &roi, QList<TrackPoint> &persList, pet::StereoContext *sc, BackgroundFilter *bgFilter, bool markerLess) +void PersonList::calcPersonPos( + const Mat & img, + QRect & roi, + QList<TrackPoint> & persList, + pet::StereoContext *sc, + BackgroundFilter * bgFilter, + bool markerLess) { int i, j; - if (!bgFilter->getEnabled()) // nur fuer den fall von bgSubtraction durchfuehren + if(!bgFilter->getEnabled()) // nur fuer den fall von bgSubtraction durchfuehren { - debout << "Warning: Person Detection without Background subtraction may cause a lot false detectiones!" <<endl; + debout << "Warning: Person Detection without Background subtraction may cause a lot false detectiones!" << endl; } searchEllipses(sc, roi, bgFilter); - if (!markerLess) // schon zuvor mit markern personen detektiert + if(!markerLess) // schon zuvor mit markern personen detektiert { bool found; - for (j = 0; j < persList.size(); ++j) + for(j = 0; j < persList.size(); ++j) { found = false; - for (i = 0; (!found) && (i < size()); ++i) + for(i = 0; (!found) && (i < size()); ++i) { - if (at(i).getHeadEllipse()->isInside(persList[j].x(),persList[j].y())) + if(at(i).getHeadEllipse()->isInside(persList[j].x(), persList[j].y())) { found = true; } } - if (!found) // wenn zuvor durch marker gefundene Person nicht in kopfellipse, dann loeschen - { // hier koennte auch nur die Qualitaet heruntergesetzt werden + if(!found) // wenn zuvor durch marker gefundene Person nicht in kopfellipse, dann loeschen + { // hier koennte auch nur die Qualitaet heruntergesetzt werden persList.removeAt(j); --j; } @@ -718,10 +815,10 @@ void PersonList::calcPersonPos(const Mat &img, QRect &roi, QList<TrackPoint> &pe } else { - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { Vec2F c(at(i).getHeadEllipse()->center()); // war at(i).at(1)... - if (!(c.x() < roi.left() || c.x() > roi.right() || c.y() < roi.top() || c.y() > roi.bottom())) + if(!(c.x() < roi.left() || c.x() > roi.right() || c.y() < roi.top() || c.y() > roi.bottom())) { TrackPoint tp(c, 100); // 100 beste qualitaet // hier koennte auch sofort x/y/z gesetzt werden @@ -730,186 +827,198 @@ void PersonList::calcPersonPos(const Mat &img, QRect &roi, QList<TrackPoint> &pe } } - /* - // kopf/koerpermodell, wobei kpfmittelpunkt in 0 liegt - // in cm - float model(float x, float y) - { - return 0.001*(x*x*x*x + y*y*y*y); - } + /* + // kopf/koerpermodell, wobei kpfmittelpunkt in 0 liegt + // in cm + float model(float x, float y) + { + return 0.001*(x*x*x*x + y*y*y*y); + } - //float errorModel(float x, float y) - //{ - // (rx-(medianX+j))*(rx-(medianX+j))+(ry-(medianY+i))*(ry-(medianY+i))+(rz-(medianZ+model(j,i)))*(rz-(medianZ+model(j,i))); - //} + //float errorModel(float x, float y) + //{ + // +(rx-(medianX+j))*(rx-(medianX+j))+(ry-(medianY+i))*(ry-(medianY+i))+(rz-(medianZ+model(j,i)))*(rz-(medianZ+model(j,i))); + //} - if (false) - { - int x, y, i, j, *sRow, sCol; - int frameSize=mMain->getControlWidget()->trackNumberSize->value(); // war 24 - unsigned short* data = (unsigned short*) mDisparity.imageData+frameSize/2; //war 500; // char* - unsigned short* yData = data+(mDisparity.width*frameSize/2); //war 300); - unsigned short* sData; - float val, rx, ry, rz, row, col; - float medianX, medianY, medianZ, diff, diffMin=100000., diffMax=0.; - int diffAnz, diffAnz2=0; - double diffMed=0; - - sRow = (int *) malloc((frameSize+1)*sizeof(int)); - CvSize sz = cvSize(mRectRight.width, mRectRight.height); - IplImage *tmpImg = cvCreateImage(sz, 8, 3); - CvMat *tmpMat = cvCreateMat(mRectRight.height, mRectRight.width, CV_32FC1); - //IplImage *tmpImg = cvCloneImage(&mRectRight); // make a copy - //debout << tmpImg->width << " " << tmpImg->height <<endl; - //debout << mDisparity.width << " " << mDisparity.widthStep <<endl; - - for (y = frameSize/2; y < mDisparity.height-frameSize/2; ++y) + if (false) + { + int x, y, i, j, *sRow, sCol; + int frameSize=mMain->getControlWidget()->trackNumberSize->value(); // war 24 + unsigned short* data = (unsigned short*) mDisparity.imageData+frameSize/2; //war 500; // char* + unsigned short* yData = data+(mDisparity.width*frameSize/2); //war 300); + unsigned short* sData; + float val, rx, ry, rz, row, col; + float medianX, medianY, medianZ, diff, diffMin=100000., diffMax=0.; + int diffAnz, diffAnz2=0; + double diffMed=0; + + sRow = (int *) malloc((frameSize+1)*sizeof(int)); + CvSize sz = cvSize(mRectRight.width, mRectRight.height); + IplImage *tmpImg = cvCreateImage(sz, 8, 3); + CvMat *tmpMat = cvCreateMat(mRectRight.height, mRectRight.width, CV_32FC1); + //IplImage *tmpImg = cvCloneImage(&mRectRight); // make a copy + //debout << tmpImg->width << " " << tmpImg->height <<endl; + //debout << mDisparity.width << " " << mDisparity.widthStep <<endl; + + for (y = frameSize/2; y < mDisparity.height-frameSize/2; ++y) + { + for (x = frameSize/2; x < mDisparity.width-frameSize/2; ++x) + { +// for (y = 300; y < 850; ++y) +// { +// for (x = 500; x < 900; ++x) +// { + + + // wenn hintergrund subtracxtion an, dann wird nur der vordergrund untersucht + if (( mMain->getBackgroundFilter()->getEnabled() && mMain->getBackgroundFilter()->isForeground(x, y) && +dispValueValid(*data)) || + (!mMain->getBackgroundFilter()->getEnabled() && dispValueValid(*data))) //(*data != mSurfaceValue+65280) +&& (*data != mBackForthValue+65280)) // 65280 == 0xff00 { - for (x = frameSize/2; x < mDisparity.width-frameSize/2; ++x) - { - // for (y = 300; y < 850; ++y) - // { - // for (x = 500; x < 900; ++x) - // { + diff=0.; + diffAnz=0; +// val = (*data-mMin)/(double)(mMax-mMin); // disp zwischen 0..1 +// if (val>0.5) +// { +// (tmpImg->imageData)[3*x+y*tmpImg->widthStep] = 255; +// (tmpImg->imageData)[3*x+y*tmpImg->widthStep+1] = 255; +// (tmpImg->imageData)[3*x+y*tmpImg->widthStep+2] = 255; +// } + getMedianXYZaround(x, y, &medianX, &medianY, &medianZ); // median in 5x5 umfeld um aktuellen pkt + // ohne beruecksichtigung der perspektive +// for (i = -frameSize/2; i <= frameSize/2; ++i) // y +// for (j = -frameSize/2; j <= frameSize/2; ++j) // x +// { +// sData = data+j+i*mDisparity.width; +// if (dispValueValid(*sData)) // Kopf soll -0.01*(x*x+y*y) annehmen // so gewaehlt, dass +pixel ca cm +// { +// triclopsRCD16ToXYZ(mTriclopsContext, y+i, x+j, *sData, &rx, &ry, &rz); +// rx *= 100.; ry *= 100.; rz *= 100.; // in cm +// +diff+=(rx-(medianX+j))*(rx-(medianX+j))+(ry-(medianY+i))*(ry-(medianY+i))+(rz-(medianZ+0.001*(j*j*j*j+i*i*i*i)))*(rz-(medianZ+0.001*(j*j*j*j+i*i*i*i))); +// ++diffAnz; +// } +// } + // pixel, an dem modell liegt wird bestimmt und dort die differenz zur disparity aufsummiert + // ACHTUNG wichtig, sonst fehelr: der nicht sichtbare kopfbereich wuerde auch auf pixel gemappt an dem +per disp die andere ansicht gegen nicht sichtbaren kopfbeeich verglichen wird - falsch! - // wenn hintergrund subtracxtion an, dann wird nur der vordergrund untersucht - if (( mMain->getBackgroundFilter()->getEnabled() && mMain->getBackgroundFilter()->isForeground(x, y) && dispValueValid(*data)) || - (!mMain->getBackgroundFilter()->getEnabled() && dispValueValid(*data))) //(*data != mSurfaceValue+65280) && (*data != mBackForthValue+65280)) // 65280 == 0xff00 - { - diff=0.; - diffAnz=0; - // val = (*data-mMin)/(double)(mMax-mMin); // disp zwischen 0..1 - // if (val>0.5) - // { - // (tmpImg->imageData)[3*x+y*tmpImg->widthStep] = 255; - // (tmpImg->imageData)[3*x+y*tmpImg->widthStep+1] = 255; - // (tmpImg->imageData)[3*x+y*tmpImg->widthStep+2] = 255; - // } - getMedianXYZaround(x, y, &medianX, &medianY, &medianZ); // median in 5x5 umfeld um aktuellen pkt - // ohne beruecksichtigung der perspektive - // for (i = -frameSize/2; i <= frameSize/2; ++i) // y - // for (j = -frameSize/2; j <= frameSize/2; ++j) // x - // { - // sData = data+j+i*mDisparity.width; - // if (dispValueValid(*sData)) // Kopf soll -0.01*(x*x+y*y) annehmen // so gewaehlt, dass pixel ca cm - // { - // triclopsRCD16ToXYZ(mTriclopsContext, y+i, x+j, *sData, &rx, &ry, &rz); - // rx *= 100.; ry *= 100.; rz *= 100.; // in cm - // diff+=(rx-(medianX+j))*(rx-(medianX+j))+(ry-(medianY+i))*(ry-(medianY+i))+(rz-(medianZ+0.001*(j*j*j*j+i*i*i*i)))*(rz-(medianZ+0.001*(j*j*j*j+i*i*i*i))); - // ++diffAnz; - // } - // } - // pixel, an dem modell liegt wird bestimmt und dort die differenz zur disparity aufsummiert - // ACHTUNG wichtig, sonst fehelr: der nicht sichtbare kopfbereich wuerde auch auf pixel gemappt an dem per disp die andere ansicht gegen nicht sichtbaren kopfbeeich verglichen wird - falsch! - - - //i, j in cm - for (i=0;i<=frameSize; ++i) - sRow[i] = -1; - for (i = -frameSize/2; i <= frameSize/2; ++i) // y + //i, j in cm + for (i=0;i<=frameSize; ++i) + sRow[i] = -1; + for (i = -frameSize/2; i <= frameSize/2; ++i) // y + { + sCol=-1; + for (j = -frameSize/2; j <= frameSize/2; ++j) // x + { // ich interpretier row und col genau anders herum: col = x row = y + triclopsXYZToRCD(mTriclopsContext, medianX+j, medianY+i, medianZ+model(j,i), &row, &col, &val); +// auf welchem pixel liegt modellform + // wenn resultierende col nicht mehr steigt, dann for-schleifen-abbruch + // erst beginnen mit dem zaehlen, wenn col mehr wird, auch wenn dann erstenes datum verworfen +wird if ((sRow[j+frameSize/2] < 0) || (myRound(row)<=sRow[j+frameSize/2]) || (sCol < 0) || (myRound(col)<=sCol)) { - sCol=-1; - for (j = -frameSize/2; j <= frameSize/2; ++j) // x - { // ich interpretier row und col genau anders herum: col = x row = y - triclopsXYZToRCD(mTriclopsContext, medianX+j, medianY+i, medianZ+model(j,i), &row, &col, &val); // auf welchem pixel liegt modellform - // wenn resultierende col nicht mehr steigt, dann for-schleifen-abbruch - // erst beginnen mit dem zaehlen, wenn col mehr wird, auch wenn dann erstenes datum verworfen wird - if ((sRow[j+frameSize/2] < 0) || - (myRound(row)<=sRow[j+frameSize/2]) || - (sCol < 0) || - (myRound(col)<=sCol)) - { - sRow[j+frameSize/2] = myRound(row); - sCol = myRound(col); - continue; - } + sRow[j+frameSize/2] = myRound(row); + sCol = myRound(col); + continue; + } - sCol = myRound(col); - sRow[j+frameSize/2] = myRound(row); - if (0<=sCol && sCol<mDisparity.width && 0<=sRow[j+frameSize/2] && sRow[j+frameSize/2]<mDisparity.height) - { - sData = ((unsigned short*) mDisparity.imageData) + sCol + sRow[j+frameSize/2]*mDisparity.width; - if (dispValueValid(*sData)) // hier kam es zum Absturz bevor vorvorheriges if eingefuegt wurde + sCol = myRound(col); + sRow[j+frameSize/2] = myRound(row); + if (0<=sCol && sCol<mDisparity.width && 0<=sRow[j+frameSize/2] && +sRow[j+frameSize/2]<mDisparity.height) + { + sData = ((unsigned short*) mDisparity.imageData) + sCol + sRow[j+frameSize/2]*mDisparity.width; + if (dispValueValid(*sData)) // hier kam es zum Absturz bevor vorvorheriges if eingefuegt wurde + { + triclopsRCD16ToXYZ(mTriclopsContext, sRow[j+frameSize/2], sCol, *sData, &rx, &ry, &rz); + rx *= 100.; ry *= 100.; rz *= 100.; // in cm + if +(i*i+j*j<mMain->getControlWidget()->trackColorMarkerSize->value()*mMain->getControlWidget()->trackColorMarkerSize->value()) +// war 120 kopf + { + diff += +(rx-(medianX+j))*(rx-(medianX+j))+(ry-(medianY+i))*(ry-(medianY+i))+(rz-(medianZ+model(j,i)))*(rz-(medianZ+model(j,i))); +// pow(a,2) + ++diffAnz; + } + else //fehler um kopfumfang 21cm alles was uber medianZ-30cm liegt als fehler gewichtet +(hoeher als Schulter) + { + val = rz-(medianZ+30.); // Abstand zur Schulter + val = (val>0?0:val*val); // oberhalb Schulter wird quadratisch negativ bewertet + if ((i<6 && y>=mDisparity.height/2) || + (i>6 && y<mDisparity.height/2) || + (j<6 && x>=mDisparity.width/2) || + (j>6 && x<mDisparity.width/2)) { - triclopsRCD16ToXYZ(mTriclopsContext, sRow[j+frameSize/2], sCol, *sData, &rx, &ry, &rz); - rx *= 100.; ry *= 100.; rz *= 100.; // in cm - if (i*i+j*j<mMain->getControlWidget()->trackColorMarkerSize->value()*mMain->getControlWidget()->trackColorMarkerSize->value()) // war 120 kopf - { - diff += (rx-(medianX+j))*(rx-(medianX+j))+(ry-(medianY+i))*(ry-(medianY+i))+(rz-(medianZ+model(j,i)))*(rz-(medianZ+model(j,i))); // pow(a,2) - ++diffAnz; - } - else //fehler um kopfumfang 21cm alles was uber medianZ-30cm liegt als fehler gewichtet (hoeher als Schulter) - { - val = rz-(medianZ+30.); // Abstand zur Schulter - val = (val>0?0:val*val); // oberhalb Schulter wird quadratisch negativ bewertet - if ((i<6 && y>=mDisparity.height/2) || - (i>6 && y<mDisparity.height/2) || - (j<6 && x>=mDisparity.width/2) || - (j>6 && x<mDisparity.width/2)) - { - diff += val; - ++diffAnz; - } - } - } + diff += val; + ++diffAnz; } - //if ((x==193 && y==237) || (x==1045 && y==264)) - // debout << (int)(i*i+j*j<120) << " " << x << " " << y << " " << j << " " << i << " " << sCol << " " << sRow[j+frameSize/2] << " " << diff << " " << endl; - // wenn resultierende row nicht mehr steigt, dann for-schleifen-abbruch } } - - - if (diffAnz < frameSize*frameSize/16) - diff = -2.; - else - { - diff/=diffAnz; - ++diffAnz2; - diffMed+=diff; - if (diff<diffMin) - diffMin=diff; - if (diff>diffMax) - diffMax=diff; } + //if ((x==193 && y==237) || (x==1045 && y==264)) + // debout << (int)(i*i+j*j<120) << " " << x << " " << y << " " << j << " " << i << " " << +sCol << " " << sRow[j+frameSize/2] << " " << diff << " " << endl; + // wenn resultierende row nicht mehr steigt, dann for-schleifen-abbruch } - else - diff = -1.; + } + - *(((float *)(tmpMat->data.ptr+y*tmpMat->step))+x) = diff;// step zaehlt in char!! - ++data; + if (diffAnz < frameSize*frameSize/16) + diff = -2.; + else + { + diff/=diffAnz; + ++diffAnz2; + diffMed+=diff; + if (diff<diffMin) + diffMin=diff; + if (diff>diffMax) + diffMax=diff; } - data = (yData += mDisparity.width); // falsch, da nicht mehr char sondern short: (yData += mDisparity.widthStep); // because sometimes widthStep != width } - diffMed=diffMed/diffAnz2; - debout << diffMin<< " " << diffMax<<" " << diffMed << endl; - free(sRow); + else + diff = -1.; - float zoom = 1000.*(diffMax-diffMed)/(diffMax-diffMin); - for (y = frameSize/2; y < mDisparity.height-frameSize/2; ++y) + *(((float *)(tmpMat->data.ptr+y*tmpMat->step))+x) = diff;// step zaehlt in char!! + ++data; + } + data = (yData += mDisparity.width); // falsch, da nicht mehr char sondern short: (yData += +mDisparity.widthStep); // because sometimes widthStep != width + } + diffMed=diffMed/diffAnz2; + debout << diffMin<< " " << diffMax<<" " << diffMed << endl; + free(sRow); + + float zoom = 1000.*(diffMax-diffMed)/(diffMax-diffMin); + for (y = frameSize/2; y < mDisparity.height-frameSize/2; ++y) + { + for (x = frameSize/2; x < mDisparity.width-frameSize/2; ++x) + { + val = *(((float *)(tmpMat->data.ptr+y*tmpMat->step))+x); + if (val<0) { - for (x = frameSize/2; x < mDisparity.width-frameSize/2; ++x) - { - val = *(((float *)(tmpMat->data.ptr+y*tmpMat->step))+x); - if (val<0) - { - (tmpImg->imageData)[3*x+y*tmpImg->widthStep] = 255; // blau - (tmpImg->imageData)[3*x+y*tmpImg->widthStep+1] = 0; - (tmpImg->imageData)[3*x+y*tmpImg->widthStep+2] = 0; - } - else - { - val = (val-diffMin)/(diffMax-diffMin); - //val = sqrt(val); - val = val>(1./zoom)?1:val*zoom; - val = 255-255*val; - (tmpImg->imageData)[3*x+y*tmpImg->widthStep] = val; - (tmpImg->imageData)[3*x+y*tmpImg->widthStep+1] = val; - (tmpImg->imageData)[3*x+y*tmpImg->widthStep+2] = val; - } - } + (tmpImg->imageData)[3*x+y*tmpImg->widthStep] = 255; // blau + (tmpImg->imageData)[3*x+y*tmpImg->widthStep+1] = 0; + (tmpImg->imageData)[3*x+y*tmpImg->widthStep+2] = 0; } + else + { + val = (val-diffMin)/(diffMax-diffMin); + //val = sqrt(val); + val = val>(1./zoom)?1:val*zoom; + val = 255-255*val; + (tmpImg->imageData)[3*x+y*tmpImg->widthStep] = val; + (tmpImg->imageData)[3*x+y*tmpImg->widthStep+1] = val; + (tmpImg->imageData)[3*x+y*tmpImg->widthStep+2] = val; + } + } + } // // weichzeichnen // IplImage *blurImg = cvCloneImage(&mDisparity); // make a copy @@ -942,7 +1051,8 @@ void PersonList::calcPersonPos(const Mat &img, QRect &roi, QList<TrackPoint> &pe // } // ++data; // } -// data = (yData += mDisparity.width); // falsch, da nicht mehr char sondern short: (yData += mDisparity.widthStep); // because sometimes widthStep != width +// data = (yData += mDisparity.width); // falsch, da nicht mehr char sondern short: (yData += +mDisparity.widthStep); // because sometimes widthStep != width // } // // lokale maxima rot markieren @@ -952,7 +1062,8 @@ void PersonList::calcPersonPos(const Mat &img, QRect &roi, QList<TrackPoint> &pe // { // for (x = frameSize/2; x < blurImg->width-frameSize/2; ++x) // { -// if (dispValueValid(*data)) //(*data != mSurfaceValue+65280) && (*data != mBackForthValue+65280)) // 65280 == 0xff00 +// if (dispValueValid(*data)) //(*data != mSurfaceValue+65280) && (*data != mBackForthValue+65280)) +// 65280 == 0xff00 // { // triclopsRCD16ToXYZ(mTriclopsContext, y, x, *data, &rx, &ry, &rz); // diff=1.; @@ -980,20 +1091,19 @@ void PersonList::calcPersonPos(const Mat &img, QRect &roi, QList<TrackPoint> &pe // } // ++data; // } -// data = (yData += blurImg->width); // falsch, da nicht mehr char sondern short: (yData += mDisparity.widthStep); // because sometimes widthStep != width +// data = (yData += blurImg->width); // falsch, da nicht mehr char sondern short: (yData += +mDisparity.widthStep); // because sometimes widthStep != width // } - //cvNamedWindow("mDisparity", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll - //cvShowImage("mDisparity", &mDisparity); - //cvNamedWindow("blurImg", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll - //cvShowImage("blurImg", blurImg); - cvNamedWindow("tmpImg", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll - cvShowImage("tmpImg", tmpImg); - //cvWaitKey( 0 ); // zahl statt null, wenn nach bestimmter zeit weitergegangen werden soll + //cvNamedWindow("mDisparity", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll + //cvShowImage("mDisparity", &mDisparity); + //cvNamedWindow("blurImg", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll + //cvShowImage("blurImg", blurImg); + cvNamedWindow("tmpImg", CV_WINDOW_AUTOSIZE ); // 0 wenn skalierbar sein soll + cvShowImage("tmpImg", tmpImg); + //cvWaitKey( 0 ); // zahl statt null, wenn nach bestimmter zeit weitergegangen werden soll - } + } */ - } #endif // STEREO_DISABLED - diff --git a/src/petrack.cpp b/src/petrack.cpp index 00cbb5f423bfa7784c09e1ff7b0eab641d09bceb..4ba37d2e134932dec6f0cb7014b1ce191575291b 100644 --- a/src/petrack.cpp +++ b/src/petrack.cpp @@ -18,84 +18,82 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> -#include <QtOpenGL> #include <QSignalMapper> +#include <QtOpenGL> +#include <QtWidgets> // Added for Qt5 support -#include <QtPrintSupport/QPrinter> -#include <QtPrintSupport/QPrintDialog> - -#include "stereoItem.h" -#include "stereoWidget.h" +#include "aboutDialog.h" +#include "animation.h" +#include "autoCalib.h" +#include "backgroundItem.h" +#include "calibFilter.h" +#include "codeMarkerWidget.h" #include "colorMarkerItem.h" -#include "multiColorMarkerItem.h" -#include "colorRangeWidget.h" #include "colorMarkerWidget.h" -#include "codeMarkerWidget.h" -#include "multiColorMarkerWidget.h" -#include "petrack.h" +#include "colorRangeWidget.h" #include "control.h" -#include "view.h" #include "gridItem.h" #include "imageItem.h" #include "logoItem.h" -#include "animation.h" -#include "player.h" -#include "calibFilter.h" -#include "autoCalib.h" -#include "trackerItem.h" -#include "backgroundItem.h" #include "moCapItem.h" +#include "multiColorMarkerItem.h" +#include "multiColorMarkerWidget.h" +#include "openMoCapDialog.h" +#include "pMessageBox.h" +#include "petrack.h" +#include "player.h" +#include "recognitionRoiItem.h" +#include "stereoItem.h" +#include "stereoWidget.h" #include "tracker.h" +#include "trackerItem.h" #include "trackerReal.h" -#include "pMessageBox.h" #include "trackingRoiItem.h" -#include "recognitionRoiItem.h" -#include "openMoCapDialog.h" +#include "view.h" -#include "aboutDialog.h" +#include <QtPrintSupport/QPrintDialog> +#include <QtPrintSupport/QPrinter> #ifdef AVI #include "aviFile.h" #else #include "aviFileWriter.h" #endif +#include "IO.h" #include "person.h" +#include <cmath> #include <ctime> #include <iomanip> -#include <cmath> - #include <opencv2/opencv.hpp> -#include "IO.h" -//temp muss spaeter herausgenommen werden, -// dient dazu, in anderen dateien um schnell ueber cw->temp1->value() an einstellbare daten zu kommen +// temp muss spaeter herausgenommen werden, +// dient dazu, in anderen dateien um schnell ueber cw->temp1->value() an einstellbare daten zu kommen Control *cw; int Petrack::trcVersion = 0; // Reihenfolge des anlegens der objekte ist sehr wichtig -Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPath()+ "/.zenodo.json")) +Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPath() + "/.zenodo.json")) { QIcon icon; - icon.addFile(":/icon"); // about + icon.addFile(":/icon"); // about icon.addFile(":/icon_smallest"); // window title bar setWindowIcon(icon); - mHeadSize = -1; - mCmPerPixel = -1; - mScene = nullptr; - mTracker = nullptr; - mTrackerReal = nullptr; // damit beim zeichnen von control mit analysePlot nicht auf einen feheler laeuft - mStatusLabelFPS = nullptr; + mHeadSize = -1; + mCmPerPixel = -1; + mScene = nullptr; + mTracker = nullptr; + mTrackerReal = nullptr; // damit beim zeichnen von control mit analysePlot nicht auf einen feheler laeuft + mStatusLabelFPS = nullptr; mStatusPosRealHeight = nullptr; - mStatusLabelPosReal = nullptr; - mImageItem = nullptr; - mRecognitionChanged = true; - mTrackChanged = true; - mCoordItem = nullptr; - mImage = nullptr; + mStatusLabelPosReal = nullptr; + mImageItem = nullptr; + mRecognitionChanged = true; + mTrackChanged = true; + mCoordItem = nullptr; + mImage = nullptr; setLoading(true); setAcceptDrops(true); @@ -107,13 +105,14 @@ Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPa mSwapFilter.disable(); mBackgroundFilter.disable(); mStereoContext = nullptr; - mCalibFilter = new CalibFilter; // schoener waere erst zu erzeugen, wenn video geladen wird, da sonst bei stereo erst normealer und dann stereo objekt erzeugt wird - mCalibFilter->disable(); // aber control widget greift schon bei erzeugung auf alle objekte zur einstellung zurueck + mCalibFilter = new CalibFilter; // schoener waere erst zu erzeugen, wenn video geladen wird, da sonst bei stereo + // erst normealer und dann stereo objekt erzeugt wird + mCalibFilter->disable(); // aber control widget greift schon bei erzeugung auf alle objekte zur einstellung zurueck mScene = new QGraphicsScene(this); mControlWidget = new Control(*this, *mScene, mReco); - cw = mControlWidget; // muss spaeter geloescht werden + cw = mControlWidget; // muss spaeter geloescht werden mStereoWidget = new StereoWidget(this); mStereoWidget->setWindowFlags(Qt::Window); @@ -142,7 +141,7 @@ Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPa mAnimation = new Animation(this); mLogoItem = new LogoItem(this); // durch uebergabe von scene wird indirekt ein scene->addItem() aufgerufen - mLogoItem->setZValue(6); // groesser heisst weiter oben + mLogoItem->setZValue(6); // groesser heisst weiter oben mExtrCalibration.setMainWindow(this); @@ -161,14 +160,34 @@ Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPa mViewWidget = new ViewWidget(this); - mView = mViewWidget->view(); + mView = mViewWidget->view(); mView->setScene(mScene); connect(mView, SIGNAL(mouseDoubleClick()), this, SLOT(openSequence())); - connect(mView, SIGNAL(mouseShiftDoubleClick(QPointF)), this, SLOT(addManualTrackPointOnlyVisible(QPointF))); //const QPoint &pos funktionierte nicht - connect(mView, SIGNAL(mouseShiftControlDoubleClick(QPointF)), this, SLOT(splitTrackPerson(QPointF))); //const QPoint &pos funktionierte nicht - connect(mView, SIGNAL(mouseControlDoubleClick(QPointF)), this, SLOT(addOrMoveManualTrackPoint(QPointF))); //const QPoint &pos funktionierte nicht - connect(mView, SIGNAL(mouseRightDoubleClick(QPointF, int)), this, SLOT(deleteTrackPoint(QPointF, int))); //const QPoint &pos funktionierte nicht - connect(mView, SIGNAL(mouseMiddleDoubleClick(int)), this, SLOT(deleteTrackPointAll(int))); //const QPoint &pos funktionierte nicht + connect( + mView, + SIGNAL(mouseShiftDoubleClick(QPointF)), + this, + SLOT(addManualTrackPointOnlyVisible(QPointF))); // const QPoint &pos funktionierte nicht + connect( + mView, + SIGNAL(mouseShiftControlDoubleClick(QPointF)), + this, + SLOT(splitTrackPerson(QPointF))); // const QPoint &pos funktionierte nicht + connect( + mView, + SIGNAL(mouseControlDoubleClick(QPointF)), + this, + SLOT(addOrMoveManualTrackPoint(QPointF))); // const QPoint &pos funktionierte nicht + connect( + mView, + SIGNAL(mouseRightDoubleClick(QPointF, int)), + this, + SLOT(deleteTrackPoint(QPointF, int))); // const QPoint &pos funktionierte nicht + connect( + mView, + SIGNAL(mouseMiddleDoubleClick(int)), + this, + SLOT(deleteTrackPointAll(int))); // const QPoint &pos funktionierte nicht connect(mView, SIGNAL(mouseShiftWheel(int)), this, SLOT(skipToFrameWheel(int))); mPlayerWidget = new Player(mAnimation, this); @@ -180,7 +199,7 @@ Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPa //--------------------------- - mTracker = new Tracker(this); + mTracker = new Tracker(this); mTrackerReal = new TrackerReal(this); mTrackerItem = new TrackerItem(this, mTracker); mTrackerItem->setZValue(5); // groesser heisst weiter oben @@ -193,23 +212,23 @@ Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPa //--------------------------- mStereoItem = new StereoItem(this); - mStereoItem->setZValue(2);// groesser heisst weiter oben + mStereoItem->setZValue(2); // groesser heisst weiter oben mStereoItem->setVisible(false); //--------------------------- mColorMarkerItem = new ColorMarkerItem(this); - mColorMarkerItem->setZValue(2);// groesser heisst weiter oben + mColorMarkerItem->setZValue(2); // groesser heisst weiter oben mColorMarkerItem->setVisible(false); //--------------------------- mCodeMarkerItem = new CodeMarkerItem(this, mReco.getCodeMarkerOptions()); - mCodeMarkerItem->setZValue(2);// groesser heisst weiter oben + mCodeMarkerItem->setZValue(2); // groesser heisst weiter oben mCodeMarkerItem->setVisible(false); //--------------------------- mMultiColorMarkerItem = new MultiColorMarkerItem(this); - mMultiColorMarkerItem->setZValue(2);// groesser heisst weiter oben + mMultiColorMarkerItem->setZValue(2); // groesser heisst weiter oben mMultiColorMarkerItem->setVisible(false); //--------------------------- @@ -254,8 +273,8 @@ Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPa mSplitter->addWidget(mControlWidget); - mSplitter->setStretchFactor(0,1); - mSplitter->setStretchFactor(1,0); + mSplitter->setStretchFactor(0, 1); + mSplitter->setStretchFactor(1, 0); mCentralLayout->addWidget(mSplitter); @@ -274,10 +293,10 @@ Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPa mReco.getCodeMarkerOptions().setControlWidget(mControlWidget); mReco.getCodeMarkerOptions().setCodeMarkerItem(mCodeMarkerItem); - mSeqFileName = QDir::currentPath(); //fuer allerersten Aufruf des Programms + mSeqFileName = QDir::currentPath(); // fuer allerersten Aufruf des Programms readSettings(); - saveXml(mDefaultSettings); //noch nicht noetig, da eh noch nicht fkt + saveXml(mDefaultSettings); // noch nicht noetig, da eh noch nicht fkt mShowFPS = 0; @@ -289,7 +308,7 @@ Petrack::Petrack() : mAuthors(IO::readAuthors(QCoreApplication::applicationDirPa // um im background subtraction filter das hoehenbild zu beruecksichtigen mBackgroundFilter.setStereoContext(&mStereoContext); - mAutoBackTrack = true; // ist der default, dann wenn in XML-Datei nicht drin steht + mAutoBackTrack = true; // ist der default, dann wenn in XML-Datei nicht drin steht mAutoTrackOptimizeColor = false; // ist der default, dann wenn in XML-Datei nicht drin steht setLoading(false); @@ -304,7 +323,7 @@ Petrack::~Petrack() void Petrack::dragEnterEvent(QDragEnterEvent *event) { - if (event->mimeData()->hasUrls()) + if(event->mimeData()->hasUrls()) event->acceptProposedAction(); } @@ -318,11 +337,11 @@ void Petrack::dragEnterEvent(QDragEnterEvent *event) */ void Petrack::dropEvent(QDropEvent *event) { - if (event->mimeData()->hasUrls()) + if(event->mimeData()->hasUrls()) { - if (event->mimeData()->urls().first().toLocalFile().right(4) == ".pet") + if(event->mimeData()->urls().first().toLocalFile().right(4) == ".pet") openProject(event->mimeData()->urls().first().toLocalFile()); - else if (event->mimeData()->urls().first().toLocalFile().right(4) == ".trc") + else if(event->mimeData()->urls().first().toLocalFile().right(4) == ".trc") importTracker(event->mimeData()->urls().first().toLocalFile()); else openSequence(event->mimeData()->urls().first().toLocalFile()); @@ -332,28 +351,28 @@ void Petrack::dropEvent(QDropEvent *event) void Petrack::updateSceneRect() { - double iW=0, iH=0, bS=0; + double iW = 0, iH = 0, bS = 0; - if (mImage) + if(mImage) { iW = mImage->width(); iH = mImage->height(); bS = getImageBorderSize(); } - if (mControlWidget->getCalibCoordShow()) + if(mControlWidget->getCalibCoordShow()) { - double scale=mControlWidget->getCalibCoordScale()/10.; - double tX=mControlWidget->getCalibCoordTransX()/10.; - double tY=mControlWidget->getCalibCoordTransY()/10.; + double scale = mControlWidget->getCalibCoordScale() / 10.; + double tX = mControlWidget->getCalibCoordTransX() / 10.; + double tY = mControlWidget->getCalibCoordTransY() / 10.; // setzen der bounding box der scene // Faktor 1.1 dient dazu, dass auch Zahl "1" bei coord gut in sichtbaren Bereich passt - double xMin = (tX-1.1*scale < -bS) ? tX-1.1*scale : -bS; - double yMin = (tY-1.1*scale < -bS) ? tY-1.1*scale : -bS; - double xMax = (tX+1.1*scale > iW-bS) ? tX+1.1*scale : iW-bS; - double yMax = (tY+1.1*scale > iH-bS) ? tY+1.1*scale : iH-bS; - mScene->setSceneRect(xMin, yMin, xMax-xMin, yMax-yMin); + double xMin = (tX - 1.1 * scale < -bS) ? tX - 1.1 * scale : -bS; + double yMin = (tY - 1.1 * scale < -bS) ? tY - 1.1 * scale : -bS; + double xMax = (tX + 1.1 * scale > iW - bS) ? tX + 1.1 * scale : iW - bS; + double yMax = (tY + 1.1 * scale > iH - bS) ? tY + 1.1 * scale : iH - bS; + mScene->setSceneRect(xMin, yMin, xMax - xMin, yMax - yMin); } else mScene->setSceneRect(-bS, -bS, iW, iH); @@ -367,124 +386,125 @@ void Petrack::updateSceneRect() */ void Petrack::openXml(QDomDocument &doc, bool openSeq) { - QDomElement root = doc.firstChildElement("PETRACK"); - QString seq; - int frame = -1, sourceFrameIn = -1, sourceFrameOut = -1; - double fps = DEFAULT_FPS; - int onlyPeopleNr = 1; - QString onlyPeopleNrList = "1"; - int zoom = 250, rotate = 0, hScroll = 0, vScroll = 0; + QString seq; + int frame = -1, sourceFrameIn = -1, sourceFrameOut = -1; + double fps = DEFAULT_FPS; + int onlyPeopleNr = 1; + QString onlyPeopleNrList = "1"; + int zoom = 250, rotate = 0, hScroll = 0, vScroll = 0; enum Camera cam = cameraUnset; setLoading(true); for(QDomElement elem = root.firstChildElement(); !elem.isNull(); elem = elem.nextSiblingElement()) { - if (elem.tagName() == "MAIN") + if(elem.tagName() == "MAIN") { - if (elem.hasAttribute("SRC")) + if(elem.hasAttribute("SRC")) { - seq = elem.attribute("SRC"); + seq = elem.attribute("SRC"); QString tmpSeq = getExistingFile(seq, mProFileName); - if (tmpSeq != "") + if(tmpSeq != "") seq = tmpSeq; } - if (elem.hasAttribute("STATUS_HEIGHT")) + if(elem.hasAttribute("STATUS_HEIGHT")) { - if (mStatusPosRealHeight) // null kann eigentlich nicht vorkommen, da im constructor von petrack erzeugt wird + if(mStatusPosRealHeight) // null kann eigentlich nicht vorkommen, da im constructor von petrack erzeugt + // wird mStatusPosRealHeight->setValue(elem.attribute("STATUS_HEIGHT").toDouble()); } } - else if (elem.tagName() == "STEREO") + else if(elem.tagName() == "STEREO") { mStereoWidget->getXml(elem); } - else if (elem.tagName() == "COLOR_MARKER") + else if(elem.tagName() == "COLOR_MARKER") { mColorMarkerWidget->getXml(elem); } - else if (elem.tagName() == "CODE_MARKER") + else if(elem.tagName() == "CODE_MARKER") { mCodeMarkerWidget->getXml(elem); } - else if (elem.tagName() == "MULTI_COLOR_MARKER") + else if(elem.tagName() == "MULTI_COLOR_MARKER") { mMultiColorMarkerWidget->getXml(elem); } - else if (elem.tagName() == "MOCAP") + else if(elem.tagName() == "MOCAP") { mMoCapController.getXml(elem); } - else if (elem.tagName() == "CONTROL") + else if(elem.tagName() == "CONTROL") { mControlWidget->getXml(elem); QDomElement tmpElem = (elem.firstChildElement("TRACKING")).firstChildElement("PATH"); - if (tmpElem.hasAttribute("ONLY_PEOPLE_NR")) + if(tmpElem.hasAttribute("ONLY_PEOPLE_NR")) onlyPeopleNr = tmpElem.attribute("ONLY_PEOPLE_NR").toInt(); - if (tmpElem.hasAttribute("ONLY_PEOPLE_NR_LIST")) + if(tmpElem.hasAttribute("ONLY_PEOPLE_NR_LIST")) onlyPeopleNrList = tmpElem.attribute("ONLY_PEOPLE_NR_LIST"); } - else if (elem.tagName() == "EXTR_CALIBRATION") + else if(elem.tagName() == "EXTR_CALIBRATION") { mExtrCalibration.getXml(elem); } - else if (elem.tagName() == "PLAYER") + else if(elem.tagName() == "PLAYER") { - if (elem.hasAttribute("FRAME")) + if(elem.hasAttribute("FRAME")) { frame = elem.attribute("FRAME").toInt(); } - if (elem.hasAttribute("FPS")) + if(elem.hasAttribute("FPS")) { fps = elem.attribute("FPS").toDouble(); } - if (elem.hasAttribute("SOURCE_FRAME_IN")) + if(elem.hasAttribute("SOURCE_FRAME_IN")) { sourceFrameIn = elem.attribute("SOURCE_FRAME_IN").toInt(); } - if (elem.hasAttribute("SOURCE_FRAME_OUT")) + if(elem.hasAttribute("SOURCE_FRAME_OUT")) { sourceFrameOut = elem.attribute("SOURCE_FRAME_OUT").toInt(); } - if (elem.hasAttribute("PLAYER_SPEED_FIXED")) + if(elem.hasAttribute("PLAYER_SPEED_FIXED")) { mPlayerWidget->setPlayerSpeedLimited(elem.attribute("PLAYER_SPEED_FIXED").toInt()); } } - else if (elem.tagName() == "VIEW") + else if(elem.tagName() == "VIEW") { - if (elem.hasAttribute("ANTIALIAS")) + if(elem.hasAttribute("ANTIALIAS")) { mAntialiasAct->setChecked(elem.attribute("ANTIALIAS").toInt() == Qt::Checked); } - if (elem.hasAttribute("OPENGL")) + if(elem.hasAttribute("OPENGL")) { mOpenGLAct->setChecked(elem.attribute("OPENGL").toInt() == Qt::Checked); } - if (elem.hasAttribute("SAVE_TRANSFORMED")) + if(elem.hasAttribute("SAVE_TRANSFORMED")) { mCropZoomViewAct->setChecked(elem.attribute("SAVE_TRANSFORMED") == Qt::Checked); } - if (elem.hasAttribute("TRANSFORMATION")) + if(elem.hasAttribute("TRANSFORMATION")) { - QString matStr = elem.attribute("TRANSFORMATION"); + QString matStr = elem.attribute("TRANSFORMATION"); QTextStream in(&matStr); in >> zoom >> rotate >> hScroll >> vScroll; } - if (elem.hasAttribute("CAMERA")) + if(elem.hasAttribute("CAMERA")) { cam = (enum Camera) elem.attribute("CAMERA").toInt(); } - if (elem.hasAttribute("HIDE_CONTROLS")) + if(elem.hasAttribute("HIDE_CONTROLS")) { mHideControlsAct->setChecked(elem.attribute("HIDE_CONTROLS").toInt() == Qt::Checked); } - } else if (elem.tagName() == "AUTO_TRACK") + } + else if(elem.tagName() == "AUTO_TRACK") { - if (elem.hasAttribute("BACK_TRACK")) + if(elem.hasAttribute("BACK_TRACK")) { mAutoBackTrack = elem.attribute("BACK_TRACK").toInt(); } - if (elem.hasAttribute("OPTIMZE_COLOR")) + if(elem.hasAttribute("OPTIMZE_COLOR")) { mAutoTrackOptimizeColor = elem.attribute("OPTIMZE_COLOR").toInt(); } @@ -495,7 +515,7 @@ void Petrack::openXml(QDomDocument &doc, bool openSeq) // open koennte am schluss passieren, dann wuerde nicht erst unveraendertes bild angezeigt, // dafuer koennte es aber sein, dass werte zb bei fx nicht einstellbar sind! - if (openSeq && (seq != "")) + if(openSeq && (seq != "")) openSequence(seq); // wenn leer, dann kommt abfrage hoch, welche datei; abbrechen, wenn aktuelle gewuenscht mViewWidget->setZoomLevel(zoom); @@ -504,33 +524,34 @@ void Petrack::openXml(QDomDocument &doc, bool openSeq) mView->verticalScrollBar()->setValue(vScroll); bool loaded = false; - if (!mBackgroundFilter.getFilename().isEmpty()) + if(!mBackgroundFilter.getFilename().isEmpty()) { - if (!(loaded = mBackgroundFilter.load(mBackgroundFilter.getFilename()))) + if(!(loaded = mBackgroundFilter.load(mBackgroundFilter.getFilename()))) debout << "Error: loading background file " << mBackgroundFilter.getFilename() << "!" << std::endl; } - mPlayerWidget->setFrameInNum( sourceFrameIn == -1 ? mAnimation->getSourceInFrameNum() : sourceFrameIn ); - mPlayerWidget->setFrameOutNum( sourceFrameOut == -1 ? mAnimation->getSourceOutFrameNum() : sourceFrameOut ); + mPlayerWidget->setFrameInNum(sourceFrameIn == -1 ? mAnimation->getSourceInFrameNum() : sourceFrameIn); + mPlayerWidget->setFrameOutNum(sourceFrameOut == -1 ? mAnimation->getSourceOutFrameNum() : sourceFrameOut); mPlayerWidget->update(); - if (frame != -1) + if(frame != -1) { - if (mControlWidget->filterBg->isChecked() && !loaded)// mit dem anfangs geladenen bild wurde bereits faelschlicherweise bg bestimmt + if(mControlWidget->filterBg->isChecked() && + !loaded) // mit dem anfangs geladenen bild wurde bereits faelschlicherweise bg bestimmt mBackgroundFilter.reset(); // erst nach dem springen zu einem frame background bestimmen mPlayerWidget->skipToFrame(frame); // hier wird updateImage ausgefuehrt } - else if (loaded) + else if(loaded) updateImage(); // nicht schon in control, sonst loescht opensequence wieder tracker - if (mTrcFileName != "") + if(mTrcFileName != "") { // vorher loeschen aller trajektorien, da sonst nach start im ersten bild // mgl zwei trackpoints // beim haendischen importieren sind weiterhin parallele trajektorien moeglich (warnung wird ausgegeben) frame = 0; // default - if ((mTracker->largestLastFrame() >= frame) && (mTracker->smallestFirstFrame() <= frame)) + if((mTracker->largestLastFrame() >= frame) && (mTracker->smallestFirstFrame() <= frame)) { mTracker->clear(); mTracker->reset(); @@ -541,37 +562,39 @@ void Petrack::openXml(QDomDocument &doc, bool openSeq) mControlWidget->trackShowOnlyNr->setValue(onlyPeopleNr); mControlWidget->trackShowOnlyNrList->setText(onlyPeopleNrList); - if (cam == cameraLeft) + if(cam == cameraLeft) mCameraLeftViewAct->setChecked(true); - else if (cam == cameraRight) + else if(cam == cameraRight) mCameraRightViewAct->setChecked(true); setCamera(); mPlayerWidget->setFPS(fps); // erst spaet setzen, damit Wert den des geladenen Videos ueberschreiben kann setLoading(false); - } void Petrack::openProject(QString fileName, bool openSeq) // default fileName="", openSequence = true { - if (!QFileInfo(mProFileName).isDir()) // a project is already loaded - if (!maybeSave()) + if(!QFileInfo(mProFileName).isDir()) // a project is already loaded + if(!maybeSave()) return; // if no destination file or folder is given - if (fileName.isEmpty()) - fileName = QFileDialog::getOpenFileName(this, tr("Select project file"), QFileInfo(mProFileName).path(), - tr("PeTrack project file (*.pet);;All files (*.*)")); - - if (!fileName.isEmpty()) + if(fileName.isEmpty()) + fileName = QFileDialog::getOpenFileName( + this, + tr("Select project file"), + QFileInfo(mProFileName).path(), + tr("PeTrack project file (*.pet);;All files (*.*)")); + + if(!fileName.isEmpty()) { QFile file(fileName); - if (!file.open(QIODevice::ReadOnly)) + if(!file.open(QIODevice::ReadOnly)) { PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(fileName, file.errorString())); return; } resetSettings(); QDomDocument doc("PETRACK"); // eigentlich Pfad zu Beschreibungsdatei fuer Dateiaufbau - if (!doc.setContent(&file)) + if(!doc.setContent(&file)) { PCritical(this, tr("PeTrack"), tr("Cannot read content from %1.").arg(fileName)); file.close(); @@ -583,11 +606,15 @@ void Petrack::openProject(QString fileName, bool openSeq) // default fileName="" setProFileName(fileName); QDomElement root = doc.firstChildElement("PETRACK"); - if (root.hasAttribute("VERSION")) + if(root.hasAttribute("VERSION")) { - if (root.attribute("VERSION") != mPetrackVersion) + if(root.attribute("VERSION") != mPetrackVersion) { - PWarning(this, tr("PeTrack"), tr("Reading %1:\nDifferent version numbers %2 (application) and %3 (file) may cause problems.").arg(fileName, mPetrackVersion, root.attribute("VERSION"))); + PWarning( + this, + tr("PeTrack"), + tr("Reading %1:\nDifferent version numbers %2 (application) and %3 (file) may cause problems.") + .arg(fileName, mPetrackVersion, root.attribute("VERSION"))); } } openXml(doc, openSeq); @@ -604,9 +631,9 @@ void Petrack::saveXml(QDomDocument &doc) doc.appendChild(root); // main settings (window size, status hight) - elem = doc.createElement("MAIN"); + elem = doc.createElement("MAIN"); QString seq = ""; - if (mImage) + if(mImage) seq = getFileList(mSeqFileName, mProFileName); elem.setAttribute("SRC", seq); @@ -663,7 +690,13 @@ void Petrack::saveXml(QDomDocument &doc) elem.setAttribute("ANTIALIAS", mAntialiasAct->isChecked()); elem.setAttribute("OPENGL", mOpenGLAct->isChecked()); elem.setAttribute("SAVE_TRANSFORMED", mCropZoomViewAct->isChecked()); - elem.setAttribute("TRANSFORMATION", QString("%1 %2 %3 %4").arg(mViewWidget->getZoomLevel()).arg(mViewWidget->getRotateLevel()).arg(mView->horizontalScrollBar()->value()).arg(mView->verticalScrollBar()->value())); + elem.setAttribute( + "TRANSFORMATION", + QString("%1 %2 %3 %4") + .arg(mViewWidget->getZoomLevel()) + .arg(mViewWidget->getRotateLevel()) + .arg(mView->horizontalScrollBar()->value()) + .arg(mView->verticalScrollBar()->value())); #ifndef STEREO_DISABLED elem.setAttribute("CAMERA", mAnimation->getCamera()); #else @@ -689,21 +722,21 @@ bool Petrack::saveSameProject() bool Petrack::saveProject(QString fileName) // default fileName="" { // if no destination file or folder is given - if (fileName.isEmpty() || QFileInfo(mProFileName).isDir()) + if(fileName.isEmpty() || QFileInfo(mProFileName).isDir()) { - fileName = QFileDialog::getSaveFileName(this, tr("Select project file"), mProFileName, - tr("PeTrack project file (*.pet);;All files (*.*)")); + fileName = QFileDialog::getSaveFileName( + this, tr("Select project file"), mProFileName, tr("PeTrack project file (*.pet);;All files (*.*)")); } - if (!fileName.isEmpty()) + if(!fileName.isEmpty()) { setProFileName(fileName); QDomDocument doc("PETRACK"); // eigentlich Pfad zu Beschreibungsdatei fuer Dateiaufbau saveXml(doc); // file output - QByteArray byteArray; - QXmlStreamWriter xmlStream (&byteArray); + QByteArray byteArray; + QXmlStreamWriter xmlStream(&byteArray); xmlStream.setAutoFormatting(true); xmlStream.setAutoFormattingIndent(4); @@ -716,7 +749,7 @@ bool Petrack::saveProject(QString fileName) // default fileName="" xmlStream.writeEndDocument(); QFile file(fileName); - if (!file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) + if(!file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { PCritical(this, tr("PeTrack"), tr("Cannot save %1:\n%2.").arg(fileName, file.errorString())); file.close(); @@ -735,29 +768,33 @@ bool Petrack::saveProject(QString fileName) // default fileName="" return false; } -void Petrack::writeXmlElement(QXmlStreamWriter& xmlStream, QDomElement element) +void Petrack::writeXmlElement(QXmlStreamWriter &xmlStream, QDomElement element) { xmlStream.writeStartElement(element.tagName()); - QVector<QString> attribute_names; + QVector<QString> attribute_names; const QDomNamedNodeMap attributes = element.attributes(); - for(int i = 0; i < attributes.size(); ++i){ + for(int i = 0; i < attributes.size(); ++i) + { attribute_names.push_back(attributes.item(i).toAttr().name()); } - //TODO: check if sorting of elements fits our needs + // TODO: check if sorting of elements fits our needs std::stable_sort(attribute_names.begin(), attribute_names.end()); // for a canonical XML // Wants this macro instead of range-based for loop - foreach(QString name, attribute_names){ + foreach(QString name, attribute_names) + { QDomAttr attr = element.attributeNode(name); xmlStream.writeAttribute(attr.name(), attr.value()); } // order of child nodes is defined at creation - if(element.hasChildNodes()){ + if(element.hasChildNodes()) + { const QDomNodeList children = element.childNodes(); - for(int i = 0; i < children.size(); ++i){ + for(int i = 0; i < children.size(); ++i) + { writeXmlElement(xmlStream, children.at(i).toElement()); } } @@ -771,25 +808,26 @@ void Petrack::writeXmlElement(QXmlStreamWriter& xmlStream, QDomElement element) */ void Petrack::openCameraLiveStream(int camID /* =-1*/) { - if (camID == -1) + if(camID == -1) { // if more than one camera connected show to choose - //camID = selectedID; + // camID = selectedID; debout << "No camera ID delivered: Set CameraID to 0 (default Camera)" << std::endl; camID = 0; // default - } - if (!mAnimation->openCameraStream(camID)) + if(!mAnimation->openCameraStream(camID)) { PCritical(this, tr("PeTrack"), tr("Cannot start Camera Livestream.")); return; } mSeqFileName = "camera live stream"; - debout << "open " << mSeqFileName << " (" << mAnimation->getNumFrames() << " frames; " << mAnimation->getFPS() << " fps; " << mAnimation->getSize().width() << "x" << mAnimation->getSize().height() << " pixel)" << std::endl; //size + debout << "open " << mSeqFileName << " (" << mAnimation->getNumFrames() << " frames; " << mAnimation->getFPS() + << " fps; " << mAnimation->getSize().width() << "x" << mAnimation->getSize().height() << " pixel)" + << std::endl; // size updateSequence(); updateWindowTitle(); mPlayerWidget->setFPS(mAnimation->getFPS()); - if (mOpenGLAct->isChecked()) + if(mOpenGLAct->isChecked()) mLogoItem->fadeOut(1); else mLogoItem->fadeOut(50); @@ -800,12 +838,20 @@ void Petrack::openCameraLiveStream(int camID /* =-1*/) void Petrack::openSequence(QString fileName) // default fileName = "" { - if (fileName.isEmpty()) - fileName = QFileDialog::getOpenFileName(this, tr("Open video or image sequence"), QFileInfo(mSeqFileName).path(), - tr("All supported types (*.avi *.mpg *.mts *.m2t *.m2ts *.wmv *.mp4 *.mov *.mxf *.bmp *.dib *.jpeg *.jpg *.jpe *.png *.pbm *.pgm *.ppm *.sr *.ras *.tiff *.tif *.exr *.jp2);;Video (*.avi *.mpg *.mts *.m2ts *.m2t *.wmv *.mov *.mp4 *.mxf);;Images (*.bmp *.dib *.jpeg *.jpg *.jpe *.png *.pbm *.pgm *.ppm *.sr *.ras *.tiff *.tif *.exr *.jp2);;Windows bitmaps (*.bmp *.dib);;JPEG (*.jpeg *.jpg *.jpe);;Portable network graphics (*.png);;Portable image format (*.pbm *.pgm *.ppm);;Sun rasters (*.sr *.ras);;TIFF (*.tiff *.tif);;OpenEXR HDR (*.exr);;JPEG 2000 (*.jp2);;All files (*.*)")); - if (!fileName.isEmpty()) + if(fileName.isEmpty()) + fileName = QFileDialog::getOpenFileName( + this, + tr("Open video or image sequence"), + QFileInfo(mSeqFileName).path(), + tr("All supported types (*.avi *.mpg *.mts *.m2t *.m2ts *.wmv *.mp4 *.mov *.mxf *.bmp *.dib *.jpeg *.jpg " + "*.jpe *.png *.pbm *.pgm *.ppm *.sr *.ras *.tiff *.tif *.exr *.jp2);;Video (*.avi *.mpg *.mts *.m2ts " + "*.m2t *.wmv *.mov *.mp4 *.mxf);;Images (*.bmp *.dib *.jpeg *.jpg *.jpe *.png *.pbm *.pgm *.ppm *.sr " + "*.ras *.tiff *.tif *.exr *.jp2);;Windows bitmaps (*.bmp *.dib);;JPEG (*.jpeg *.jpg *.jpe);;Portable " + "network graphics (*.png);;Portable image format (*.pbm *.pgm *.ppm);;Sun rasters (*.sr *.ras);;TIFF " + "(*.tiff *.tif);;OpenEXR HDR (*.exr);;JPEG 2000 (*.jp2);;All files (*.*)")); + if(!fileName.isEmpty()) { - if (!mAnimation->openAnimation(fileName)) + if(!mAnimation->openAnimation(fileName)) { PCritical(this, tr("PeTrack"), tr("Cannot load %1.").arg(fileName)); return; @@ -815,23 +861,23 @@ void Petrack::openSequence(QString fileName) // default fileName = "" mCameraMenu->setEnabled(mAnimation->isStereoVideo()); #ifdef STEREO - if (mAnimation->isStereoVideo()) + if(mAnimation->isStereoVideo()) { - if (mStereoContext) + if(mStereoContext) delete mStereoContext; mStereoContext = new pet::StereoContext(this); } bool lastIsStereoVideo = mAnimation->isStereoVideo(); - if (mCalibFilter == NULL || (mAnimation->isStereoVideo() != lastIsStereoVideo)) + if(mCalibFilter == NULL || (mAnimation->isStereoVideo() != lastIsStereoVideo)) { bool lastCalibFilterEnabled = false; - if (mCalibFilter != NULL) + if(mCalibFilter != NULL) { lastCalibFilterEnabled = mCalibFilter->getEnabled(); delete mCalibFilter; } - if (mAnimation->isStereoVideo()) + if(mAnimation->isStereoVideo()) { mCalibFilter = new CalibStereoFilter; ((CalibStereoFilter *) mCalibFilter)->setStereoContext(mStereoContext); @@ -842,11 +888,13 @@ void Petrack::openSequence(QString fileName) // default fileName = "" } #endif mSeqFileName = fileName; - debout << "open " << mSeqFileName << " (" << mAnimation->getNumFrames() << " frames; " << mAnimation->getFPS() << " fps; " << mAnimation->getSize().width() << "x" << mAnimation->getSize().height() << " pixel)" << std::endl; //size + debout << "open " << mSeqFileName << " (" << mAnimation->getNumFrames() << " frames; " << mAnimation->getFPS() + << " fps; " << mAnimation->getSize().width() << "x" << mAnimation->getSize().height() << " pixel)" + << std::endl; // size updateSequence(); updateWindowTitle(); mPlayerWidget->setFPS(mAnimation->getFPS()); - if (mOpenGLAct->isChecked()) + if(mOpenGLAct->isChecked()) mLogoItem->fadeOut(1); else mLogoItem->fadeOut(50); @@ -854,7 +902,8 @@ void Petrack::openSequence(QString fileName) // default fileName = "" } } -void Petrack::openMoCapFile(){ +void Petrack::openMoCapFile() +{ OpenMoCapDialog dialog(this, mMoCapController); dialog.exec(); } @@ -862,20 +911,22 @@ void Petrack::openMoCapFile(){ void Petrack::updateWindowTitle() { QString title; - QSize size = mAnimation->getSize(); + QSize size = mAnimation->getSize(); - if (QFileInfo(mProFileName).isDir()) + if(QFileInfo(mProFileName).isDir()) title = tr("PeTrack (v") + mPetrackVersion + tr("): "); else { title = tr("PeTrack (v") + mPetrackVersion + tr("): ") + QFileInfo(mProFileName).fileName(); - if (mAnimation->isVideo() || mAnimation->isImageSequence()) - title += "; "; + if(mAnimation->isVideo() || mAnimation->isImageSequence()) + title += "; "; } - if (mAnimation->isVideo()) - title += "sequence: " + mAnimation->getCurrentFileName() + tr(" (%1").arg(mAnimation->getNumFrames()) + tr(" frames; %1x%2").arg(size.width()).arg(size.height()) + " pixel)"; - else if (mAnimation->isImageSequence()) - title += "sequence: " + mAnimation->getCurrentFileName() + tr(" ... (%1").arg(mAnimation->getNumFrames()) + tr(" frames; %1x%2").arg(size.width()).arg(size.height()) + " pixel)"; + if(mAnimation->isVideo()) + title += "sequence: " + mAnimation->getCurrentFileName() + tr(" (%1").arg(mAnimation->getNumFrames()) + + tr(" frames; %1x%2").arg(size.width()).arg(size.height()) + " pixel)"; + else if(mAnimation->isImageSequence()) + title += "sequence: " + mAnimation->getCurrentFileName() + tr(" ... (%1").arg(mAnimation->getNumFrames()) + + tr(" frames; %1x%2").arg(size.width()).arg(size.height()) + " pixel)"; setWindowTitle(title); } @@ -910,136 +961,157 @@ void Petrack::saveViewSequence() void Petrack::saveSequence(bool saveVideo, bool saveView, QString dest) // default saveView= false, dest="" { static QString lastDir; -// bool autoSave = false; + // bool autoSave = false; // if no destination file or folder is given - if (dest.isEmpty()) + if(dest.isEmpty()) { - if (lastDir.isEmpty() && !mSeqFileName.isEmpty()) + if(lastDir.isEmpty() && !mSeqFileName.isEmpty()) lastDir = QFileInfo(mSeqFileName).path(); - if (saveVideo) + if(saveVideo) { - dest = QFileDialog::getSaveFileName(this, tr("Select video file"), lastDir, - tr("Video (*.avi);;All files (*.*)")); //? *.mpg *.mpeg + dest = QFileDialog::getSaveFileName( + this, + tr("Select video file"), + lastDir, + tr("Video (*.avi);;All files (*.*)")); //? *.mpg *.mpeg } else { - if (saveView) - dest = QFileDialog::getExistingDirectory(this, tr("Select directory to save view sequence"), - lastDir, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + if(saveView) + dest = QFileDialog::getExistingDirectory( + this, + tr("Select directory to save view sequence"), + lastDir, + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); else - dest = QFileDialog::getExistingDirectory(this, tr("Select directory to save image sequence"), - lastDir, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + dest = QFileDialog::getExistingDirectory( + this, + tr("Select directory to save image sequence"), + lastDir, + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); } } else // uebergabe von saveVideo spielt keine roll mehr, sondern wird hier analysiert anhand von Dateiendung { -// autoSave = true; // command line option - if (dest.right(4) == ".avi") + // autoSave = true; // command line option + if(dest.right(4) == ".avi") saveVideo = true; else saveVideo = false; } - if (!dest.isEmpty() && mImage) + if(!dest.isEmpty() && mImage) { - int rest = mAnimation->getNumFrames()-1; - int numLength = 1; - int memPos = mPlayerWidget->getPos(); - QString fileName = ""; + int rest = mAnimation->getNumFrames() - 1; + int numLength = 1; + int memPos = mPlayerWidget->getPos(); + QString fileName = ""; #ifdef AVI AviFile aviFile; #else AviFileWriter aviFile; #endif - bool formatIsSaveAble = false; - bool saveRet; - QImage *viewImage = nullptr; - QPainter *painter = nullptr; - int progEnd = mAnimation->getSourceOutFrameNum()-mPlayerWidget->getPos(); // nur wenn nicht an anfang gesprungen wird:-mPlayerWidget->getPos() + bool formatIsSaveAble = false; + bool saveRet; + QImage * viewImage = nullptr; + QPainter *painter = nullptr; + int progEnd = mAnimation->getSourceOutFrameNum() - + mPlayerWidget->getPos(); // nur wenn nicht an anfang gesprungen wird:-mPlayerWidget->getPos() cv::Mat iplImgFilteredBGR; - bool writeFrameRet = false; - bool convert8To24bit = false; - int mult; + bool writeFrameRet = false; + bool convert8To24bit = false; + int mult; - if (saveVideo) + if(saveVideo) { - if (saveView) + if(saveView) { - if (mCropZoomViewAct->isChecked()) - viewImage = new QImage(mView->viewport()->width(), mView->viewport()->height(), QImage::Format_RGB32); + if(mCropZoomViewAct->isChecked()) + viewImage = + new QImage(mView->viewport()->width(), mView->viewport()->height(), QImage::Format_RGB32); else viewImage = new QImage((int) mScene->width(), (int) mScene->height(), QImage::Format_RGB32); painter = new QPainter(); } - if (convert8To24bit) + if(convert8To24bit) mult = 3; else mult = 1; bool ok = false; - if( saveView ) - ok = aviFile.open(dest.toStdString().c_str(), viewImage->width(), viewImage->height(), viewImage->depth(), mAnimation->getFPS()); + if(saveView) + ok = aviFile.open( + dest.toStdString().c_str(), + viewImage->width(), + viewImage->height(), + viewImage->depth(), + mAnimation->getFPS()); else - ok = aviFile.open(dest.toStdString().c_str(), mImg.cols, mImg.rows, mult*8*mImg.channels(), mAnimation->getFPS()); + ok = aviFile.open( + dest.toStdString().c_str(), mImg.cols, mImg.rows, mult * 8 * mImg.channels(), mAnimation->getFPS()); - if (!ok) + if(!ok) { debout << "Error: opening AVI file: " << dest.toStdString().c_str() << std::endl; return; } } - if (!saveVideo) + if(!saveVideo) { - if (saveView) + if(saveView) { - if (mCropZoomViewAct->isChecked()) - viewImage = new QImage(mView->viewport()->width(), mView->viewport()->height(), QImage::Format_RGB32); + if(mCropZoomViewAct->isChecked()) + viewImage = + new QImage(mView->viewport()->width(), mView->viewport()->height(), QImage::Format_RGB32); else viewImage = new QImage((int) mScene->width(), (int) mScene->height(), QImage::Format_RGB32); painter = new QPainter(); } // test, if fileformat is supported - if (mAnimation->isVideo()) + if(mAnimation->isVideo()) { // calculate string length of sequence number - while ((rest/=10) > 0) + while((rest /= 10) > 0) numLength++; - fileName = (dest + "/" + mAnimation->getFileBase() + "%1.png").arg(mPlayerWidget->getPos(), numLength, 10, QChar('0')); + fileName = (dest + "/" + mAnimation->getFileBase() + "%1.png") + .arg(mPlayerWidget->getPos(), numLength, 10, QChar('0')); } else fileName = dest + "/" + mAnimation->getCurrentFileName(); - if (saveView) + if(saveView) { painter->begin(viewImage); - if (mCropZoomViewAct->isChecked()) + if(mCropZoomViewAct->isChecked()) mView->render(painter); else mScene->render(painter); painter->end(); - if (viewImage->save(fileName)) //, const char * format = 0 (format wird aus dateinamen geholt), int quality = -1 default normal (0..100) + if(viewImage->save(fileName)) //, const char * format = 0 (format wird aus dateinamen geholt), int + // quality = -1 default normal (0..100) { formatIsSaveAble = true; mPlayerWidget->frameForward(); } } - else if (mImage->save(fileName)) //, const char * format = 0 (format wird aus dateinamen geholt), int quality = -1 default normal (0..100) + else if(mImage->save(fileName)) //, const char * format = 0 (format wird aus dateinamen geholt), int quality + //= -1 default normal (0..100) { formatIsSaveAble = true; mPlayerWidget->frameForward(); } } - else if ((mImgFiltered.channels() == 1) /*&& convert8To24bit*/) + else if((mImgFiltered.channels() == 1) /*&& convert8To24bit*/) { cv::Size size; - size.width = mImgFiltered.cols; + size.width = mImgFiltered.cols; size.height = mImgFiltered.rows; iplImgFilteredBGR.create(size, CV_8UC3); } @@ -1047,15 +1119,16 @@ void Petrack::saveSequence(bool saveVideo, bool saveView, QString dest) // defau QProgressDialog progress("", "Abort save", 0, progEnd, this); progress.setWindowModality(Qt::WindowModal); // blocks main window - if (saveVideo) + if(saveVideo) { - if (saveView) + if(saveView) progress.setLabelText("Save video view..."); else progress.setLabelText("Save video..."); - }else + } + else { - if (saveView) + if(saveView) progress.setLabelText("Save view sequence..."); else progress.setLabelText("Save image sequence..."); @@ -1064,71 +1137,87 @@ void Petrack::saveSequence(bool saveVideo, bool saveView, QString dest) // defau do { - progress.setValue(mPlayerWidget->getPos()-memPos); // -mempos nur, wenn nicht an den anfang gesprungen wird + progress.setValue( + mPlayerWidget->getPos() - memPos); // -mempos nur, wenn nicht an den anfang gesprungen wird qApp->processEvents(); - if (progress.wasCanceled()) + if(progress.wasCanceled()) break; - if (saveVideo) + if(saveVideo) { // video sequence - if (saveView) + if(saveView) { painter->begin(viewImage); - if (mCropZoomViewAct->isChecked()) + if(mCropZoomViewAct->isChecked()) mView->render(painter); else mScene->render(painter); painter->end(); } - if ((mImgFiltered.channels() == 1) /* && convert8To24bit*/) + if((mImgFiltered.channels() == 1) /* && convert8To24bit*/) { cv::cvtColor(mImg, iplImgFilteredBGR, cv::COLOR_GRAY2BGR); - if( saveView ) - writeFrameRet = aviFile.appendFrame((const unsigned char*) viewImage->bits(), true); // 2. param besagt, ob vertikal gespiegel werden soll + if(saveView) + writeFrameRet = aviFile.appendFrame( + (const unsigned char *) viewImage->bits(), + true); // 2. param besagt, ob vertikal gespiegel werden soll else - writeFrameRet = aviFile.appendFrame((const unsigned char*) iplImgFilteredBGR.data, true); // 2. param besagt, ob vertikal gespiegel werden soll + writeFrameRet = aviFile.appendFrame( + (const unsigned char *) iplImgFilteredBGR.data, + true); // 2. param besagt, ob vertikal gespiegel werden soll } else { - if( saveView ){ - writeFrameRet = aviFile.appendFrame((const unsigned char*) viewImage->bits(), true); // 2. param besagt, ob vertikal gespiegel werden soll - }else{ - writeFrameRet = aviFile.appendFrame((const unsigned char*) mImg.data, true); // 2. param besagt, ob vertikal gespiegel werden soll + if(saveView) + { + writeFrameRet = aviFile.appendFrame( + (const unsigned char *) viewImage->bits(), + true); // 2. param besagt, ob vertikal gespiegel werden soll + } + else + { + writeFrameRet = aviFile.appendFrame( + (const unsigned char *) mImg.data, + true); // 2. param besagt, ob vertikal gespiegel werden soll } } - if (!writeFrameRet) + if(!writeFrameRet) { progress.setValue(progEnd); - PCritical(this, tr("PeTrack"), tr("Cannot save %1 maybe because of wrong file extension or unsupported codec.").arg(dest)); + PCritical( + this, + tr("PeTrack"), + tr("Cannot save %1 maybe because of wrong file extension or unsupported codec.").arg(dest)); break; } } else { // single frame sequence - if (saveView) + if(saveView) { painter->begin(viewImage); - if (mCropZoomViewAct->isChecked()) + if(mCropZoomViewAct->isChecked()) mView->render(painter); else mScene->render(painter); painter->end(); } - if (mAnimation->isVideo()) + if(mAnimation->isVideo()) { - fileName = (dest + "/" + mAnimation->getFileBase() + "%1.png").arg(mPlayerWidget->getPos(), numLength, 10, QChar('0')); - if (saveView) + fileName = (dest + "/" + mAnimation->getFileBase() + "%1.png") + .arg(mPlayerWidget->getPos(), numLength, 10, QChar('0')); + if(saveView) saveRet = viewImage->save(fileName); else saveRet = mImage->save(fileName); } - else if (formatIsSaveAble) + else if(formatIsSaveAble) { fileName = dest + "/" + mAnimation->getCurrentFileName(); - if (saveView) + if(saveView) saveRet = viewImage->save(fileName); else saveRet = mImage->save(fileName); @@ -1136,22 +1225,21 @@ void Petrack::saveSequence(bool saveVideo, bool saveView, QString dest) // defau else { fileName = dest + "/" + QFileInfo(mAnimation->getCurrentFileName()).completeBaseName() + ".png"; - if (saveView) + if(saveView) saveRet = viewImage->save(fileName); else saveRet = mImage->save(fileName, "PNG"); //, int quality = -1 default normal (0..100) } - if (!saveRet) + if(!saveRet) { progress.setValue(progEnd); PCritical(this, tr("PeTrack"), tr("Cannot save %1.").arg(fileName)); break; } } - } - while (mPlayerWidget->frameForward()); + } while(mPlayerWidget->frameForward()); - if (!saveVideo && saveView) + if(!saveVideo && saveView) { delete viewImage; delete painter; @@ -1159,10 +1247,11 @@ void Petrack::saveSequence(bool saveVideo, bool saveView, QString dest) // defau // bei abbruch koennen es auch mPlayerWidget->getPos() frames sein, die bisher geschrieben wurden //-memPos nur, wenn nicht an den anfang gesprungen wird - debout << "wrote " << mPlayerWidget->getPos()+1-memPos << " of " << mAnimation->getNumFrames() << " frames." << std::endl; + debout << "wrote " << mPlayerWidget->getPos() + 1 - memPos << " of " << mAnimation->getNumFrames() << " frames." + << std::endl; progress.setValue(progEnd); - if (saveVideo) + if(saveVideo) { aviFile.close(); } @@ -1177,34 +1266,40 @@ void Petrack::saveSequence(bool saveVideo, bool saveView, QString dest) // defau * * @param dest name of the saved file; if empty, a dialogue for the user opens */ -void Petrack::saveView(QString dest) //default = "" +void Petrack::saveView(QString dest) // default = "" { static QString lastFile; if(mImage) { // if no destination file or folder is given - if (dest.isEmpty()) + if(dest.isEmpty()) { - if (lastFile.isEmpty() && !mSeqFileName.isEmpty()) + if(lastFile.isEmpty() && !mSeqFileName.isEmpty()) lastFile = QFileInfo(mSeqFileName).path(); // alle unetrstuetzen fileformate erhaelt man mit // QImageReader::supportedImageFormats() and QImageWriter::supportedImageFormats() // gif muss nicht dabei sein, dazu muss qt mit -qt-gif uebersetzt worden sein - dest = QFileDialog::getSaveFileName(this, tr("Select image file"), lastFile, - tr("PDF (*.pdf);;Postscript (*.ps *.eps);;Windows bitmaps (*.bmp);;JPEG (*.jpeg *.jpg);;Portable network graphics (*.png);;Portable image format (*.pbm *.pgm *.ppm);;X11 Bitmap or Pixmap (*.xbm *.xpm);;Pixel Images (*.bmp *.jpeg *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm);;All supported types (*pdf *ps *.eps *.bmp *.jpeg *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm);;All files (*.*)")); + dest = QFileDialog::getSaveFileName( + this, + tr("Select image file"), + lastFile, + tr("PDF (*.pdf);;Postscript (*.ps *.eps);;Windows bitmaps (*.bmp);;JPEG (*.jpeg *.jpg);;Portable " + "network graphics (*.png);;Portable image format (*.pbm *.pgm *.ppm);;X11 Bitmap or Pixmap (*.xbm " + "*.xpm);;Pixel Images (*.bmp *.jpeg *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm);;All supported types " + "(*pdf *ps *.eps *.bmp *.jpeg *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm);;All files (*.*)")); } - if (!dest.isEmpty()) + if(!dest.isEmpty()) { - if (dest.right(4) == ".pdf" || dest.right(3) == ".ps" || dest.right(4) == ".eps") + if(dest.right(4) == ".pdf" || dest.right(3) == ".ps" || dest.right(4) == ".eps") { QPrinter printer(QPrinter::ScreenResolution); // HighResolution? printer.setColorMode(QPrinter::Color); printer.setOutputFileName(dest); QPainter painter(&printer); - if (mCropZoomViewAct->isChecked()) + if(mCropZoomViewAct->isChecked()) mView->render(&painter); else mScene->render(&painter); @@ -1213,18 +1308,19 @@ void Petrack::saveView(QString dest) //default = "" { // schwarzer rand links und unten?! QImage *img; - if (mCropZoomViewAct->isChecked()) + if(mCropZoomViewAct->isChecked()) img = new QImage(mView->viewport()->width(), mView->viewport()->height(), QImage::Format_RGB32); else img = new QImage((int) mScene->width(), (int) mScene->height(), QImage::Format_RGB32); QPainter painter(img); - if (mCropZoomViewAct->isChecked()) + if(mCropZoomViewAct->isChecked()) mView->render(&painter); else mScene->render(&painter); painter.end(); - if (!img->save(dest)) //, "PNG" - PCritical(this, tr("PeTrack"), tr("Cannot save %1 maybe because of wrong file extension.").arg(dest)); + if(!img->save(dest)) //, "PNG" + PCritical( + this, tr("PeTrack"), tr("Cannot save %1 maybe because of wrong file extension.").arg(dest)); delete img; } lastFile = dest; @@ -1232,37 +1328,42 @@ void Petrack::saveView(QString dest) //default = "" } } -void Petrack::saveImage(QString dest) //default = "" +void Petrack::saveImage(QString dest) // default = "" { static QString lastFile; if(mImage) { // if no destination file or folder is given - if (dest.isEmpty()) + if(dest.isEmpty()) { - if (lastFile.isEmpty() && !mSeqFileName.isEmpty()) + if(lastFile.isEmpty() && !mSeqFileName.isEmpty()) lastFile = QFileInfo(mSeqFileName).path(); // alle unetrstuetzen fileformate erhaelt man mit // QImageReader::supportedImageFormats() and QImageWriter::supportedImageFormats() // gif muss nict dabei sein, dazu muss qt mit -qt-gif uebesetz worden sein - dest = QFileDialog::getSaveFileName(this, tr("Select image file"), lastFile, - tr("PDF (*.pdf);;Postscript (*.ps *.eps);;Windows bitmaps (*.bmp);;JPEG (*.jpeg *.jpg);;Portable network graphics (*.png);;Portable image format (*.pbm *.pgm *.ppm);;X11 Bitmap or Pixmap (*.xbm *.xpm);;Pixel Images (*.bmp *.jpeg *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm);;All supported types (*pdf *ps *.eps *.bmp *.jpeg *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm);;All files (*.*)")); + dest = QFileDialog::getSaveFileName( + this, + tr("Select image file"), + lastFile, + tr("PDF (*.pdf);;Postscript (*.ps *.eps);;Windows bitmaps (*.bmp);;JPEG (*.jpeg *.jpg);;Portable " + "network graphics (*.png);;Portable image format (*.pbm *.pgm *.ppm);;X11 Bitmap or Pixmap (*.xbm " + "*.xpm);;Pixel Images (*.bmp *.jpeg *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm);;All supported types " + "(*pdf *ps *.eps *.bmp *.jpeg *.jpg *.png *.pbm *.pgm *.ppm *.xbm *.xpm);;All files (*.*)")); } - if (!dest.isEmpty()) + if(!dest.isEmpty()) { - if (dest.right(4) == ".pdf" || dest.right(3) == ".ps" || dest.right(4) == ".eps") + if(dest.right(4) == ".pdf" || dest.right(3) == ".ps" || dest.right(4) == ".eps") { - QPrinter printer(QPrinter::ScreenResolution); // HighResolution? printer.setColorMode(QPrinter::Color); printer.setOutputFileName(dest); QPainter painter(&printer); - QRect rect = painter.viewport(); - QSize size = mImage->size(); + QRect rect = painter.viewport(); + QSize size = mImage->size(); size.scale(rect.size(), Qt::KeepAspectRatio); painter.setViewport(rect.x(), rect.y(), size.width(), size.height()); painter.setWindow(mImage->rect()); @@ -1270,8 +1371,9 @@ void Petrack::saveImage(QString dest) //default = "" } else { - if (!mImage->save(dest)) //, "PNG" - PCritical(this, tr("PeTrack"), tr("Cannot save %1 maybe because of wrong file extension.").arg(dest)); + if(!mImage->save(dest)) //, "PNG" + PCritical( + this, tr("PeTrack"), tr("Cannot save %1 maybe because of wrong file extension.").arg(dest)); } lastFile = dest; } @@ -1284,10 +1386,12 @@ void Petrack::print() { // HighResolution font zu gross! und laengere laufzeit und eher overflow // aber so pixelig und keine schoenen linien - QPrinter printer(QPrinter::ScreenResolution); //ScreenResolution, HighResolution// liefert zu hause: QWin32PrintEngine::initialize: GetPrinter failed () + QPrinter printer(QPrinter::ScreenResolution); // ScreenResolution, HighResolution// liefert zu hause: + // QWin32PrintEngine::initialize: GetPrinter failed () printer.setPageSize(QPageSize{QPageSize::PageSizeId::A4}); QPrintDialog dialog(&printer, this); - if (dialog.exec()) { + if(dialog.exec()) + { QPainter painter(&printer); mView->render(&painter); } @@ -1304,12 +1408,17 @@ void Petrack::resetSettings() void Petrack::about() { - - - auto about = new AboutDialog(this, mPetrackVersion, mGitCommitID, - mGitCommitDate, mGitCommitBranch, - mCompilerID, mCompilerVersion, mCompileDate, mAuthors); - about->show(); + auto about = new AboutDialog( + this, + mPetrackVersion, + mGitCommitID, + mGitCommitDate, + mGitCommitBranch, + mCompilerID, + mCompilerVersion, + mCompileDate, + mAuthors); + about->show(); } @@ -1326,24 +1435,28 @@ void Petrack::keyBindings() const QString out = tr( "<p>Beside the space bar all bindings only affect inside the image.</p>" "<dl><dt><kbd>Space bar</kbd></dt><dd>toggles between pause and last play direction</dd>" - "<dt><kbd>Mouse scroll wheel</kbd></dt><dd>zooms in and out to or from the pixel of the image at the position of the mouse pointer</dd>" + "<dt><kbd>Mouse scroll wheel</kbd></dt><dd>zooms in and out to or from the pixel of the image at the position " + "of the mouse pointer</dd>" "<dt><kbd>Shift + mouse scroll wheel</kbd></dt><dd>plays forwards or backwards frame by frame</dd>" "<dt><kbd>Holding left mouse button</kbd></dt><dd>moves image</dd>" "<dt><kbd>Arrows up/down</kbd></dt><dd>zoom in/out</dd>" "<dt><kbd>Arrows left/right</kbd></dt><dd>frame back/forward</dd>" "<dt><kbd>Double-click left mouse button</kbd></dt><dd>opens video or image sequence</dd>" "<dt><kbd>Ctrl + double-click left mouse button</kbd></dt><dd>inserts new or moves near trackpoint</dd>" - "<dt><kbd>Ctrl + Shift + double-click left mouse button</kbd></dt><dd>splits near trackpoint before actual frame</dd>" + "<dt><kbd>Ctrl + Shift + double-click left mouse button</kbd></dt><dd>splits near trackpoint before actual " + "frame</dd>" "<dt><kbd>Ctrl + double-click right mouse button</kbd></dt><dd>deletes a trajectory of a near trackpoint</dd>" - "<dt><kbd>Shift + double-click right mouse button</kbd></dt><dd>deletes the past part of a trajectory of a near trackpoint</dd>" - "<dt><kbd>Alt + double-click right mouse button</kbd></dt><dd>deletes the future part of a trajectory of a near trackpoint</dd>" + "<dt><kbd>Shift + double-click right mouse button</kbd></dt><dd>deletes the past part of a trajectory of a " + "near trackpoint</dd>" + "<dt><kbd>Alt + double-click right mouse button</kbd></dt><dd>deletes the future part of a trajectory of a " + "near trackpoint</dd>" "<dt><kbd>Ctrl + double-click middle mouse button</kbd></dt><dd>deletes all trajectories</dd>" "<dt><kbd>Shift + double-click middle mouse button</kbd></dt><dd>deletes the past part of all trajectories</dd>" "<dt><kbd>Alt + double-click middle mouse button</kbd></dt><dd>deletes the future part of all trajectories</dd>" "<dt><kbd>Shift + t</kbd></dt><dd>toggles tracking online calculation</dd>" - "<dt><kbd>Shift + double-click left mouse button</kbd></dt><dd>inserts new or moves near trackpoint and enables showing only the modified trajectory</dd></dl>" - "<p>Further key bindings you will find next to the entries of the menus.</p>" - ); + "<dt><kbd>Shift + double-click left mouse button</kbd></dt><dd>inserts new or moves near trackpoint and " + "enables showing only the modified trajectory</dd></dl>" + "<p>Further key bindings you will find next to the entries of the menus.</p>"); PMessageBox *mb = new PMessageBox(this, tr("Key Bindings"), out, QIcon()); mb->setAttribute(Qt::WA_DeleteOnClose); @@ -1355,7 +1468,7 @@ void Petrack::keyBindings() void Petrack::onlineHelp() { static QUrl url("https://jugit.fz-juelich.de/ped-dyn-emp/petrack/-/wikis/home"); - if (!(QDesktopServices::openUrl(url))) + if(!(QDesktopServices::openUrl(url))) PCritical(this, tr("PeTrack"), tr("Cannot open external browser<br>with url ") + url.toString() + "!"); } @@ -1384,11 +1497,14 @@ void Petrack::fitInROI() } void Petrack::setGlobalFont() { - bool ok; + bool ok; QFont font = QFontDialog::getFont(&ok, this->font(), this); - if (ok) { + if(ok) + { this->setFont(font); // font is set to the font the user selected - } else { + } + else + { // the user canceled the dialog; font is set to the initial // value, in this case Times, 12. } @@ -1403,18 +1519,18 @@ void Petrack::showHideControlWidget() void Petrack::setCamera() { #ifndef STEREO_DISABLED - if (mAnimation) + if(mAnimation) { - if (mCameraLeftViewAct->isChecked()) + if(mCameraLeftViewAct->isChecked()) { - if ((mAnimation->getCamera()) != cameraLeft) + if((mAnimation->getCamera()) != cameraLeft) mAnimation->setCamera(cameraLeft); // war: hier wird direkt bei Umstellung neu gelesen else return; } - else if (mCameraRightViewAct->isChecked()) + else if(mCameraRightViewAct->isChecked()) { - if ((mAnimation->getCamera()) != cameraRight) + if((mAnimation->getCamera()) != cameraRight) mAnimation->setCamera(cameraRight); // war: hier wird direkt bei Umstellung neu gelesen else return; @@ -1424,10 +1540,11 @@ void Petrack::setCamera() mAnimation->setCamera(cameraUnset); return; } - updateImage(mAnimation->getFrameAtIndex(mAnimation->getCurrentFrameNum())); // wird nur aufgerufen, wenn left / right sich geaendert hat - //mPlayerWidget->updateImage(); - //mPlayerWidget->skipToFrame(mPlayerWidget->getPos()); // machtpasue!! - //updateImage(true); // nur dies aufrufen, wenn nicht links rechts gleichzeitig gehalten wird + updateImage(mAnimation->getFrameAtIndex( + mAnimation->getCurrentFrameNum())); // wird nur aufgerufen, wenn left / right sich geaendert hat + // mPlayerWidget->updateImage(); + // mPlayerWidget->skipToFrame(mPlayerWidget->getPos()); // machtpasue!! + // updateImage(true); // nur dies aufrufen, wenn nicht links rechts gleichzeitig gehalten wird } #endif @@ -1444,14 +1561,15 @@ void Petrack::createActions() connect(mOpenSeqAct, SIGNAL(triggered()), this, SLOT(openSequence())); mOpenCameraAct = new QAction(tr("Open Camera Stream"), this); - //mOpenCameraAct->setShortcut(tr("Ctrl+C")); // because of some reason it is sometimes fired with Ctrl+LeftMouseButton ==> so disabled (it's also not really needed) + // mOpenCameraAct->setShortcut(tr("Ctrl+C")); // because of some reason it is sometimes fired with + // Ctrl+LeftMouseButton ==> so disabled (it's also not really needed) connect(mOpenCameraAct, SIGNAL(triggered()), this, SLOT(openCameraLiveStream())); mOpenMoCapAct = new QAction(tr("Manage MoCap Files"), this); connect(mOpenMoCapAct, &QAction::triggered, this, &Petrack::openMoCapFile); mSaveSeqVidAct = new QAction(tr("Save Video"), this); - //mSaveSeqVidAct->setShortcut(tr("Ctrl+E")); + // mSaveSeqVidAct->setShortcut(tr("Ctrl+E")); mSaveSeqVidAct->setEnabled(false); connect(mSaveSeqVidAct, SIGNAL(triggered()), this, SLOT(saveVideo())); @@ -1498,7 +1616,7 @@ void Petrack::createActions() connect(mPrintAct, SIGNAL(triggered()), this, SLOT(print())); mResetSettingsAct = new QAction(tr("&Reset Settings"), this); -// mResetSettingsAct->setShortcut(tr("Ctrl+R")); + // mResetSettingsAct->setShortcut(tr("Ctrl+R")); mResetSettingsAct->setEnabled(false); // da es noch nicht fehlerfrei funktioniert connect(mResetSettingsAct, SIGNAL(triggered()), this, SLOT(resetSettings())); @@ -1518,9 +1636,9 @@ void Petrack::createActions() mHideControlsAct->setShortcut(tr("Ctrl+H")); mHideControlsAct->setCheckable(true); connect(mHideControlsAct, SIGNAL(triggered()), this, SLOT(showHideControlWidget())); - connect(mHideControlsAct, SIGNAL(changed()),this, SLOT(showHideControlWidget())); + connect(mHideControlsAct, SIGNAL(changed()), this, SLOT(showHideControlWidget())); - mCropZoomViewAct = new QAction(tr("&Transform while saving"), this); //Crop and zoom while saving + mCropZoomViewAct = new QAction(tr("&Transform while saving"), this); // Crop and zoom while saving mCropZoomViewAct->setCheckable(true); mOpenGLAct = new QAction(tr("Open&GL"), this); @@ -1532,7 +1650,8 @@ void Petrack::createActions() mResetAct->setShortcut(tr("Ctrl+R")); connect(mResetAct, SIGNAL(triggered()), this, SLOT(reset())); - mFitViewAct = new QAction(tr("Fit in window"), this); // Resize to window; fit in view; show all; in fenster einpassen + mFitViewAct = + new QAction(tr("Fit in window"), this); // Resize to window; fit in view; show all; in fenster einpassen mFitViewAct->setShortcut(tr("Ctrl+0")); connect(mFitViewAct, SIGNAL(triggered()), this, SLOT(fitInView())); @@ -1541,8 +1660,8 @@ void Petrack::createActions() connect(mFitROIAct, SIGNAL(triggered()), this, SLOT(fitInROI())); mCameraGroupView = new QActionGroup(this); - //mCameraGroupView->addAction(mCameraLeftViewAct); - //mCameraGroupView->addAction(mCameraRightViewAct); + // mCameraGroupView->addAction(mCameraLeftViewAct); + // mCameraGroupView->addAction(mCameraRightViewAct); mCameraLeftViewAct = new QAction(tr("&Left"), mCameraGroupView); mCameraLeftViewAct->setShortcut(tr("Ctrl++Shift+L")); mCameraLeftViewAct->setCheckable(true); @@ -1551,37 +1670,44 @@ void Petrack::createActions() mCameraRightViewAct->setShortcut(tr("Ctrl++Shift+R")); mCameraRightViewAct->setCheckable(true); connect(mCameraRightViewAct, SIGNAL(triggered()), this, SLOT(setCamera())); - mCameraRightViewAct->setChecked(true); // right wird als default genommen, da reference image in triclops auch right ist // erste trj wurden mit left gerechnet + mCameraRightViewAct->setChecked(true); // right wird als default genommen, da reference image in triclops auch right + // ist // erste trj wurden mit left gerechnet mLimitPlaybackSpeed = new QAction(tr("&Limit playback speed")); - // Not checkable like Fix since this is also controlled through clicking on FPS and syncing currently would be bothersome - connect(mLimitPlaybackSpeed, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setPlayerSpeedLimited(!mPlayerWidget->getPlayerSpeedLimited());}); + // Not checkable like Fix since this is also controlled through clicking on FPS and syncing currently would be + // bothersome + connect( + mLimitPlaybackSpeed, + &QAction::triggered, + mPlayerWidget, + [&]() { mPlayerWidget->setPlayerSpeedLimited(!mPlayerWidget->getPlayerSpeedLimited()); }); mFixPlaybackSpeed = new QAction(tr("&Fix playback speed")); mFixPlaybackSpeed->setCheckable(true); connect(mFixPlaybackSpeed, &QAction::toggled, mPlayerWidget, &Player::setPlayerSpeedFixed); mSetToRealtime = new QAction(tr("&Realtime")); - connect(mSetToRealtime, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setSpeedRelativeToRealtime(1.0);}); + connect( + mSetToRealtime, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(1.0); }); mSetTo2p00 = new QAction(tr("&x2")); - connect(mSetTo2p00, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setSpeedRelativeToRealtime(2.0);}); + connect(mSetTo2p00, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(2.0); }); mSetTo1p75 = new QAction(tr("&x1.75")); - connect(mSetTo1p75, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setSpeedRelativeToRealtime(1.75);}); + connect(mSetTo1p75, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(1.75); }); mSetTo1p50 = new QAction(tr("&x1.5")); - connect(mSetTo1p50, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setSpeedRelativeToRealtime(1.5);}); + connect(mSetTo1p50, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(1.5); }); mSetTo1p25 = new QAction(tr("&x1.25")); - connect(mSetTo1p25, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setSpeedRelativeToRealtime(1.25);}); + connect(mSetTo1p25, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(1.25); }); mSetTo0p75 = new QAction(tr("&x0.75")); - connect(mSetTo0p75, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setSpeedRelativeToRealtime(0.75);}); + connect(mSetTo0p75, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(0.75); }); mSetTo0p50 = new QAction(tr("&x0.5")); - connect(mSetTo0p50, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setSpeedRelativeToRealtime(0.5);}); + connect(mSetTo0p50, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(0.5); }); mSetTo0p25 = new QAction(tr("&x0.25")); - connect(mSetTo0p25, &QAction::triggered, mPlayerWidget, [&](){mPlayerWidget->setSpeedRelativeToRealtime(0.25);}); + connect(mSetTo0p25, &QAction::triggered, mPlayerWidget, [&]() { mPlayerWidget->setSpeedRelativeToRealtime(0.25); }); mPlayerLooping = new QAction(tr("&Loop")); mPlayerLooping->setCheckable(true); connect(mPlayerLooping, &QAction::triggered, mPlayerWidget, &Player::setLooping); // ------------------------------------------------------------------------------------------------------- - QSignalMapper* signalMapper = new QSignalMapper(this); + QSignalMapper *signalMapper = new QSignalMapper(this); mDelPastAct = new QAction(tr("&Past part of all trj."), this); connect(mDelPastAct, SIGNAL(triggered()), signalMapper, SLOT(map())); @@ -1693,7 +1819,7 @@ void Petrack::createMenus() */ void Petrack::createStatusBar() { - QFont f("Courier", 12, QFont::Bold); //Times Helvetica, Normal + QFont f("Courier", 12, QFont::Bold); // Times Helvetica, Normal statusBar()->setMaximumHeight(28); statusBar()->showMessage(tr("Ready")); statusBar()->addPermanentWidget(mStatusLabelStereo = new QLabel(" ")); @@ -1727,19 +1853,20 @@ void Petrack::createStatusBar() void Petrack::resetUI() { - ///ToDo: + /// ToDo: /// - /// Reset all UI elements to default settings - /// Noetig damit alle UI Elemente, welche in der neu geladenen Projekt-Datei z.B. noch nicht vorhanden sind, auf sinnvolle Werte gesetzt werden. - /// Anderenfalls kommt es evtl. beim nacheinander laden verschiedener Projekte zu einem Programmabsturz + /// Reset all UI elements to default settings + /// Noetig damit alle UI Elemente, welche in der neu geladenen Projekt-Datei z.B. noch nicht vorhanden sind, auf + /// sinnvolle Werte gesetzt werden. Anderenfalls kommt es evtl. beim nacheinander laden verschiedener Projekte zu + /// einem Programmabsturz /// return; mSeqFileName = ""; mAnimation->free(); - if( mImage ) + if(mImage) { - mImage->fill(QColor::fromRgb(255,255,255)); + mImage->fill(QColor::fromRgb(255, 255, 255)); mImageItem->setImage(mImage); mLogoItem->show(); } @@ -1775,10 +1902,10 @@ void Petrack::resetUI() mControlWidget->fy->setValue(1000); mControlWidget->cx->setValue(960); mControlWidget->cx->setMinimum(0); - mControlWidget->cx->setMaximum(mControlWidget->cx->value()*2); + mControlWidget->cx->setMaximum(mControlWidget->cx->value() * 2); mControlWidget->cy->setValue(540); mControlWidget->cx->setMinimum(0); - mControlWidget->cy->setMaximum(mControlWidget->cy->value()*2); + mControlWidget->cy->setMaximum(mControlWidget->cy->value() * 2); mControlWidget->r2->setValue(0); mControlWidget->r4->setValue(0); mControlWidget->r6->setValue(0); @@ -1848,11 +1975,11 @@ void Petrack::resetUI() // region of interest mControlWidget->roiFix->setCheckState(Qt::Unchecked); mControlWidget->roiShow->setCheckState(Qt::Unchecked); - getRecoRoiItem()->setRect(0,0,0,0); + getRecoRoiItem()->setRect(0, 0, 0, 0); // marker, default multicolor marker (until 11/2016 hermes marker) mControlWidget->recoMethod->setCurrentIndex( - mControlWidget->recoMethod->findData(QVariant::fromValue(reco::RecognitionMethod::MultiColor))); + mControlWidget->recoMethod->findData(QVariant::fromValue(reco::RecognitionMethod::MultiColor))); mControlWidget->markerBrightness->setValue(100); mControlWidget->markerIgnoreWithout->setCheckState(Qt::Checked); @@ -1888,7 +2015,7 @@ void Petrack::resetUI() mControlWidget->trackExtrapolation->setCheckState(Qt::Checked); mControlWidget->trackMerge->setCheckState(Qt::Unchecked); mControlWidget->trackOnlySelected->setCheckState(Qt::Checked); - getTrackRoiItem()->setRect(0,0,0,0); + getTrackRoiItem()->setRect(0, 0, 0, 0); // export options mControlWidget->trackMissingFrames->setCheckState(Qt::Checked); @@ -1966,39 +2093,40 @@ void Petrack::resetUI() void Petrack::setStatusStereo(float x, float y, float z) { - if (mStatusLabelStereo) + if(mStatusLabelStereo) { - if (z<0) + if(z < 0) mStatusLabelStereo->setText(QString("x= novalue y= novalue z= novalue ")); else - mStatusLabelStereo->setText(QString("x=%1cm y=%2cm z=%3cm ").arg(x, 6, 'f', 1).arg(y, 6, 'f', 1).arg(z, 6, 'f', 1)); + mStatusLabelStereo->setText( + QString("x=%1cm y=%2cm z=%3cm ").arg(x, 6, 'f', 1).arg(y, 6, 'f', 1).arg(z, 6, 'f', 1)); } } void Petrack::setStatusTime() { - if (mStatusLabelTime) + if(mStatusLabelTime) mStatusLabelTime->setText(mAnimation->getTimeString()); } void Petrack::setStatusFPS() { - if (mStatusLabelFPS) + if(mStatusLabelFPS) { mStatusLabelFPS->setText(QString("%1fps ").arg(mShowFPS, 5, 'f', 1)); QPalette pal = mStatusLabelFPS->palette(); // static moeglich? - QColor color; + QColor color; - double diff = mShowFPS-mAnimation->getFPS(); - int opacity = mPlayerWidget->getPlayerSpeedLimited() ? 128 : 20; + double diff = mShowFPS - mAnimation->getFPS(); + int opacity = mPlayerWidget->getPlayerSpeedLimited() ? 128 : 20; - if( diff < -6 ) // very slow ==> red - color.setRgb(200,0,0,opacity); - else if( diff < -2 ) // better ==> yellow - color.setRgb(200,200,0,opacity); - else if (diff > -2) // nearly ok ==> green - color.setRgb(0,200,0,opacity); + if(diff < -6) // very slow ==> red + color.setRgb(200, 0, 0, opacity); + else if(diff < -2) // better ==> yellow + color.setRgb(200, 200, 0, opacity); + else if(diff > -2) // nearly ok ==> green + color.setRgb(0, 200, 0, opacity); pal.setColor(QPalette::Window, color); @@ -2007,10 +2135,10 @@ void Petrack::setStatusFPS() } void Petrack::setShowFPS(double fps) { - if ((fps == 0.) || (mShowFPS == 0)) + if((fps == 0.) || (mShowFPS == 0)) mShowFPS = fps; else - mShowFPS = mShowFPS*.9+fps*.1; // glaetten durch Hinzunahme des alten Wertes + mShowFPS = mShowFPS * .9 + fps * .1; // glaetten durch Hinzunahme des alten Wertes setStatusFPS(); } @@ -2025,28 +2153,30 @@ void Petrack::setShowFPS(double fps) * * @param skipped True, if this is a skipped frame; default false */ -void Petrack::updateShowFPS(bool skipped) { +void Petrack::updateShowFPS(bool skipped) +{ static QElapsedTimer lastTime; - static int skippedFrames = 0; + static int skippedFrames = 0; - if(skipped){ + if(skipped) + { skippedFrames++; return; } - if (mPlayerWidget->getPaused()) + if(mPlayerWidget->getPaused()) { setShowFPS(0.); lastTime.invalidate(); } else { - if (lastTime.isValid()) + if(lastTime.isValid()) { - if (lastTime.elapsed() > 0) + if(lastTime.elapsed() > 0) { - int numFrames = skippedFrames > 0 ? skippedFrames+1 : 1; - setShowFPS(numFrames*1000./lastTime.elapsed()); + int numFrames = skippedFrames > 0 ? skippedFrames + 1 : 1; + setShowFPS(numFrames * 1000. / lastTime.elapsed()); skippedFrames = 0; } } @@ -2058,17 +2188,24 @@ void Petrack::updateShowFPS(bool skipped) { // gebraucht in control.cpp void Petrack::setStatusPosReal() // pos in cm { - if (mImageItem) + if(mImageItem) setStatusPosReal(mImageItem->getPosReal(mMousePosOnImage, getStatusPosRealHeight())); } void Petrack::setStatusPosReal(const QPointF &pos) // pos in cm { - if (mStatusLabelPosReal) + if(mStatusLabelPosReal) { - QChar deg(0xB0); - QString labelText = QString(" cm from ground:%1cm,%2cm,%3").arg(pos.x(), 6, 'f', 1).arg(pos.y(), 6, 'f', 1).arg( - getImageItem()->getAngleToGround(mMousePosOnImage.x(), mMousePosOnImage.y(), getStatusPosRealHeight()), 5, 'f', 1); + QChar deg(0xB0); + QString labelText = QString(" cm from ground:%1cm,%2cm,%3") + .arg(pos.x(), 6, 'f', 1) + .arg(pos.y(), 6, 'f', 1) + .arg( + getImageItem()->getAngleToGround( + mMousePosOnImage.x(), mMousePosOnImage.y(), getStatusPosRealHeight()), + 5, + 'f', + 1); labelText.append(deg); mStatusLabelPosReal->setText(labelText); } @@ -2083,26 +2220,25 @@ void Petrack::setStatusColor(const QRgb &col) { 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) + if((qRed(col) + qGreen(col) + qBlue(col)) / 3 < 128) mStatusLabelColor->setText(QString("<font color=\"#ffffff\"> %1</font>").arg(s)); else mStatusLabelColor->setText(QString("<font color=\"#000000\"> %1</font>").arg(s)); QPalette pal = mStatusLabelColor->palette(); // static moeglich? - QColor color(qRed(col), qGreen(col), qBlue(col)); + QColor color(qRed(col), qGreen(col), qBlue(col)); pal.setColor(QPalette::Window, color); mStatusLabelColor->setPalette(pal); mControlWidget->getColorPlot()->setCursor(color); mControlWidget->getColorPlot()->replot(); - } void Petrack::setStatusColor() { QPointF pos = getMousePosOnImage(); - if (pos.x() >= 0 && pos.x() < mImage->width() && pos.y() > 0 && pos.y() < mImage->height()) + if(pos.x() >= 0 && pos.x() < mImage->width() && pos.y() > 0 && pos.y() < mImage->height()) { setStatusColor(mImage->pixel(pos.toPoint())); } @@ -2110,7 +2246,7 @@ void Petrack::setStatusColor() double Petrack::getStatusPosRealHeight() { - if (mStatusPosRealHeight) + if(mStatusPosRealHeight) return mStatusPosRealHeight->value(); else return 0.; @@ -2127,14 +2263,14 @@ double Petrack::getStatusPosRealHeight() void Petrack::readSettings() { QSettings settings("Forschungszentrum Juelich GmbH", "PeTrack by Maik Boltes, Daniel Salden"); - QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); - QSize size = settings.value("size", QSize(400, 400)).toSize(); + QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); + QSize size = settings.value("size", QSize(400, 400)).toSize(); mAntialiasAct->setChecked(settings.value("antialias", false).toBool()); mOpenGLAct->setChecked(settings.value("opengl", false).toBool()); mSeqFileName = settings.value("seqFileName", QDir::currentPath()).toString(); setProFileName(settings.value("proFilePath", QDir::currentPath()).toString()); - // nicht ganz sauber, da so immer schon zu anfang in calib file list etwas drin steht und somit auto ausgefuehrt werden kann - // wird aber beim ersten openCalib... ueberschrieben + // nicht ganz sauber, da so immer schon zu anfang in calib file list etwas drin steht und somit auto ausgefuehrt + // werden kann wird aber beim ersten openCalib... ueberschrieben mAutoCalib.addCalibFile(settings.value("calibFile", QDir::currentPath()).toString()); resize(size); move(pos); @@ -2156,31 +2292,31 @@ void Petrack::writeSettings() settings.setValue("opengl", mOpenGLAct->isChecked()); settings.setValue("seqFileName", mSeqFileName); settings.setValue("proFilePath", QFileInfo(mProFileName).path()); // nur path, damit bei saveCurrentProject - if (!mAutoCalib.isEmptyCalibFiles()) //!mCalibFiles.isEmpty() + if(!mAutoCalib.isEmptyCalibFiles()) //! mCalibFiles.isEmpty() settings.setValue("calibFile", mAutoCalib.getCalibFile(0)); settings.setValue("controlSplitterSizes", mSplitter->saveState()); } bool Petrack::maybeSave() { - int ret = PWarning(this, tr("PeTrack"), - tr("Do you want to save " - "the current project?\n" - "Be sure to save trajectories, background " - "and 3D calibration point separately!"), - PMessageBox::StandardButton::Yes | - PMessageBox::StandardButton::No | - PMessageBox::StandardButton::Cancel, - PMessageBox::StandardButton::Yes); - - if (ret == PMessageBox::StandardButton::Yes) + int ret = PWarning( + this, + tr("PeTrack"), + tr("Do you want to save " + "the current project?\n" + "Be sure to save trajectories, background " + "and 3D calibration point separately!"), + PMessageBox::StandardButton::Yes | PMessageBox::StandardButton::No | PMessageBox::StandardButton::Cancel, + PMessageBox::StandardButton::Yes); + + if(ret == PMessageBox::StandardButton::Yes) { - if (saveSameProject()) + if(saveSameProject()) return true; else return false; } - else if (ret == PMessageBox::StandardButton::Cancel) + else if(ret == PMessageBox::StandardButton::Cancel) return false; else return true; @@ -2188,15 +2324,13 @@ bool Petrack::maybeSave() void Petrack::closeEvent(QCloseEvent *event) { - - if (maybeSave()) + if(maybeSave()) { writeSettings(); event->accept(); } else event->ignore(); - } /** @@ -2208,13 +2342,13 @@ void Petrack::closeEvent(QCloseEvent *event) */ void Petrack::setMousePosOnImage(QPointF pos) { - if (mImage) + if(mImage) { mMousePosOnImage = pos; setStatusPosReal(mImageItem->getPosReal(pos, getStatusPosRealHeight())); // pixel coordinate - QPoint pos1((int)(pos.x())+1, (int)(pos.y())+1); + QPoint pos1((int) (pos.x()) + 1, (int) (pos.y()) + 1); setStatusPos(pos1); // pixel color @@ -2222,36 +2356,37 @@ void Petrack::setMousePosOnImage(QPointF pos) } } -void Petrack::keyPressEvent(QKeyEvent * event) -{ - switch (event->key()) { - case Qt::Key_Left: - mPlayerWidget->frameBackward(); - break; - case Qt::Key_Right: - mPlayerWidget->frameForward(); - break; - case Qt::Key_Down: - mViewWidget->zoomOut(1); - break; - case Qt::Key_Up: - mViewWidget->zoomIn(1); - break; - case Qt::Key_Space: - // space wird von buttons, wenn focus drauf ist als Aktivierung vorher abgegriffen und nicht durchgereicht - mPlayerWidget->togglePlayPause(); - break; - case Qt::Key_D: - break; - default: - ; +void Petrack::keyPressEvent(QKeyEvent *event) +{ + switch(event->key()) + { + case Qt::Key_Left: + mPlayerWidget->frameBackward(); + break; + case Qt::Key_Right: + mPlayerWidget->frameForward(); + break; + case Qt::Key_Down: + mViewWidget->zoomOut(1); + break; + case Qt::Key_Up: + mViewWidget->zoomIn(1); + break; + case Qt::Key_Space: + // space wird von buttons, wenn focus drauf ist als Aktivierung vorher abgegriffen und nicht durchgereicht + mPlayerWidget->togglePlayPause(); + break; + case Qt::Key_D: + break; + default:; } } void Petrack::mousePressEvent(QMouseEvent *event) { // mouse click in fps status label ? - if( event->pos().x() >= mStatusLabelFPS->pos().x() && event->pos().x() <= mStatusLabelFPS->pos().x()+mStatusLabelFPS->width() ) + if(event->pos().x() >= mStatusLabelFPS->pos().x() && + event->pos().x() <= mStatusLabelFPS->pos().x() + mStatusLabelFPS->width()) { mPlayerWidget->togglePlayerSpeedLimited(); setStatusFPS(); @@ -2261,98 +2396,103 @@ void Petrack::mousePressEvent(QMouseEvent *event) /// update control widget, if image size changed (especially because of changing border) void Petrack::updateControlImage(cv::Mat &img) { - // auch moeglich hoehe und breite von bild stat border veraenderungen zu checken static int lastBorderSize = -1; - if( isLoading() ) + if(isLoading()) lastBorderSize = -1; - int diffBorderSize=0; - int iW = img.cols; - int iH = img.rows; + int diffBorderSize = 0; + int iW = img.cols; + int iH = img.rows; // wird auch nochmal in ImageWidget gemacht, aber ist hier frueher noetig double cX = mControlWidget->getCalibCxValue(); // merken, da min/max value verandernkann wenn aus dem rahmen double cY = mControlWidget->getCalibCyValue(); - mControlWidget->setCalibCxMin(0 /*iW/2.-50.*/); + mControlWidget->setCalibCxMin(0 /*iW/2.-50.*/); mControlWidget->setCalibCxMax(iW /*iW/2.+50.*/); - mControlWidget->setCalibCyMin(0 /*iH/2.-50.*/); + mControlWidget->setCalibCyMin(0 /*iH/2.-50.*/); mControlWidget->setCalibCyMax(iH /*iH/2.+50.*/); - if (mControlWidget->fixCenter->checkState() == Qt::Checked) + if(mControlWidget->fixCenter->checkState() == Qt::Checked) { - mControlWidget->setCalibCxValue((iW-1)/2.); - mControlWidget->setCalibCyValue((iH-1)/2.); + mControlWidget->setCalibCxValue((iW - 1) / 2.); + mControlWidget->setCalibCyValue((iH - 1) / 2.); } else { - if (lastBorderSize != -1) - diffBorderSize = getImageBorderSize()-lastBorderSize; + if(lastBorderSize != -1) + diffBorderSize = getImageBorderSize() - lastBorderSize; lastBorderSize = getImageBorderSize(); - mControlWidget->setCalibCxValue(cX+diffBorderSize); - mControlWidget->setCalibCyValue(cY+diffBorderSize); + mControlWidget->setCalibCxValue(cX + diffBorderSize); + mControlWidget->setCalibCyValue(cY + diffBorderSize); } } -void Petrack::importTracker(QString dest) //default = "" +void Petrack::importTracker(QString dest) // default = "" { static QString lastFile; - if (lastFile == "") + if(lastFile == "") lastFile = mTrcFileName; // if no destination file or folder is given - if (dest.isEmpty()) + if(dest.isEmpty()) { - dest = QFileDialog::getOpenFileName(this, tr("Select file for importing tracking pathes"), lastFile, - tr("PeTrack tracker (*.trc *.txt);;All files (*.*)")); + dest = QFileDialog::getOpenFileName( + this, + tr("Select file for importing tracking pathes"), + lastFile, + tr("PeTrack tracker (*.trc *.txt);;All files (*.*)")); } - if (!dest.isEmpty()) + if(!dest.isEmpty()) { - if (dest.right(4) == ".trc") + if(dest.right(4) == ".trc") { QFile file(dest); - int i, sz; + int i, sz; - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { // errorstring ist je nach Betriebssystem in einer anderen Sprache!!!! PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2").arg(dest).arg(file.errorString())); return; } - setTrackChanged(true);// flag changes of track parameters + setTrackChanged(true); // flag changes of track parameters mTracker->reset(); QTextStream in(&file); TrackPerson tp; - QString comment; + QString comment; - bool ok; // shows if int stands in first line - that was in the first version of trc file + bool ok; // shows if int stands in first line - that was in the first version of trc file QString firstLine = in.readLine(); - sz = firstLine.toInt(&ok); - if (!ok) + sz = firstLine.toInt(&ok); + if(!ok) { - if (firstLine.contains("version 4",Qt::CaseInsensitive)) + if(firstLine.contains("version 4", Qt::CaseInsensitive)) { trcVersion = 4; } - else if (firstLine.contains("version 3",Qt::CaseInsensitive)) + else if(firstLine.contains("version 3", Qt::CaseInsensitive)) { trcVersion = 3; } - else if(firstLine.contains("version 2",Qt::CaseInsensitive)) + else if(firstLine.contains("version 2", Qt::CaseInsensitive)) { trcVersion = 2; } else { debout << "Error: wrong header while reading TRC file." << std::endl; - QMessageBox::critical(this, tr("PeTrack"), tr("Could not import tracker:\nNot supported trc version in file: %1.").arg(dest)); + QMessageBox::critical( + this, + tr("PeTrack"), + tr("Could not import tracker:\nNot supported trc version in file: %1.").arg(dest)); return; } in >> sz; @@ -2360,64 +2500,72 @@ void Petrack::importTracker(QString dest) //default = "" else trcVersion = 1; - if ((sz > 0) && (mTracker->size() != 0)) - debout << "Warning: Overlapping trajectories will be joined not until tracking adds new trackpoints." << std::endl; - for (i = 0; i < sz; ++i) + if((sz > 0) && (mTracker->size() != 0)) + debout << "Warning: Overlapping trajectories will be joined not until tracking adds new trackpoints." + << std::endl; + for(i = 0; i < sz; ++i) { - if( trcVersion == 2) + if(trcVersion == 2) { in >> tp; - }else if( trcVersion >= 3) + } + else if(trcVersion >= 3) { in >> tp; } mTracker->append(tp); - tp.clear(); // loeschen, sonst immer weitere pfade angehangen werden + tp.clear(); // loeschen, sonst immer weitere pfade angehangen werden } mControlWidget->trackNumberAll->setText(QString("%1").arg(mTracker->size())); - mControlWidget->trackShowOnlyNr->setMaximum(MAX(mTracker->size(),1)); - mControlWidget->trackNumberVisible->setText(QString("%1").arg(mTracker->visible(mAnimation->getCurrentFrameNum()))); + mControlWidget->trackShowOnlyNr->setMaximum(MAX(mTracker->size(), 1)); + mControlWidget->trackNumberVisible->setText( + QString("%1").arg(mTracker->visible(mAnimation->getCurrentFrameNum()))); mControlWidget->colorPlot->replot(); file.close(); debout << "import " << dest << " (" << sz << " person(s), file version " << trcVersion << ")" << std::endl; - mTrcFileName = dest; // fuer Project-File, dann koennte track path direkt mitgeladen werden, wenn er noch da ist - }else - if (dest.right(4) == ".txt") // 3D Koordinaten als Tracking-Daten importieren Zeilenformat: Personennr, Framenr, x, y, z + mTrcFileName = + dest; // fuer Project-File, dann koennte track path direkt mitgeladen werden, wenn er noch da ist + } + else if(dest.right(4) == ".txt") // 3D Koordinaten als Tracking-Daten importieren Zeilenformat: Personennr, + // Framenr, x, y, z { - PWarning(this,tr("PeTrack"), tr("Are you sure you want to import 3D data from TXT-File? You have to make sure that the coordinate system now is exactly at the same position and orientation than at export time!")); + PWarning( + this, + tr("PeTrack"), + tr("Are you sure you want to import 3D data from TXT-File? You have to make sure that the coordinate " + "system now is exactly at the same position and orientation than at export time!")); QFile file(dest); // size of person list int sz = 0; - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { // errorstring ist je nach Betriebssystem in einer anderen Sprache!!!! PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2").arg(dest).arg(file.errorString())); return; } - setTrackChanged(true);// flag changes of track parameters + setTrackChanged(true); // flag changes of track parameters mTracker->reset(); QTextStream in(&file); TrackPerson tp; - TrackPoint tPoint; + TrackPoint tPoint; cv::Point2f p2d; QString line; QString headerline; - bool exec_once_flag = false; - double conversionFactorTo_cm = 1.0; - int personNr = -1, frameNr = -1, current_personNr = 1; - float x, y ,z; + bool exec_once_flag = false; + double conversionFactorTo_cm = 1.0; + int personNr = -1, frameNr = -1, current_personNr = 1; + float x, y, z; - while( 1 ) + while(1) { - // Falls Datei am Ende letzte Person abspeichern und Lese-Schleife beenden - if( in.atEnd() ) + if(in.atEnd()) { tp.setLastFrame(frameNr); mTracker->append(tp); @@ -2429,27 +2577,26 @@ void Petrack::importTracker(QString dest) //default = "" line = in.readLine(); // Kommentare ueberlesen - if( line.startsWith("#",Qt::CaseInsensitive) ) + if(line.startsWith("#", Qt::CaseInsensitive)) { headerline = line; continue; } - if ((!exec_once_flag) && (!headerline.contains("cm"))) + if((!exec_once_flag) && (!headerline.contains("cm"))) { conversionFactorTo_cm = 100.0; - exec_once_flag = true; - PWarning(this,tr("PeTrack"), tr("PeTrack will interpret position data as unit [m]. No header with [cm] found.")); + exec_once_flag = true; + PWarning( + this, + tr("PeTrack"), + tr("PeTrack will interpret position data as unit [m]. No header with [cm] found.")); } QTextStream stream(&line); // Zeile als Stream einlesen Format: [id frame x y z] - stream >> personNr - >> frameNr - >> x - >> y - >> z; + stream >> personNr >> frameNr >> x >> y >> z; // convert data to cm x = x * conversionFactorTo_cm; @@ -2457,23 +2604,27 @@ void Petrack::importTracker(QString dest) //default = "" z = z * conversionFactorTo_cm; // 3-dimensionale Berechnung/Anzeige des Punktes - if( mControlWidget->getCalibCoordDimension() == 0 ) + if(mControlWidget->getCalibCoordDimension() == 0) { - p2d = mExtrCalibration.getImagePoint(cv::Point3f(x,y,z)); + p2d = mExtrCalibration.getImagePoint(cv::Point3f(x, y, z)); } // 2-dimensionale Berechnung/Anzeige des Punktes else { - QPointF pos = mImageItem->getPosImage(QPointF(x,y),z); - p2d.x = pos.x(); - p2d.y = pos.y(); + QPointF pos = mImageItem->getPosImage(QPointF(x, y), z); + p2d.x = pos.x(); + p2d.y = pos.y(); } - tPoint = TrackPoint(Vec2F(p2d.x,p2d.y),100); - tPoint.setSp(x,y,-mControlWidget->getCalibExtrTrans3()-z); // fuer den Abstand zur Kamera in z-Richtung wie bei einer Stereokamera + tPoint = TrackPoint(Vec2F(p2d.x, p2d.y), 100); + tPoint.setSp( + x, + y, + -mControlWidget->getCalibExtrTrans3() - + z); // fuer den Abstand zur Kamera in z-Richtung wie bei einer Stereokamera // Neue ID ? ==> letzte Person beendet ==> abspeichern - if( personNr > current_personNr ) + if(personNr > current_personNr) { mTracker->append(tp); ++sz; @@ -2482,7 +2633,7 @@ void Petrack::importTracker(QString dest) //default = "" } // TrackPerson leer ? ==> Neue TrackPerson erstellen - if ( tp.isEmpty() ) + if(tp.isEmpty()) { tp = TrackPerson(personNr, frameNr, tPoint); tp.setFirstFrame(frameNr); @@ -2497,12 +2648,14 @@ void Petrack::importTracker(QString dest) //default = "" } mControlWidget->trackNumberAll->setText(QString("%1").arg(mTracker->size())); - mControlWidget->trackShowOnlyNr->setMaximum(MAX(mTracker->size(),1)); - mControlWidget->trackNumberVisible->setText(QString("%1").arg(mTracker->visible(mAnimation->getCurrentFrameNum()))); + mControlWidget->trackShowOnlyNr->setMaximum(MAX(mTracker->size(), 1)); + mControlWidget->trackNumberVisible->setText( + QString("%1").arg(mTracker->visible(mAnimation->getCurrentFrameNum()))); mControlWidget->colorPlot->replot(); file.close(); debout << "import " << dest << " (" << sz << " person(s) )" << std::endl; - mTrcFileName = dest; // fuer Project-File, dann koennte track path direkt mitgeladen werden, wenn er noch da ist + mTrcFileName = + dest; // fuer Project-File, dann koennte track path direkt mitgeladen werden, wenn er noch da ist } else { @@ -2514,90 +2667,104 @@ void Petrack::importTracker(QString dest) //default = "" void Petrack::testTracker() { - static int idx=0; // index in Fehlerliste, die als letztes angesprungen wurde + static int idx = 0; // index in Fehlerliste, die als letztes angesprungen wurde QList<int> pers, frame; - mTracker->checkPlausibility(pers, frame, - mControlWidget->testEqual->isChecked(), - mControlWidget->testVelocity->isChecked(), - mControlWidget->testInside->isChecked(), - mControlWidget->testLength->isChecked()); - if (pers.length()<=idx) - idx=0; - if (pers.length()>idx) + mTracker->checkPlausibility( + pers, + frame, + mControlWidget->testEqual->isChecked(), + mControlWidget->testVelocity->isChecked(), + mControlWidget->testInside->isChecked(), + mControlWidget->testLength->isChecked()); + if(pers.length() <= idx) + idx = 0; + if(pers.length() > idx) { mControlWidget->trackShowOnly->setCheckState(Qt::Checked); mControlWidget->trackShowOnlyNr->setValue(pers[idx]); mPlayerWidget->skipToFrame(frame[idx]); ++idx; } - } int Petrack::calculateRealTracker() { bool autoCorrectOnlyExport = (mReco.getRecoMethod() == reco::RecognitionMethod::MultiColor) && // multicolor - mMultiColorMarkerWidget->autoCorrect->isChecked() && - mMultiColorMarkerWidget->autoCorrectOnlyExport->isChecked(); - int anz = mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), getImageBorderSize(), - mControlWidget->anaMissingFrames->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); + mMultiColorMarkerWidget->autoCorrect->isChecked() && + mMultiColorMarkerWidget->autoCorrectOnlyExport->isChecked(); + int anz = mTrackerReal->calculate( + mTracker, + mImageItem, + mControlWidget->getColorPlot(), + getImageBorderSize(), + mControlWidget->anaMissingFrames->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->calcMinMax(); return anz; } -void Petrack::exportTracker(QString dest) //default = "" +void Petrack::exportTracker(QString dest) // default = "" { static QString lastFile; - if (lastFile == "") + if(lastFile == "") lastFile = mTrcFileName; - if (mTracker) + if(mTracker) { // if no destination file or folder is given - if (dest.isEmpty()) + if(dest.isEmpty()) { - 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 (*.*)")); + 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(""); - if( fileDialog.exec() ){ + if(fileDialog.exec()) + { dest = fileDialog.selectedFiles().at(0); } - } + } - if (!dest.isEmpty()) + if(!dest.isEmpty()) { QList<int> pers, frame; bool autoCorrectOnlyExport = (mReco.getRecoMethod() == reco::RecognitionMethod::MultiColor) && // multicolor - mMultiColorMarkerWidget->autoCorrect->isChecked() && - mMultiColorMarkerWidget->autoCorrectOnlyExport->isChecked(); + mMultiColorMarkerWidget->autoCorrect->isChecked() && + mMultiColorMarkerWidget->autoCorrectOnlyExport->isChecked(); - if (dest.right(4) == ".trc") + if(dest.right(4) == ".trc") { #ifdef TIME_MEASUREMENT double time1 = 0.0, tstart; - tstart = clock(); + tstart = clock(); #endif QTemporaryFile file; - int i; + int i; - if (!file.open()/*!file.open(QIODevice::WriteOnly | QIODevice::Text)*/) + if(!file.open() /*!file.open(QIODevice::WriteOnly | QIODevice::Text)*/) { PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString())); return; } - QProgressDialog progress("Export TRC-File",nullptr,0,mTracker->size()+1,this->window()); + QProgressDialog progress("Export TRC-File", nullptr, 0, mTracker->size() + 1, this->window()); progress.setWindowTitle("Export .trc-File"); progress.setWindowModality(Qt::WindowModal); progress.setVisible(true); @@ -2606,50 +2773,53 @@ void Petrack::exportTracker(QString dest) //default = "" qApp->processEvents(); - trcVersion = 4; + trcVersion = 4; - debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s), file version " << trcVersion << ")..." << std::endl; + debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s), file version " + << trcVersion << ")..." << std::endl; QTextStream out(&file); out << "version " << trcVersion << Qt::endl; out << mTracker->size() << Qt::endl; - for (i = 0; i < mTracker->size(); ++i) + 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); + progress.setLabelText(QString("Export person %1 of %2 ...").arg(i + 1).arg(mTracker->size())); + progress.setValue(i + 1); out << (*mTracker)[i] << Qt::endl; } file.flush(); file.close(); #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(writing) = " << time1 << " sec." << endl; - time1 = 0.0; + time1 = 0.0; tstart = clock(); #endif progress.setLabelText(QString("Save file ...")); qApp->processEvents(); - if (QFile::exists(dest)) + if(QFile::exists(dest)) QFile::remove(dest); - if( !file.copy(dest) ) - PCritical(this, tr("PeTrack"), - tr("Could not export tracking data.\n" - "Please try again!")); + if(!file.copy(dest)) + PCritical( + this, + tr("PeTrack"), + tr("Could not export tracking data.\n" + "Please try again!")); else statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000); - progress.setValue(mTracker->size()+1); + progress.setValue(mTracker->size() + 1); std::cout << " finished " << std::endl; #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(copying) = " << time1 << " sec." << endl; // time1 = 0.0; @@ -2661,63 +2831,77 @@ void Petrack::exportTracker(QString dest) //default = "" // 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 + mTrcFileName = + dest; // fuer Project-File, dann koennte track path direkt mitgeladen werden, wenn er noch da ist } - else if (dest.right(4) == ".txt") + else if(dest.right(4) == ".txt") { QTemporaryFile file; - if (!file.open()) + if(!file.open()) { PCritical(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))..." << std::endl; + debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s))..." + << std::endl; #ifdef TIME_MEASUREMENT double time1 = 0.0, tstart; - tstart = clock(); + 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()) + // 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 + 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; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(recalcHeight) = " << time1 << " sec." << endl; - time1 = 0.0; + 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); + 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; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(calculate) = " << time1 << " sec." << endl; - time1 = 0.0; + time1 = 0.0; tstart = clock(); #endif QTextStream out(&file); - out << "# PeTrack project: " << QFileInfo(getProFileName()).fileName() << Qt::endl; + out << "# PeTrack project: " << QFileInfo(getProFileName()).fileName() << Qt::endl; out << "# raw trajectory file: " << QFileInfo(getTrackFileName()).fileName() << Qt::endl; - out << "# framerate: " << mAnimation->getFPS() << " fps" << Qt::endl; + out << "# framerate: " << mAnimation->getFPS() << " fps" << Qt::endl; - if (mControlWidget->exportComment->isChecked()) + if(mControlWidget->exportComment->isChecked()) { out << "# personal information:" << Qt::endl; out << "# ID| Comment" << Qt::endl; @@ -2727,38 +2911,42 @@ void Petrack::exportTracker(QString dest) //default = "" std::cout << "ID | Comment" << std::endl; std::cout << "----|----------------" << std::endl; - for(int i=0;i<mTracker->size();++i) + 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 << std::setw(4) << (i+1) << "|" << commentSplit.at(0) << std::endl; + out << "#" << qSetFieldWidth(3) << (i + 1) << qSetFieldWidth(0) << "|" << commentSplit.at(0) + << Qt::endl; + std::cout << std::setw(4) << (i + 1) << "|" << commentSplit.at(0) << std::endl; commentSplit.pop_front(); - for (const auto& line : commentSplit) + for(const auto &line : commentSplit) { out << "#" << qSetFieldWidth(3) << " " << qSetFieldWidth(0) << "|" << line << Qt::endl; std::cout << " |" << line << std::endl; } } } - mTrackerReal->exportTxt(out, - mControlWidget->trackAlternateHeight->checkState(), - mStereoWidget->stereoUseForExport->isChecked(), - mControlWidget->exportViewDir->isChecked(), - mControlWidget->exportAngleOfView->isChecked(), - mControlWidget->exportUseM->isChecked(), - mControlWidget->exportMarkerID->isChecked()); - //out << *mTrackerReal; + 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)) + if(QFile::exists(dest)) QFile::remove(dest); - if( !file.copy(dest) ) - PCritical(this, tr("PeTrack"), - tr("Could not export tracking data.\n" - "Please try again!")); + if(!file.copy(dest)) + PCritical( + this, + tr("PeTrack"), + tr("Could not export tracking data.\n" + "Please try again!")); else statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000); @@ -2766,7 +2954,7 @@ void Petrack::exportTracker(QString dest) //default = "" #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(export) = " << time1 << " sec." << endl; // time1 = 0.0; @@ -2779,70 +2967,102 @@ void Petrack::exportTracker(QString dest) //default = "" // cout << " time(checkPlausibility) = " << time1 << " sec." << endl; #endif } - else if (dest.right(4) == ".dat") + else if(dest.right(4) == ".dat") { QTemporaryFile fileDat; - if (!fileDat.open()) //!fileDat.open(QIODevice::WriteOnly | QIODevice::Text)) + if(!fileDat.open()) //! fileDat.open(QIODevice::WriteOnly | QIODevice::Text)) { PCritical(this, tr("PeTrack"), tr("Cannot open %1:\n%2.").arg(dest).arg(fileDat.errorString())); return; } - // recalcHeight true, wenn personenhoehe ueber trackpoints neu berechnet werden soll (z.b. um waehrend play mehrfachberuecksichtigung von punkten auszuschliessen, aenderungen in altitude neu in berechnung einfliessen zu lassen) - if (mControlWidget->trackRecalcHeight->checkState()) + // 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; + mTrackerReal->calculate( + mTracker, + mImageItem, + mControlWidget->getColorPlot(), + getImageBorderSize(), + mControlWidget->trackMissingFrames->checkState(), + mStereoWidget->stereoUseForExport->isChecked(), + mControlWidget->trackAlternateHeight->checkState(), + mControlWidget->coordAltitude->value(), + mStereoWidget->stereoUseCalibrationCenter->isChecked(), + mControlWidget->exportElimTp->isChecked(), + mControlWidget->exportElimTrj->isChecked(), + mControlWidget->exportSmooth->isChecked(), + mControlWidget->exportViewDir->isChecked(), + mControlWidget->exportAngleOfView->isChecked(), + mControlWidget->exportMarkerID->isChecked(), + autoCorrectOnlyExport); + + debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s))..." + << std::endl; QTextStream outDat(&fileDat); - mTrackerReal->exportDat(outDat, mControlWidget->trackAlternateHeight->checkState(), mStereoWidget->stereoUseForExport->isChecked()); + mTrackerReal->exportDat( + outDat, + mControlWidget->trackAlternateHeight->checkState(), + mStereoWidget->stereoUseForExport->isChecked()); fileDat.flush(); fileDat.close(); - if (QFile::exists(dest)) + if(QFile::exists(dest)) QFile::remove(dest); - if( !fileDat.copy(dest) ) - PCritical(this, tr("PeTrack"), - tr("Could not export tracking data.\n" - "Please try again!")); + if(!fileDat.copy(dest)) + PCritical( + this, + tr("PeTrack"), + tr("Could not export tracking data.\n" + "Please try again!")); else statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000); std::cout << " finished" << std::endl; } - else if (dest.right(5) == ".trav") + 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()) + // 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(), + mControlWidget->exportViewDir->isChecked(), + mControlWidget->exportAngleOfView->isChecked(), + mControlWidget->exportMarkerID->isChecked(), + autoCorrectOnlyExport); QTemporaryFile fileXml; - if (!fileXml.open()) //!fileXml.open(QIODevice::WriteOnly | QIODevice::Text)) + if(!fileXml.open()) //! fileXml.open(QIODevice::WriteOnly | QIODevice::Text)) { PCritical(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; - // already done: mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), getImageBorderSize(), mControlWidget->trackMissingFrames->checkState()); + debout << "export tracking data to " << dest << " (" << mTracker->size() << " person(s))..." + << std::endl; + // already done: mTrackerReal->calculate(mTracker, mImageItem, mControlWidget->getColorPlot(), + // getImageBorderSize(), mControlWidget->trackMissingFrames->checkState()); QTextStream outXml(&fileXml); outXml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << Qt::endl; outXml << "<trajectoriesDataset>" << Qt::endl; @@ -2851,24 +3071,31 @@ void Petrack::exportTracker(QString dest) //default = "" outXml << " <roomID>0</roomID>" << Qt::endl; outXml << " <agents>" << mTracker->size() << "</agents>" << Qt::endl; outXml << " <frameRate>" << mAnimation->getFPS() << "</frameRate> <!--per second-->" << Qt::endl; - // outXml << " <timeStep>" << 1000./mAnimation->getFPS() << "</timeStep> <!-- millisecond-->" << endl; inverse von - outXml << " <timeFirstFrame sec=\"" << mAnimation->getFirstFrameSec() << "\" microsec=\"" << mAnimation->getFirstFrameMicroSec() - << "\"/> <!-- " << mAnimation->getTimeString(0) << " -->" << Qt::endl; - outXml << " </header>" << Qt::endl<< Qt::endl; - - mTrackerReal->exportXml(outXml, mControlWidget->trackAlternateHeight->checkState(), mStereoWidget->stereoUseForExport->isChecked()); + // outXml << " <timeStep>" << 1000./mAnimation->getFPS() << "</timeStep> <!-- millisecond-->" + // << endl; inverse von + outXml << " <timeFirstFrame sec=\"" << mAnimation->getFirstFrameSec() << "\" microsec=\"" + << mAnimation->getFirstFrameMicroSec() << "\"/> <!-- " << mAnimation->getTimeString(0) << " -->" + << Qt::endl; + outXml << " </header>" << Qt::endl << Qt::endl; + + mTrackerReal->exportXml( + outXml, + mControlWidget->trackAlternateHeight->checkState(), + mStereoWidget->stereoUseForExport->isChecked()); outXml << "</trajectoriesDataset>" << Qt::endl; fileXml.flush(); fileXml.close(); - if (QFile::exists(dest)) + if(QFile::exists(dest)) QFile::remove(dest); - if( !fileXml.copy(dest) ) - PCritical(this, tr("PeTrack"), - tr("Could not export tracking data.\n" - "Please try again!")); + if(!fileXml.copy(dest)) + PCritical( + this, + tr("PeTrack"), + tr("Could not export tracking data.\n" + "Please try again!")); else statusBar()->showMessage(tr("Saved tracking data to %1.").arg(dest), 5000); @@ -2887,7 +3114,7 @@ void Petrack::exportTracker(QString dest) //default = "" // fuer anschliessende groessenberechnung void Petrack::playAll() { - int memPos = mPlayerWidget->getPos(); + int memPos = mPlayerWidget->getPos(); int progVal = 0; QProgressDialog progress("Playing whole sequence...", "Abort playing", 0, mAnimation->getNumFrames(), this); @@ -2896,12 +3123,11 @@ void Petrack::playAll() // vorwaertslaufen ab aktueller Stelle und trackOnlineCalc zum tracken nutzen do { - progress.setValue(++progVal); //mPlayerWidget->getPos() + progress.setValue(++progVal); // mPlayerWidget->getPos() qApp->processEvents(); - if (progress.wasCanceled()) + if(progress.wasCanceled()) break; - } - while (mPlayerWidget->frameForward()); + } while(mPlayerWidget->frameForward()); mPlayerWidget->skipToFrame(memPos); } @@ -2919,37 +3145,41 @@ void Petrack::playAll() */ void Petrack::trackAll() { - int memPos = mPlayerWidget->getPos(); - int progVal = 0; + int memPos = mPlayerWidget->getPos(); + int progVal = 0; enum Qt::CheckState memCheckState = mControlWidget->trackOnlineCalc->checkState(); - enum Qt::CheckState memRecoState = mControlWidget->performRecognition->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); + QProgressDialog progress( + "Tracking pedestrians through all frames...", + "Abort tracking", + 0, + 2 * mAnimation->getNumFrames() - memPos, + this); progress.setWindowModality(Qt::WindowModal); // blocks main window // vorwaertslaufen ab aktueller Stelle und trackOnlineCalc zum tracken nutzen do { - progress.setValue(++progVal); //mPlayerWidget->getPos() + progress.setValue(++progVal); // mPlayerWidget->getPos() qApp->processEvents(); - if (progress.wasCanceled()) + if(progress.wasCanceled()) break; - } - while (mPlayerWidget->frameForward()); + } while(mPlayerWidget->frameForward()); - if (mAutoBackTrack) + 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); + 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() + // 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!!!!!!!!!! @@ -2959,21 +3189,20 @@ void Petrack::trackAll() // rueckwaertslaufen do { - if (progVal+1 < 2*mAnimation->getNumFrames()-memPos) - progress.setValue(++progVal); //mPlayerWidget->getPos() + if(progVal + 1 < 2 * mAnimation->getNumFrames() - memPos) + progress.setValue(++progVal); // mPlayerWidget->getPos() qApp->processEvents(); - if (progress.wasCanceled()) + if(progress.wasCanceled()) break; - if (mPlayerWidget->getPos() == memPos+1) + if(mPlayerWidget->getPos() == memPos + 1) mControlWidget->performRecognition->setCheckState(Qt::Checked); - } - while (mPlayerWidget->frameBackward()); + } while(mPlayerWidget->frameBackward()); // bei abbruch koennen es auch mPlayerWidget->getPos() frames sein, die bisher geschrieben wurden - progress.setValue(2*mAnimation->getNumFrames()-memPos); + progress.setValue(2 * mAnimation->getNumFrames() - memPos); } - if (mAutoTrackOptimizeColor) + if(mAutoTrackOptimizeColor) mTracker->optimizeColor(); mControlWidget->performRecognition->setCheckState(memRecoState); @@ -2987,31 +3216,29 @@ 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) + if(level == -1) level = mControlWidget->trackRegionLevels->value(); - return (int)((getHeadSize(pos, pers, frame) / pow(2.,level)) * (mControlWidget->trackRegionScale->value() / 10.)); + 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; + debout << "go update: " << getElapsedTime() << endl; #endif mCodeMarkerItem->resetSavedMarkers(); - static int lastRecoFrame = -10000; + static int lastRecoFrame = -10000; static bool borderChangedForTracking = false; // 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()) + if(!mImg.empty() && mImage && semaphore.tryAcquire()) { - int frameNum = mAnimation->getCurrentFrameNum(); setStatusTime(); @@ -3022,95 +3249,99 @@ void Petrack::updateImage(bool imageChanged) // default = false (only true for n // have to store because evaluation sets the filter parameter to unchanged bool brightContrastChanged = mBrightContrastFilter.changed(); - bool swapChanged = mSwapFilter.changed(); - bool borderChanged = mBorderFilter.changed(); - bool calibChanged = mCalibFilter->changed(); + bool swapChanged = mSwapFilter.changed(); + bool borderChanged = mBorderFilter.changed(); + bool calibChanged = mCalibFilter->changed(); // speicherverwaltung wird komplett von filtern ueberneommen // Filter anwenden, Reihenfolge wichtig - Rechenintensive moeglichst frueh // fkt so nur mit kopierenden filtern #ifdef TIME_MEASUREMENT - // "==========: " - debout << "vor filter: " << getElapsedTime() <<endl; + // "==========: " + debout << "vor filter: " << getElapsedTime() << endl; #endif - if (imageChanged || swapChanged) + if(imageChanged || swapChanged) mImgFiltered = mSwapFilter.apply(mImgFiltered); else mImgFiltered = mSwapFilter.getLastResult(); - if (imageChanged || swapChanged || brightContrastChanged) + if(imageChanged || swapChanged || brightContrastChanged) mImgFiltered = mBrightContrastFilter.apply(mImgFiltered); else mImgFiltered = mBrightContrastFilter.getLastResult(); - if (imageChanged || swapChanged || brightContrastChanged || borderChanged) + if(imageChanged || swapChanged || brightContrastChanged || borderChanged) mImgFiltered = mBorderFilter.apply(mImgFiltered); // mIplImg else mImgFiltered = mBorderFilter.getLastResult(); #ifdef TIME_MEASUREMENT - // "==========: " - debout << "nch filter: " << getElapsedTime() <<endl; + // "==========: " + debout << "nch filter: " << getElapsedTime() << endl; #endif - if (borderChanged) + if(borderChanged) updateControlImage(mImgFiltered); #ifndef STEREO_DISABLED - if (imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged) + if(imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged) { - if (mStereoContext) + if(mStereoContext) mStereoContext->init(mImgFiltered); } #endif #ifdef TIME_MEASUREMENT - // "==========: " - debout << "vor calib: " << getElapsedTime() <<endl; + // "==========: " + debout << "vor calib: " << getElapsedTime() << endl; #endif - if (imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged) + if(imageChanged || swapChanged || brightContrastChanged || borderChanged || calibChanged) mImgFiltered = mCalibFilter->apply(mImgFiltered); else mImgFiltered = mCalibFilter->getLastResult(); #ifdef TIME_MEASUREMENT - // "==========: " - debout << "nach calib: " << getElapsedTime() <<endl; + // "==========: " + debout << "nach calib: " << getElapsedTime() << endl; #endif - if (brightContrastChanged || swapChanged || borderChanged || calibChanged) + if(brightContrastChanged || swapChanged || borderChanged || calibChanged) { - // abfrage hinzugenommen, damit beim laden von .pet bg-file angegeben werden kann fuer mehrere versuche und beim nachladen von versuch nicht bg geloescht wird - if (mBackgroundFilter.getFilename() != "") - debout << "Warning: No background reset, because of explicit loaded background image!" <<std::endl; + // abfrage hinzugenommen, damit beim laden von .pet bg-file angegeben werden kann fuer mehrere versuche und + // beim nachladen von versuch nicht bg geloescht wird + if(mBackgroundFilter.getFilename() != "") + debout << "Warning: No background reset, because of explicit loaded background image!" << std::endl; else - mBackgroundFilter.reset(); // alle gesammelten hintergrundinfos werden verworfen und bg.changed auf true gesetzt + mBackgroundFilter + .reset(); // alle gesammelten hintergrundinfos werden verworfen und bg.changed auf true gesetzt } - if (imageChanged || mBackgroundFilter.changed()) + if(imageChanged || mBackgroundFilter.changed()) mImgFiltered = mBackgroundFilter.apply(mImgFiltered); else mImgFiltered = mBackgroundFilter.getLastResult(); #ifdef TIME_MEASUREMENT - // "==========: " - debout << "nach bg: " << getElapsedTime() <<endl; + // "==========: " + debout << "nach bg: " << getElapsedTime() << endl; #endif // delete track list, if intrinsic param have changed - if (calibChanged && mTracker->size() > 0) //mCalibFilter.getEnabled() && + if(calibChanged && mTracker->size() > 0) // mCalibFilter.getEnabled() && { // Evtl. nicht Tracker loeschen sondern entsprechend der neuen Calibration verschieben?!?!? mTracker->clear(); mTracker->reset(); - if( !isLoading() ) - debout << "Warning: deleted all tracking pathes because intrinsic parameters have changed." << std::endl; + if(!isLoading()) + debout << "Warning: deleted all tracking pathes because intrinsic parameters have changed." + << std::endl; } else { #ifndef STEREO_DISABLED // calculate position in 3D space and height of person for "old" trackPoints, if checked "even" - if (mStereoContext && mStereoWidget->stereoUseForHeightEver->isChecked() && mStereoWidget->stereoUseForHeight->isChecked()) + if(mStereoContext && mStereoWidget->stereoUseForHeightEver->isChecked() && + mStereoWidget->stereoUseForHeight->isChecked()) { // buildt disparity picture if it should be used for height detection mStereoContext->getDisparity(); @@ -3119,21 +3350,23 @@ void Petrack::updateImage(bool imageChanged) // default = false (only true for n } #endif } - if (borderChanged) + 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 ??? + 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())); + QRect roi( + myRound(mTrackingRoiItem->rect().x() + getImageBorderSize()), + myRound(mTrackingRoiItem->rect().y() + getImageBorderSize()), + myRound(mTrackingRoiItem->rect().width()), + myRound(mTrackingRoiItem->rect().height())); - if (borderChangedForTracking) + if(borderChangedForTracking) { cv::Size size; - size.width = mImgFiltered.cols; + size.width = mImgFiltered.cols; size.height = mImgFiltered.rows; mTracker->resize(size); @@ -3141,7 +3374,7 @@ void Petrack::updateImage(bool imageChanged) // default = false (only true for n } #ifndef STEREO_DISABLED // buildt disparity picture if it should be used for height detection - if (mStereoContext && mStereoWidget->stereoUseForHeight->isChecked()) + if(mStereoContext && mStereoWidget->stereoUseForHeight->isChecked()) mStereoContext->getDisparity(); #endif @@ -3149,61 +3382,72 @@ void Petrack::updateImage(bool imageChanged) // default = false (only true for n 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 + // 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; + debout << "vor track: " << getElapsedTime() << endl; #endif -// debout << "test" << endl; - int anz = mTracker->track(mImgFiltered, rect, frameNum, - mControlWidget->trackRepeat->isChecked(), - mControlWidget->trackRepeatQual->value(), getImageBorderSize(), - mReco.getRecoMethod(), mControlWidget->trackRegionLevels->value(), - getPedestriansToTrack()); + // debout << "test" << endl; + int anz = mTracker->track( + mImgFiltered, + rect, + frameNum, + mControlWidget->trackRepeat->isChecked(), + mControlWidget->trackRepeatQual->value(), + getImageBorderSize(), + mReco.getRecoMethod(), + mControlWidget->trackRegionLevels->value(), + getPedestriansToTrack()); #ifdef TIME_MEASUREMENT - debout << "nach track: " << getElapsedTime() <<endl; + debout << "nach track: " << getElapsedTime() << endl; #endif mControlWidget->trackNumberNow->setText(QString("%1").arg(anz)); - mTrackChanged = false; + mTrackChanged = false; borderChangedForTracking = false; } else mControlWidget->trackNumberNow->setText(QString("0")); // hier muesste fuer ameisen etc allgemeinABC.getPosList(...) - if (((((lastRecoFrame+mControlWidget->recoStep->value()) <= frameNum) || - ((lastRecoFrame-mControlWidget->recoStep->value()) >= frameNum)) && - imageChanged) || mAnimation->isCameraLiveStream() || swapChanged || brightContrastChanged || borderChanged || calibChanged || recognitionChanged()) + if(((((lastRecoFrame + mControlWidget->recoStep->value()) <= frameNum) || + ((lastRecoFrame - mControlWidget->recoStep->value()) >= frameNum)) && + imageChanged) || + mAnimation->isCameraLiveStream() || swapChanged || brightContrastChanged || borderChanged || calibChanged || + recognitionChanged()) { #ifndef STEREO_DISABLED // buildt disparity picture if it should be used for height detection or recognition - if (mStereoContext && (mStereoWidget->stereoUseForHeight->isChecked() || mStereoWidget->stereoUseForReco->isChecked())) + if(mStereoContext && + (mStereoWidget->stereoUseForHeight->isChecked() || mStereoWidget->stereoUseForReco->isChecked())) mStereoContext->getDisparity(); // wird nicht neu berechnet, wenn vor tracking schon berechnet wurde #endif - if (borderChanged) + if(borderChanged) mRecognitionRoiItem->checkRect(); - if (mControlWidget->performRecognition->checkState() == Qt::Checked) + 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())); + QRect rect( + myRound(mRecognitionRoiItem->rect().x() + getImageBorderSize()), + myRound(mRecognitionRoiItem->rect().y() + getImageBorderSize()), + myRound(mRecognitionRoiItem->rect().width()), + myRound(mRecognitionRoiItem->rect().height())); QList<TrackPoint> persList; - auto recoMethod = mReco.getRecoMethod(); + auto recoMethod = mReco.getRecoMethod(); #ifdef TIME_MEASUREMENT // "==========: " - debout << "vor reco: " << getElapsedTime() <<endl; + debout << "vor reco: " << getElapsedTime() << endl; #endif - if ((recoMethod == reco::RecognitionMethod::Casern) || (recoMethod == reco::RecognitionMethod::Hermes) - || (recoMethod == reco::RecognitionMethod::Color) || (recoMethod == reco::RecognitionMethod::Japan) - || (recoMethod == reco::RecognitionMethod::MultiColor) || (recoMethod == reco::RecognitionMethod::Code)) //else + if((recoMethod == reco::RecognitionMethod::Casern) || (recoMethod == reco::RecognitionMethod::Hermes) || + (recoMethod == reco::RecognitionMethod::Color) || (recoMethod == reco::RecognitionMethod::Japan) || + (recoMethod == reco::RecognitionMethod::MultiColor) || + (recoMethod == reco::RecognitionMethod::Code)) // else { - persList = mReco.getMarkerPos(mImgFiltered, rect, mControlWidget, getImageBorderSize(), getBackgroundFilter()); + persList = mReco.getMarkerPos( + mImgFiltered, rect, mControlWidget, getImageBorderSize(), getBackgroundFilter()); } #ifndef STEREO_DISABLED - if (mStereoContext && mStereoWidget->stereoUseForReco->isChecked()) + if(mStereoContext && mStereoWidget->stereoUseForReco->isChecked()) { PersonList pl; pl.calcPersonPos(mImgFiltered, rect, &persList, mStereoContext, getBackgroundFilter(), markerLess); @@ -3211,19 +3455,20 @@ void Petrack::updateImage(bool imageChanged) // default = false (only true for n #endif #ifdef TIME_MEASUREMENT // "==========: " - debout << "nach reco: " << getElapsedTime() <<endl; + debout << "nach reco: " << getElapsedTime() << endl; #endif mTracker->addPoints(persList, frameNum, mReco.getRecoMethod()); // folgendes lieber im Anschluss, ggf beim exportieren oder statt test direkt del: - if (mStereoContext && mStereoWidget->stereoUseForReco->isChecked()) + if(mStereoContext && mStereoWidget->stereoUseForReco->isChecked()) mTracker->purge(frameNum); // bereinigen wenn weniger als 0.2 recognition und nur getrackt mControlWidget->recoNumberNow->setText(QString("%1").arg(persList.size())); mRecognitionChanged = false; - if (false) // hier muss Abfage hin ob kasernen marker genutzt wird - mControlWidget->getColorPlot()->replot(); // oder nur wenn tab offen oder wenn sich mtracker geaendert hat??? + 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")); @@ -3232,26 +3477,29 @@ void Petrack::updateImage(bool imageChanged) // default = false (only true for n 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 + 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); - if (borderChanged) + if(borderChanged) mImageItem->setImage(mImage); else { - getScene()->update(); //repaint(); + getScene()->update(); // repaint(); // update pixel color (because image pixel moves) setStatusColor(); } #ifdef QWT mControlWidget->getAnalysePlot()->setActFrame(frameNum); - if (mControlWidget->anaMarkAct->isChecked()) + if(mControlWidget->anaMarkAct->isChecked()) { mControlWidget->getAnalysePlot()->replot(); } @@ -3261,7 +3509,7 @@ void Petrack::updateImage(bool imageChanged) // default = false (only true for n } #ifdef TIME_MEASUREMENT // "==========: " - debout << "stp update: " << getElapsedTime() <<endl; + debout << "stp update: " << getElapsedTime() << endl; #endif } void Petrack::updateImage(const cv::Mat &img) @@ -3276,28 +3524,28 @@ void Petrack::updateSequence() QImage *oldImage = mImage; QSize size = mAnimation->getSize(); - size.setWidth(size.width()+2*getImageBorderSize());// border is inside the mImage! - size.setHeight(size.height()+2*getImageBorderSize()); - mImage = new QImage(size, QImage::Format_RGB888);//32); //wird in updateImage gemacht + size.setWidth(size.width() + 2 * getImageBorderSize()); // border is inside the mImage! + size.setHeight(size.height() + 2 * getImageBorderSize()); + mImage = new QImage(size, QImage::Format_RGB888); // 32); //wird in updateImage gemacht // set roi for recognition if image size changes or roi is zero - //in oldImage steckt border drin, mIplImg->height zeigt noch auf altes ursprungsbild + // 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())))) + 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())))) + if((mTrackingRoiItem->rect().width() == 0) || + (oldImage && ((oldImage->width() != mImage->width()) || (oldImage->height() != mImage->height())))) mTrackingRoiItem->setRect(-getImageBorderSize(), -getImageBorderSize(), mImage->width(), mImage->height()); cv::Size size2; - size2.width = mTrackingRoiItem->rect().width(); + size2.width = mTrackingRoiItem->rect().width(); size2.height = mTrackingRoiItem->rect().height(); mTracker->init(size2); mPlayerWidget->setAnim(mAnimation); mPlayerWidget->skipToFrame(0); - mImageItem->setImage(mImage);//wird in updateImage gemacht + mImageItem->setImage(mImage); // wird in updateImage gemacht delete oldImage; mSaveSeqVidAct->setEnabled(true); mSaveSeqVidViewAct->setEnabled(true); @@ -3334,12 +3582,13 @@ double Petrack::getCmPerPixel() const */ void Petrack::setHeadSize(double hS) { - if (hS == -1) + if(hS == -1) { mCmPerPixel = getImageItem()->getCmPerPixel(); - //debout << mCmPerPixel <<endl; - mHeadSize = (HEAD_SIZE*mControlWidget->coordAltitude->value() / (mControlWidget->coordAltitude->value()-mControlWidget->mapDefaultHeight->value())) / - mCmPerPixel; + // debout << mCmPerPixel <<endl; + mHeadSize = (HEAD_SIZE * mControlWidget->coordAltitude->value() / + (mControlWidget->coordAltitude->value() - mControlWidget->mapDefaultHeight->value())) / + mCmPerPixel; } else mHeadSize = hS; @@ -3350,42 +3599,48 @@ double Petrack::getHeadSize(QPointF *pos, int pers, int frame) { double z, h; - if ((pers >= 0) && (pers < mTracker->size()) && mTracker->at(pers).trackPointExist(frame)) + if((pers >= 0) && (pers < mTracker->size()) && mTracker->at(pers).trackPointExist(frame)) { - if( mControlWidget->getCalibCoordDimension() == 0 ) + if(mControlWidget->getCalibCoordDimension() == 0) { - - int diff; - cv::Point3f p3d = getExtrCalibration()->get3DPoint(cv::Point2f(mTracker->at(pers).trackPointAt(frame).x(), - mTracker->at(pers).trackPointAt(frame).y()), - mControlWidget->mapDefaultHeight->value()); - - cv::Point2f p3d_x1 = getExtrCalibration()->getImagePoint( cv::Point3f(p3d.x+HEAD_SIZE*0.5, p3d.y, p3d.z) ); - cv::Point2f p3d_x2 = getExtrCalibration()->getImagePoint( cv::Point3f(p3d.x-HEAD_SIZE*0.5, p3d.y, p3d.z) ); - cv::Point2f p3d_y1 = getExtrCalibration()->getImagePoint( cv::Point3f(p3d.x, p3d.y+HEAD_SIZE*0.5, p3d.z) ); - cv::Point2f p3d_y2 = getExtrCalibration()->getImagePoint( cv::Point3f(p3d.x, p3d.y-HEAD_SIZE*0.5, p3d.z) ); - - diff = (int) std::max(sqrt(pow(p3d_x2.x-p3d_x1.x,2)+pow(p3d_x2.y-p3d_x1.y,2)), - sqrt(pow(p3d_y2.x-p3d_y1.x,2)+pow(p3d_y2.y-p3d_y1.y,2))); - return diff;// < 8 ? 8 : diff; - }else + int diff; + cv::Point3f p3d = getExtrCalibration()->get3DPoint( + cv::Point2f(mTracker->at(pers).trackPointAt(frame).x(), mTracker->at(pers).trackPointAt(frame).y()), + mControlWidget->mapDefaultHeight->value()); + + cv::Point2f p3d_x1 = + getExtrCalibration()->getImagePoint(cv::Point3f(p3d.x + HEAD_SIZE * 0.5, p3d.y, p3d.z)); + cv::Point2f p3d_x2 = + getExtrCalibration()->getImagePoint(cv::Point3f(p3d.x - HEAD_SIZE * 0.5, p3d.y, p3d.z)); + cv::Point2f p3d_y1 = + getExtrCalibration()->getImagePoint(cv::Point3f(p3d.x, p3d.y + HEAD_SIZE * 0.5, p3d.z)); + cv::Point2f p3d_y2 = + getExtrCalibration()->getImagePoint(cv::Point3f(p3d.x, p3d.y - HEAD_SIZE * 0.5, p3d.z)); + + diff = (int) std::max( + sqrt(pow(p3d_x2.x - p3d_x1.x, 2) + pow(p3d_x2.y - p3d_x1.y, 2)), + sqrt(pow(p3d_y2.x - p3d_y1.x, 2) + pow(p3d_y2.y - p3d_y1.y, 2))); + return diff; // < 8 ? 8 : diff; + } + else { z = mTracker->at(pers).trackPointAt(frame).sp().z(); h = mTracker->at(pers).height(); - if (z > 0) - return (HEAD_SIZE*mControlWidget->coordAltitude->value() / z) / getImageItem()->getCmPerPixel(); - else if (h > MIN_HEIGHT) - return (HEAD_SIZE*mControlWidget->coordAltitude->value() / (mControlWidget->coordAltitude->value()-h)) / getImageItem()->getCmPerPixel(); + 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 != nullptr) + if(pos != nullptr) return mHeadSize; // muss noch aus density map gelesen werden!!! - else //(pos == NULL) && (pers == -1) + else //(pos == NULL) && (pers == -1) return mHeadSize; - } /** @@ -3398,49 +3653,49 @@ double Petrack::getHeadSize(QPointF *pos, int pers, int frame) */ QSet<int> Petrack::getPedestrianUserSelection() { - if (mControlWidget->trackShowOnly->checkState() == Qt::Checked) { + if(mControlWidget->trackShowOnly->checkState() == Qt::Checked) + { QSet<int> onlyVisible; onlyVisible.insert(mControlWidget->trackShowOnlyNr->value() - 1); return onlyVisible; } - if (mControlWidget->trackShowOnlyList->checkState() == Qt::Checked) { - QStringList list = mControlWidget->trackShowOnlyNrList->text().split( - ",", Qt::SkipEmptyParts); - QSet<int> onlyVisible; - foreach (QString s, list) + if(mControlWidget->trackShowOnlyList->checkState() == Qt::Checked) + { + QStringList list = mControlWidget->trackShowOnlyNrList->text().split(",", Qt::SkipEmptyParts); + QSet<int> onlyVisible; + foreach(QString s, list) { bool ok = false; - int nr = s.toInt(&ok); - if (ok /* && nr <= maxPed && nr > 0*/) // einzelne ID + int nr = s.toInt(&ok); + if(ok /* && nr <= maxPed && nr > 0*/) // einzelne ID { onlyVisible.insert(nr - 1); } else // error or IDs range (e.g. 1-3, 6-10, etc.) { QStringList range = s.split("-", Qt::SkipEmptyParts); - int last, first = range[0].toInt(&ok); + int last, first = range[0].toInt(&ok); - if (ok /* && first <= maxPed && nr > 0*/) + if(ok /* && first <= maxPed && nr > 0*/) { last = range[1].toInt(&ok); - if (ok /* && last <= maxPed && nr > 0*/) + if(ok /* && last <= maxPed && nr > 0*/) { - if (first > last) - { - std::swap(first, last); - } - - for (int i = first; i <= last; i++) - { - onlyVisible.insert(i - 1); - } + if(first > last) + { + std::swap(first, last); + } + + for(int i = first; i <= last; i++) + { + onlyVisible.insert(i - 1); + } } } } - if (!ok) + if(!ok) { - debout << "Warning: error while reading showOnlyVisible list from input line!" - << std::endl; + debout << "Warning: error while reading showOnlyVisible list from input line!" << std::endl; } } return onlyVisible; // in anzeige wird ab 1 gezaehlt, in datenstruktur ab 0 @@ -3459,19 +3714,19 @@ QSet<int> Petrack::getPedestrianUserSelection() */ QSet<int> Petrack::getPedestriansToTrack() { - if (mControlWidget->trackOnlySelected->checkState() == Qt::Checked) + if(mControlWidget->trackOnlySelected->checkState() == Qt::Checked) { - return getPedestrianUserSelection(); + return getPedestrianUserSelection(); } return QSet<int>(); } -void Petrack::addManualTrackPointOnlyVisible(const QPointF& pos) +void Petrack::addManualTrackPointOnlyVisible(const QPointF &pos) { - int pers = addOrMoveManualTrackPoint(pos)+1; - if (pers == 0) - pers = mTracker->size()+1; + int pers = addOrMoveManualTrackPoint(pos) + 1; + if(pers == 0) + pers = mTracker->size() + 1; pers = mControlWidget->trackShowOnlyNr->maximum(); mControlWidget->trackShowOnlyNr->setValue(pers); mControlWidget->trackShowOnly->setChecked(true); @@ -3480,14 +3735,13 @@ void Petrack::addManualTrackPointOnlyVisible(const QPointF& pos) void Petrack::updateControlWidget() { mControlWidget->trackNumberAll->setText(QString("%1").arg(mTracker->size())); - mControlWidget->trackShowOnlyNr->setMaximum(MAX(mTracker->size(),1)); + mControlWidget->trackShowOnlyNr->setMaximum(MAX(mTracker->size(), 1)); mControlWidget->trackNumberVisible->setText(QString("%1").arg(mTracker->visible(mAnimation->getCurrentFrameNum()))); } void Petrack::splitTrackPerson(QPointF pos) { - mTracker->splitPersonAt((Vec2F) pos, mAnimation->getCurrentFrameNum(), - getPedestrianUserSelection()); + mTracker->splitPersonAt((Vec2F) pos, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection()); updateControlWidget(); } @@ -3501,48 +3755,43 @@ void Petrack::splitTrackPerson(QPointF pos) * @param pos pixel position of mouse on image * @return index of person whose point was moved; -1 if failed or new trajectory is started */ -int Petrack::addOrMoveManualTrackPoint(const QPointF& pos) +int Petrack::addOrMoveManualTrackPoint(const QPointF &pos) { - int pers = -1; + int pers = -1; TrackPoint tP(Vec2F{pos}, 110); // 110 is higher than 100 (max. quality) and gets clamped to 100 after insertion // allows replacemet of every point (check for better quality always passes) - mTracker->addPoint(tP, mAnimation->getCurrentFrameNum(), - getPedestrianUserSelection(), mReco.getRecoMethod(), &pers); + mTracker->addPoint( + tP, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection(), mReco.getRecoMethod(), &pers); updateControlWidget(); return pers; } // direction zeigt an, ob bis zum aktuellen (-1), ab dem aktuellen (1) oder ganzer trackpath (0) // loeschen von Trackpoints einer Trajektorie -void Petrack::deleteTrackPoint(QPointF pos, int direction) //const QPoint &pos +void Petrack::deleteTrackPoint(QPointF pos, int direction) // const QPoint &pos { - mTracker->delPoint((Vec2F) pos, direction, mAnimation->getCurrentFrameNum(), - getPedestrianUserSelection()); + mTracker->delPoint((Vec2F) pos, direction, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection()); updateControlWidget(); } void Petrack::editTrackPersonComment(QPointF pos) { - - mTracker->editTrackPersonComment((Vec2F) pos, mAnimation->getCurrentFrameNum(), - getPedestrianUserSelection()); + mTracker->editTrackPersonComment((Vec2F) pos, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection()); updateControlWidget(); } void Petrack::setTrackPersonHeight(QPointF pos) { - mTracker->setTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(), - getPedestrianUserSelection()); + mTracker->setTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection()); updateControlWidget(); } void Petrack::resetTrackPersonHeight(QPointF pos) { - mTracker->resetTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(), - getPedestrianUserSelection()); + mTracker->resetTrackPersonHeight((Vec2F) pos, mAnimation->getCurrentFrameNum(), getPedestrianUserSelection()); updateControlWidget(); } // direction zeigt an, ob bis zum aktuellen (-1), ab dem aktuellen (1) oder ganzer trackpath (0) // loeschen von Trackpoints aller Trajektorien -void Petrack::deleteTrackPointAll(int direction) //const QPoint &pos +void Petrack::deleteTrackPointAll(int direction) // const QPoint &pos { mTracker->delPointAll(direction, mAnimation->getCurrentFrameNum()); updateControlWidget(); @@ -3570,29 +3819,31 @@ void Petrack::updateSourceInOutFrames() // delta gibt menge an Umdrehungen und richtung an void Petrack::skipToFrameWheel(int delta) { - mPlayerWidget->skipToFrame(mPlayerWidget->getPos()+delta); + mPlayerWidget->skipToFrame(mPlayerWidget->getPos() + delta); } -void Petrack::setPeTrackVersion(const std::string& petrackVersion) +void Petrack::setPeTrackVersion(const std::string &petrackVersion) { mPetrackVersion = QString::fromStdString(petrackVersion); } void Petrack::setGitInformation( - const std::string& gitCommitID, - const std::string& gitCommitDate, - const std::string& gitCommitBranch) + const std::string &gitCommitID, + const std::string &gitCommitDate, + const std::string &gitCommitBranch) { - mGitCommitID= QString::fromStdString(gitCommitID); - mGitCommitDate = QString::fromStdString(gitCommitDate); + mGitCommitID = QString::fromStdString(gitCommitID); + mGitCommitDate = QString::fromStdString(gitCommitDate); mGitCommitBranch = QString::fromStdString(gitCommitBranch); } -void Petrack::setCompileInformation(const std::string &compileTimeStamp, const std::string &compilerID, - const std::string &compilerVersion) +void Petrack::setCompileInformation( + const std::string &compileTimeStamp, + const std::string &compilerID, + const std::string &compilerVersion) { - mCompileDate = QString::fromStdString(compileTimeStamp); - mCompilerID = QString::fromStdString(compilerID); + mCompileDate = QString::fromStdString(compileTimeStamp); + mCompilerID = QString::fromStdString(compilerID); mCompilerVersion = QString::fromStdString(compilerVersion); } diff --git a/src/player.cpp b/src/player.cpp index d97c6badf2376b24f9e4fd50394bd54afc1d9d68..716e026109387a633ea19724fd3e9a033e198136 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -18,82 +18,83 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include "player.h" + +#include "animation.h" +#include "control.h" +#include "pMessageBox.h" +#include "petrack.h" + #include <QApplication> -#include <QToolButton> -#include <QVBoxLayout> +#include <QIntValidator> +#include <QLabel> +#include <QLineEdit> #include <QPixmap> #include <QSlider> #include <QStyle> -#include <QLineEdit> -#include <QLabel> -#include <QIntValidator> +#include <QToolButton> +#include <QVBoxLayout> #include <QtConcurrent> -#include "player.h" -#include "animation.h" -#include "petrack.h" -#include "control.h" -#include "pMessageBox.h" - Player::Player(Animation *anim, QWidget *parent) : QWidget(parent) { - int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize); + int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize); QSize iconSize(size, size); - //play forward Button + // play forward Button mPlayForwardButton = new QToolButton; mPlayForwardButton->setIcon(QPixmap(":/playF")); mPlayForwardButton->setIconSize(iconSize); - connect(mPlayForwardButton, &QToolButton::clicked,this, [&](){this->play(PlayerState::FORWARD);}); + connect(mPlayForwardButton, &QToolButton::clicked, this, [&]() { this->play(PlayerState::FORWARD); }); - //play backward Button + // play backward Button mPlayBackwardButton = new QToolButton; mPlayBackwardButton->setIcon(QPixmap(":/playB")); mPlayBackwardButton->setIconSize(iconSize); - connect(mPlayBackwardButton, &QToolButton::clicked, this, [&](){this->play(PlayerState::BACKWARD);}); + connect(mPlayBackwardButton, &QToolButton::clicked, this, [&]() { this->play(PlayerState::BACKWARD); }); - //frame forward Button + // frame forward Button mFrameForwardButton = new QToolButton; mFrameForwardButton->setAutoRepeat(true); - mFrameForwardButton->setAutoRepeatDelay(400); // before repetition starts - mFrameForwardButton->setAutoRepeatInterval(1000./DEFAULT_FPS); // war: 40 // for 1000 ms / 25 fps + mFrameForwardButton->setAutoRepeatDelay(400); // before repetition starts + mFrameForwardButton->setAutoRepeatInterval(1000. / DEFAULT_FPS); // war: 40 // for 1000 ms / 25 fps mFrameForwardButton->setIcon(QPixmap(":/skipF")); mFrameForwardButton->setIconSize(iconSize); - connect(mFrameForwardButton,SIGNAL(clicked()),this,SLOT(frameForward())); + connect(mFrameForwardButton, SIGNAL(clicked()), this, SLOT(frameForward())); - //frame backward Button + // frame backward Button mFrameBackwardButton = new QToolButton; mFrameBackwardButton->setAutoRepeat(true); - mFrameBackwardButton->setAutoRepeatDelay(400); // before repetition starts - mFrameBackwardButton->setAutoRepeatInterval(1000./DEFAULT_FPS); // war: 40 // for 1000 ms / 25 fps + mFrameBackwardButton->setAutoRepeatDelay(400); // before repetition starts + mFrameBackwardButton->setAutoRepeatInterval(1000. / DEFAULT_FPS); // war: 40 // for 1000 ms / 25 fps mFrameBackwardButton->setIcon(QPixmap(":/skipB")); mFrameBackwardButton->setIconSize(iconSize); - connect(mFrameBackwardButton,SIGNAL(clicked()),this,SLOT(frameBackward())); + connect(mFrameBackwardButton, SIGNAL(clicked()), this, SLOT(frameBackward())); - //pause button; + // pause button; mPauseButton = new QToolButton; mPauseButton->setIcon(QPixmap(":/pause")); mPauseButton->setIconSize(iconSize); - connect(mPauseButton,SIGNAL(clicked()),this,SLOT(pause())); + connect(mPauseButton, SIGNAL(clicked()), this, SLOT(pause())); - //rec button; + // rec button; mRecButton = new QToolButton; mRecButton->setIcon(QPixmap(":/record")); mRecButton->setIconSize(iconSize); - connect(mRecButton,SIGNAL(clicked()),this,SLOT(recStream())); + connect(mRecButton, SIGNAL(clicked()), this, SLOT(recStream())); mRec = false; - //slider + // slider mSlider = new QSlider(Qt::Horizontal); mSlider->setTickPosition(QSlider::TicksAbove); mSlider->setMinimumWidth(100); - connect(mSlider,SIGNAL(valueChanged(int)),this,SLOT(skipToFrame(int))); + connect(mSlider, SIGNAL(valueChanged(int)), this, SLOT(skipToFrame(int))); - //frame number - QFont f("Courier", 12, QFont::Bold); //Times Helvetica, Normal - mFrameNumValidator = new QIntValidator(0, 999999, this); - mFrameInNumValidator = new QIntValidator(0, 999999, this); + // frame number + QFont f("Courier", 12, QFont::Bold); // Times Helvetica, Normal + mFrameNumValidator = new QIntValidator(0, 999999, this); + mFrameInNumValidator = new QIntValidator(0, 999999, this); mFrameOutNumValidator = new QIntValidator(0, 999999, this); mFrameInNum = new QLineEdit(""); @@ -102,7 +103,7 @@ Player::Player(Animation *anim, QWidget *parent) : QWidget(parent) mFrameInNum->setAlignment(Qt::AlignRight); mFrameInNum->setValidator(mFrameInNumValidator); mFrameInNum->setFont(f); - connect(mFrameInNum,SIGNAL(editingFinished()),this,SLOT(update())); + connect(mFrameInNum, SIGNAL(editingFinished()), this, SLOT(update())); mFrameOutNum = new QLineEdit(""); mFrameOutNum->setMaxLength(8); @@ -110,27 +111,27 @@ Player::Player(Animation *anim, QWidget *parent) : QWidget(parent) mFrameOutNum->setAlignment(Qt::AlignRight); mFrameOutNum->setValidator(mFrameOutNumValidator); mFrameOutNum->setFont(f); - connect(mFrameOutNum,SIGNAL(editingFinished()),this,SLOT(update())); + connect(mFrameOutNum, SIGNAL(editingFinished()), this, SLOT(update())); mFrameNum = new QLineEdit("0"); - mFrameNum->setMaxLength(8); // bedeutet maxminal 1,1 stunden - mFrameNum->setMaximumWidth(75); //5*sz.width() //62 + mFrameNum->setMaxLength(8); // bedeutet maxminal 1,1 stunden + mFrameNum->setMaximumWidth(75); // 5*sz.width() //62 mFrameNum->setAlignment(Qt::AlignRight); mFrameNum->setValidator(mFrameNumValidator); mFrameNum->setFont(f); - connect(mFrameNum,SIGNAL(editingFinished()),this,SLOT(skipToFrame())); + connect(mFrameNum, SIGNAL(editingFinished()), this, SLOT(skipToFrame())); - //frame number + // frame number mFpsNum = new QLineEdit(QString::number(DEFAULT_FPS)); - mFpsNum->setMaxLength(8); // bedeutet maxminal 999,99 - mFpsNum->setMaximumWidth(62); //5*sz.width() + mFpsNum->setMaxLength(8); // bedeutet maxminal 999,99 + mFpsNum->setMaximumWidth(62); // 5*sz.width() mFpsNum->setAlignment(Qt::AlignRight); mFpsNumValidator = new QDoubleValidator(0.0, 999.99, 2, this); mFpsNum->setValidator(mFpsNumValidator); mFpsNum->setFont(f); - connect(mFpsNum,SIGNAL(editingFinished()),this,SLOT(setFPS())); + connect(mFpsNum, SIGNAL(editingFinished()), this, SLOT(setFPS())); - QFont f2("Courier", 12, QFont::Normal); //Times Helvetica, Normal + QFont f2("Courier", 12, QFont::Normal); // Times Helvetica, Normal mAtLabel = new QLabel("@"); mAtLabel->setFont(f2); @@ -145,7 +146,7 @@ Player::Player(Animation *anim, QWidget *parent) : QWidget(parent) // default value mPlayerSpeedLimited = false; - //player layout + // player layout mPlayerLayout = new QHBoxLayout(); mPlayerLayout->addWidget(mPlayBackwardButton); mPlayerLayout->addWidget(mFrameBackwardButton); @@ -164,24 +165,22 @@ Player::Player(Animation *anim, QWidget *parent) : QWidget(parent) mPlayerLayout->addWidget(mFpsLabel); mPlayerLayout->setMargin(0); - mMainWindow = (class Petrack*) parent; + mMainWindow = (class Petrack *) parent; setLayout(mPlayerLayout); setAnim(anim); - } void Player::setFPS(double fps) // default: double fps=-1. { - if (fps != -1) + if(fps != -1) { mFpsNum->setText(QString::number(fps)); - mFrameForwardButton->setAutoRepeatInterval(1000./fps); // for 1000 ms / 25 fps - mFrameBackwardButton->setAutoRepeatInterval(1000./fps); // for 1000 ms / 25 fps + mFrameForwardButton->setAutoRepeatInterval(1000. / fps); // for 1000 ms / 25 fps + mFrameBackwardButton->setAutoRepeatInterval(1000. / fps); // for 1000 ms / 25 fps } mAnimation->setFPS(mFpsNum->text().toDouble()); - } void Player::setPlayerSpeedLimited(bool fixed) { @@ -209,16 +208,16 @@ void Player::setLooping(bool looping) void Player::setSpeedRelativeToRealtime(double factor) { - setFPS(mAnimation->getOriginalFPS()*factor); + setFPS(mAnimation->getOriginalFPS() * factor); } void Player::setAnim(Animation *anim) { - if (anim) + if(anim) { pause(); mAnimation = anim; - int max = anim->getNumFrames()>1 ? anim->getNumFrames()-1 : 0; + int max = anim->getNumFrames() > 1 ? anim->getNumFrames() - 1 : 0; setSliderMax(max); mFrameNumValidator->setTop(max); mFrameInNumValidator->setTop(anim->getSourceOutFrameNum()); @@ -246,7 +245,7 @@ void Player::setSliderMax(int max) */ bool Player::updateImage() { - if (mImg.empty()) + if(mImg.empty()) { pause(); return false; @@ -254,22 +253,23 @@ bool Player::updateImage() qApp->processEvents(); #ifdef TIME_MEASUREMENT double time1 = 0.0, tstart; - tstart = clock(); + tstart = clock(); #endif - QFuture<void> future = QtConcurrent::run([&]() {mMainWindow->updateImage(mImg); }); + QFuture<void> future = QtConcurrent::run([&]() { mMainWindow->updateImage(mImg); }); future.waitForFinished(); - if (mRec) + if(mRec) { - mAviFile.appendFrame((const unsigned char*) mImg.data, true); + mAviFile.appendFrame((const unsigned char *) mImg.data, true); } #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(update image) = " << time1 << " sec." << endl; #endif - mSlider->setValue(mAnimation->getCurrentFrameNum()); //(1000*mAnimation->getCurrentFrameNum())/mAnimation->getNumFrames()); + mSlider->setValue( + mAnimation->getCurrentFrameNum()); //(1000*mAnimation->getCurrentFrameNum())/mAnimation->getNumFrames()); mFrameNum->setText(QString().number(mAnimation->getCurrentFrameNum())); return true; @@ -280,23 +280,23 @@ bool Player::forward() qApp->processEvents(); #ifdef TIME_MEASUREMENT double time1 = 0.0, tstart; - tstart = clock(); + tstart = clock(); #endif bool should_be_last_frame = mAnimation->getCurrentFrameNum() == mAnimation->getSourceOutFrameNum(); mImg = mAnimation->getNextFrame(); // check if animation is broken somewhere in the video - if (mImg.empty()) + if(mImg.empty()) { - if (!should_be_last_frame) + if(!should_be_last_frame) { debout << "Warning: video unexpected finished." << std::endl; } } #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(load frame) = " << time1 << " sec." << endl; #endif return updateImage(); @@ -307,12 +307,12 @@ bool Player::backward() qApp->processEvents(); #ifdef TIME_MEASUREMENT double time1 = 0.0, tstart; - tstart = clock(); + tstart = clock(); #endif mImg = mAnimation->getPreviousFrame(); #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(load frame) = " << time1 << " sec." << endl; #endif return updateImage(); @@ -325,11 +325,15 @@ bool Player::backward() * @see PlayerState * @param state */ -void Player::play(PlayerState state){ - if(mState == PlayerState::PAUSE){ +void Player::play(PlayerState state) +{ + if(mState == PlayerState::PAUSE) + { mState = state; playVideo(); - }else{ + } + else + { mState = state; } } @@ -344,67 +348,88 @@ void Player::play(PlayerState state){ * The method is left, when the video is paused and reentered, when playing * gets started again. */ -void Player::playVideo(){ +void Player::playVideo() +{ static QElapsedTimer timer; - int currentFrame = mAnimation->getCurrentFrameNum(); - long long int overtime = 0; + int currentFrame = mAnimation->getCurrentFrameNum(); + long long int overtime = 0; - while(mState != PlayerState::PAUSE){ + while(mState != PlayerState::PAUSE) + { // slow down the player speed for extrem fast video sequences (Jiayue China or 16fps cam99 basigo grid video) - if (mPlayerSpeedLimited || mPlayerSpeedFixed) + if(mPlayerSpeedLimited || mPlayerSpeedFixed) { - auto supposedDiff = static_cast<long long int>(1'000/mAnimation->getFPS()); + auto supposedDiff = static_cast<long long int>(1'000 / mAnimation->getFPS()); - if(timer.isValid()){ - if(mPlayerSpeedFixed && mState == PlayerState::FORWARD){ + if(timer.isValid()) + { + if(mPlayerSpeedFixed && mState == PlayerState::FORWARD) + { overtime = std::max(0LL, overtime + (timer.elapsed() - supposedDiff)); - if(overtime >= supposedDiff){ + if(overtime >= supposedDiff) + { mAnimation->skipFrame(static_cast<int>(overtime / supposedDiff)); overtime = overtime % supposedDiff; - currentFrame = std::min(mAnimation->getCurrentFrameNum() + 1, mAnimation->getSourceOutFrameNum()); + currentFrame = + std::min(mAnimation->getCurrentFrameNum() + 1, mAnimation->getSourceOutFrameNum()); } } - while(!timer.hasExpired(supposedDiff)){ + while(!timer.hasExpired(supposedDiff)) + { qApp->processEvents(); } } timer.start(); - }else{ + } + else + { timer.invalidate(); } - switch(mState){ - case PlayerState::FORWARD: - mImg = mAnimation->getFrameAtIndex(currentFrame); - currentFrame++; - break; - case PlayerState::BACKWARD: - mImg = mAnimation->getFrameAtIndex(currentFrame); - currentFrame--; - break; - case PlayerState::PAUSE: - break; + switch(mState) + { + case PlayerState::FORWARD: + mImg = mAnimation->getFrameAtIndex(currentFrame); + currentFrame++; + break; + case PlayerState::BACKWARD: + mImg = mAnimation->getFrameAtIndex(currentFrame); + currentFrame--; + break; + case PlayerState::PAUSE: + break; } - if(!updateImage()){ + if(!updateImage()) + { mState = PlayerState::PAUSE; - if( mAnimation->getCurrentFrameNum() != 0 && mAnimation->getCurrentFrameNum() != mAnimation->getSourceOutFrameNum()){ + if(mAnimation->getCurrentFrameNum() != 0 && + mAnimation->getCurrentFrameNum() != mAnimation->getSourceOutFrameNum()) + { debout << "Warning: video unexpectedly finished." << std::endl; } - }else{ - if( mLooping && mMainWindow->getControlWidget()->trackOnlineCalc->checkState() == Qt::Checked) + } + else + { + if(mLooping && mMainWindow->getControlWidget()->trackOnlineCalc->checkState() == Qt::Checked) { - PWarning(this, "Error: No tracking while looping", "Looping and tracking are incompatible. Please disable one first."); + PWarning( + this, + "Error: No tracking while looping", + "Looping and tracking are incompatible. Please disable one first."); mState = PlayerState::PAUSE; break; - }else if(mLooping) + } + else if(mLooping) { - if(mState == PlayerState::FORWARD && mAnimation->getCurrentFrameNum() == mAnimation->getSourceOutFrameNum()) + if(mState == PlayerState::FORWARD && + mAnimation->getCurrentFrameNum() == mAnimation->getSourceOutFrameNum()) { currentFrame = 0; - }else if(mState == PlayerState::BACKWARD && mAnimation->getCurrentFrameNum() == 0) + } + else if(mState == PlayerState::BACKWARD && mAnimation->getCurrentFrameNum() == 0) { currentFrame = mAnimation->getSourceOutFrameNum(); } @@ -439,7 +464,7 @@ void Player::togglePlayPause() { static PlayerState lastState; - if (mState != PlayerState::PAUSE) + if(mState != PlayerState::PAUSE) { lastState = mState; pause(); @@ -460,12 +485,13 @@ void Player::togglePlayPause() */ void Player::recStream() { - if (mAnimation->isCameraLiveStream() || mAnimation->isVideo() || mAnimation->isImageSequence() || mAnimation->isStereoVideo()) + if(mAnimation->isCameraLiveStream() || mAnimation->isVideo() || mAnimation->isImageSequence() || + mAnimation->isStereoVideo()) { // video temp path/file name - QString videoTmp = QDir::tempPath()+"/petrack-video-record.avi"; + QString videoTmp = QDir::tempPath() + "/petrack-video-record.avi"; - if (mRec) //stop recording and save recorded stream to disk + if(mRec) // stop recording and save recorded stream to disk { mRec = false; mRecButton->setIcon(QPixmap(":/record")); @@ -474,24 +500,25 @@ void Player::recStream() QString dest; - QFileDialog fileDialog(this, - tr("Select file for saving video output"), - nullptr, - tr("Video (*.*);;AVI-File (*.avi);;All supported types (*.avi *.mp4);;All files (*.*)")); + QFileDialog fileDialog( + this, + tr("Select file for saving video output"), + nullptr, + tr("Video (*.*);;AVI-File (*.avi);;All supported types (*.avi *.mp4);;All files (*.*)")); fileDialog.setAcceptMode(QFileDialog::AcceptSave); fileDialog.setFileMode(QFileDialog::AnyFile); fileDialog.setDefaultSuffix(""); - if( fileDialog.exec() ) + if(fileDialog.exec()) dest = fileDialog.selectedFiles().at(0); - if (dest == nullptr) + if(dest == nullptr) return; - if (QFile::exists(dest)) + if(QFile::exists(dest)) QFile::remove(dest); - QProgressDialog progress("Save Video File",nullptr,0,2,mMainWindow); + QProgressDialog progress("Save Video File", nullptr, 0, 2, mMainWindow); progress.setWindowTitle("Save Video File"); progress.setWindowModality(Qt::WindowModal); progress.setVisible(true); @@ -502,26 +529,28 @@ void Player::recStream() qApp->processEvents(); progress.setValue(1); - if (!QFile(videoTmp).copy(dest)) + if(!QFile(videoTmp).copy(dest)) { - PCritical(this, tr("PeTrack"), - tr("Error: Could not save video file!")); - }else + PCritical(this, tr("PeTrack"), tr("Error: Could not save video file!")); + } + else { mMainWindow->statusBar()->showMessage(tr("Saved video file to %1.").arg(dest), 5000); - if (!QFile(videoTmp).remove()) - debout << "Could not remove tmp-file: " << videoTmp << std::endl; + if(!QFile(videoTmp).remove()) + debout << "Could not remove tmp-file: " << videoTmp << std::endl; progress.setValue(2); } - - }else // open video writer + } + else // open video writer { - if (mAviFile.open(videoTmp.toStdString().c_str(), mImg.cols, mImg.rows, 8*mImg.channels(), mAnimation->getFPS())) + if(mAviFile.open( + videoTmp.toStdString().c_str(), mImg.cols, mImg.rows, 8 * mImg.channels(), mAnimation->getFPS())) { mRec = true; mRecButton->setIcon(QPixmap(":/stop-record")); - }else + } + else { debout << "error: could not open video output file!" << std::endl; } @@ -531,7 +560,7 @@ void Player::recStream() bool Player::skipToFrame(int f) // [0..mAnimation->getNumFrames()-1] { - if (f == mAnimation->getCurrentFrameNum()) + if(f == mAnimation->getCurrentFrameNum()) { return false; } @@ -542,10 +571,10 @@ bool Player::skipToFrame(int f) // [0..mAnimation->getNumFrames()-1] bool Player::skipToFrame() // [0..mAnimation->getNumFrames()-1] { - if (mFrameNum->text().toInt() < getFrameInNum()) - mFrameNum->setText(QString::number(getFrameInNum())); - if (mFrameNum->text().toInt() > getFrameOutNum()) - mFrameNum->setText(QString::number(getFrameOutNum())); + if(mFrameNum->text().toInt() < getFrameInNum()) + mFrameNum->setText(QString::number(getFrameInNum())); + if(mFrameNum->text().toInt() > getFrameOutNum()) + mFrameNum->setText(QString::number(getFrameOutNum())); return skipToFrame(mFrameNum->text().toInt()); } @@ -555,15 +584,14 @@ bool Player::skipToFrame() // [0..mAnimation->getNumFrames()-1] */ void Player::update() { - if constexpr (true || !mMainWindow->isLoading()) + if constexpr(true || !mMainWindow->isLoading()) { - - if( mFrameNum->text().toInt() < mFrameInNum->text().toInt() ) + if(mFrameNum->text().toInt() < mFrameInNum->text().toInt()) { mFrameNum->setText(mFrameInNum->text()); skipToFrame(mFrameNum->text().toInt()); } - if( mFrameNum->text().toInt() > mFrameOutNum->text().toInt() ) + if(mFrameNum->text().toInt() > mFrameOutNum->text().toInt()) { mFrameNum->setText(mFrameOutNum->text()); skipToFrame(mFrameNum->text().toInt()); @@ -571,7 +599,7 @@ void Player::update() mSlider->setMinimum(getFrameInNum()); mSlider->setMaximum(getFrameOutNum()); - mFrameInNumValidator->setTop(getFrameOutNum()-1); + mFrameInNumValidator->setTop(getFrameOutNum() - 1); mFrameNumValidator->setBottom(getFrameInNum()); mFrameNumValidator->setTop(getFrameOutNum()); @@ -584,38 +612,38 @@ void Player::update() int Player::getFrameInNum() { - if (mFrameInNum->text() == "") + if(mFrameInNum->text() == "") return -1; return mFrameInNum->text().toInt(); } void Player::setFrameInNum(int in) { - if (in == -1) + if(in == -1) in = 0; mFrameInNum->setText(QString::number(in)); - mFrameInNumValidator->setTop(getFrameOutNum()-1); + mFrameInNumValidator->setTop(getFrameOutNum() - 1); mFrameNumValidator->setBottom(getFrameInNum()); mFrameNumValidator->setTop(getFrameOutNum()); } int Player::getFrameOutNum() { - if (mFrameOutNum->text() == "") + if(mFrameOutNum->text() == "") return -1; return mFrameOutNum->text().toInt(); } void Player::setFrameOutNum(int out) { - if (out == -1) - out = mAnimation->getMaxFrames()-1; + if(out == -1) + out = mAnimation->getMaxFrames() - 1; mFrameOutNum->setText(QString::number(out)); - mFrameInNumValidator->setTop(/*out*/getFrameOutNum()-1); + mFrameInNumValidator->setTop(/*out*/ getFrameOutNum() - 1); mFrameNumValidator->setBottom(getFrameInNum()); - mFrameNumValidator->setTop(/*out*/getFrameOutNum()); + mFrameNumValidator->setTop(/*out*/ getFrameOutNum()); } int Player::getPos() diff --git a/src/qtColorTriangle.cpp b/src/qtColorTriangle.cpp index 7d6a71b315cfd9d709aa60de3e836da27c53e623..3e3f26c9f57bd16af05988dd1637ecde0e482a97 100644 --- a/src/qtColorTriangle.cpp +++ b/src/qtColorTriangle.cpp @@ -52,18 +52,17 @@ #include <QtCore/QMap> #include <QtCore/QVarLengthArray> #include <QtGui/QConicalGradient> -#include <QtWidgets/QFrame> #include <QtGui/QImage> #include <QtGui/QKeyEvent> -#include <QtWidgets/QLayout> #include <QtGui/QMouseEvent> #include <QtGui/QPainter> #include <QtGui/QPainterPath> #include <QtGui/QPixmap> #include <QtGui/QResizeEvent> +#include <QtWidgets/QFrame> +#include <QtWidgets/QLayout> #include <QtWidgets/QToolTip> #include <QtWidgets/QVBoxLayout> - #include <math.h> #define PENDIV 20. @@ -92,8 +91,8 @@ with the new \a color. */ -const double PI = 3.14159265358979323846264338327950288419717; -const double TWOPI = 2.0*PI; +const double PI = 3.14159265358979323846264338327950288419717; +const double TWOPI = 2.0 * PI; /* Used to store color values in the range 0..255 as doubles. @@ -110,14 +109,16 @@ struct DoubleColor /* Used to store pairs of DoubleColor and DoublePoint in one structure. */ -struct Vertex { +struct Vertex +{ DoubleColor color; - QPointF point; + QPointF point; Vertex(const DoubleColor &c, const QPointF &p) : color(c), point(p) {} - Vertex(const QColor &c, const QPointF &p) - : color(DoubleColor((double) c.red(), (double) c.green(), - (double) c.blue())), point(p) {} + Vertex(const QColor &c, const QPointF &p) : + color(DoubleColor((double) c.red(), (double) c.green(), (double) c.blue())), point(p) + { + } }; /*! \internal @@ -127,15 +128,14 @@ Swaps the Vertex at *a with the one at *b. static void swap(Vertex **a, Vertex **b) { Vertex *tmp = *a; - *a = *b; - *b = tmp; + *a = *b; + *b = tmp; } /*! Constructs a color triangle widget with the given \a parent. */ -QtColorTriangle::QtColorTriangle(QWidget *parent) - : QWidget(parent), bg(sizeHint(), QImage::Format_RGB32), selMode(Idle) +QtColorTriangle::QtColorTriangle(QWidget *parent) : QWidget(parent), bg(sizeHint(), QImage::Format_RGB32), selMode(Idle) { setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); setFocusPolicy(Qt::StrongFocus); @@ -150,9 +150,7 @@ QtColorTriangle::QtColorTriangle(QWidget *parent) /*! Destructs the color triangle. */ -QtColorTriangle::~QtColorTriangle() -{ -} +QtColorTriangle::~QtColorTriangle() {} /*! \internal @@ -162,23 +160,23 @@ QtColorTriangle::~QtColorTriangle() void QtColorTriangle::polish() { outerRadius = (contentsRect().width() - 1) / 2; - if ((contentsRect().height() - 1) / 2 < outerRadius) - outerRadius = (contentsRect().height() - 1) / 2; + if((contentsRect().height() - 1) / 2 < outerRadius) + outerRadius = (contentsRect().height() - 1) / 2; - penWidth = (int) floor(outerRadius / PENDIV); //50.0); MB + penWidth = (int) floor(outerRadius / PENDIV); // 50.0); MB ellipseSize = (int) floor(outerRadius / ELLDIV); // 12.5); MB double cx = (double) contentsRect().center().x(); double cy = (double) contentsRect().center().y(); - pa = QPointF(cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); - pb = QPointF(cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); - pc = QPointF(cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); - pd = QPointF(cx + (cos(a) * (outerRadius - (outerRadius / 10.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 10.0)))); + pa = QPointF( + cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); + pb = QPointF( + cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); + pc = QPointF( + cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); + pd = QPointF( + cx + (cos(a) * (outerRadius - (outerRadius / 10.0))), cy - (sin(a) * (outerRadius - (outerRadius / 10.0)))); // Find the current position of the selector / 12.5); @@ -221,8 +219,9 @@ void QtColorTriangle::genBackground() p.fillRect(bg.rect(), palette().mid()); QConicalGradient gradient(bg.rect().center(), 90); - QColor color; - for (double i = 0; i <= 1.0; i += 0.1) { + QColor color; + for(double i = 0; i <= 1.0; i += 0.1) + { #if QT_VERSION < 0x040100 color.setHsv(int(i * 360.0), 255, 255); #else @@ -231,10 +230,16 @@ void QtColorTriangle::genBackground() gradient.setColorAt(i, color); } - QRectF innerRadiusRect(bg.rect().center().x() - innerRadius, bg.rect().center().y() - innerRadius, - innerRadius * 2 + 1, innerRadius * 2 + 1); - QRectF outerRadiusRect(bg.rect().center().x() - outerRadius, bg.rect().center().y() - outerRadius, - outerRadius * 2 + 1, outerRadius * 2 + 1); + QRectF innerRadiusRect( + bg.rect().center().x() - innerRadius, + bg.rect().center().y() - innerRadius, + innerRadius * 2 + 1, + innerRadius * 2 + 1); + QRectF outerRadiusRect( + bg.rect().center().x() - outerRadius, + bg.rect().center().y() - outerRadius, + outerRadius * 2 + 1, + outerRadius * 2 + 1); QPainterPath path; path.addEllipse(innerRadiusRect); path.addEllipse(outerRadiusRect); @@ -245,14 +250,15 @@ void QtColorTriangle::genBackground() p.restore(); double penThickness = bg.width() / 400.0; - for (int f = 0; f <= 5760; f += 20) { + for(int f = 0; f <= 5760; f += 20) + { int value = int((0.5 + cos(((f - 1800) / 5760.0) * TWOPI) / 2) * 255.0); - color.setHsv(int((f / 5760.0) * 360.0), 128 + (255 - value)/2, 255 - (255 - value)/4); + color.setHsv(int((f / 5760.0) * 360.0), 128 + (255 - value) / 2, 255 - (255 - value) / 4); p.setPen(QPen(color, penThickness)); p.drawArc(innerRadiusRect, 1440 - f, 20); - - color.setHsv(int((f / 5760.0) * 360.0), 128 + value/2, 255 - value/4); + + color.setHsv(int((f / 5760.0) * 360.0), 128 + value / 2, 255 - value / 4); p.setPen(QPen(color, penThickness)); p.drawArc(outerRadiusRect, 2880 - 1440 - f, 20); } @@ -267,73 +273,84 @@ void QtColorTriangle::genBackground() */ void QtColorTriangle::mouseMoveEvent(QMouseEvent *e) { - if ((e->buttons() & Qt::LeftButton) == 0) + if((e->buttons() & Qt::LeftButton) == 0) return; QPointF depos((double) e->pos().x(), (double) e->pos().y()); - bool newColor = false; - - if (selMode == SelectingHue) { - // If selecting hue, find the new angles for the points a,b,c - // of the triangle. The following update() will then redraw - // the triangle. - a = angleAt(depos, contentsRect()); - b = a + TWOPI / 3.0; - c = b + TWOPI / 3.0; - if (b > TWOPI) b -= TWOPI; - if (c > TWOPI) c -= TWOPI; - - double am = a - PI/2; - if (am < 0) am += TWOPI; - - curHue = 360 - (int) (((am) * 360.0) / TWOPI); - int h,s,v; - curColor.getHsv(&h, &s, &v); - - if (curHue != h) { - newColor = true; - curColor.setHsv(curHue, s, v); - } - - double cx = (double) contentsRect().center().x(); - double cy = (double) contentsRect().center().y(); - - pa = QPointF(cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); - pb = QPointF(cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); - pc = QPointF(cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); - pd = QPointF(cx + (cos(a) * (outerRadius - (outerRadius / 10.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 10.0)))); - - selectorPos = pointFromColor(curColor); - } else { - Vertex aa(Qt::black, pa); - Vertex bb(Qt::black, pb); - Vertex cc(Qt::black, pc); - - Vertex *p1 = &aa; - Vertex *p2 = &bb; - Vertex *p3 = &cc; - if (p1->point.y() > p2->point.y()) swap(&p1, &p2); - if (p1->point.y() > p3->point.y()) swap(&p1, &p3); - if (p2->point.y() > p3->point.y()) swap(&p2, &p3); - - selectorPos = movePointToTriangle(depos.x(), depos.y(), aa, bb, cc); - QColor col = colorFromPoint(selectorPos); - if (col != curColor) { - // Ensure that hue does not change when selecting - // saturation and value. - int h,s,v; - col.getHsv(&h, &s, &v); - curColor.setHsv(curHue, s, v); - newColor = true; - } + bool newColor = false; + + if(selMode == SelectingHue) + { + // If selecting hue, find the new angles for the points a,b,c + // of the triangle. The following update() will then redraw + // the triangle. + a = angleAt(depos, contentsRect()); + b = a + TWOPI / 3.0; + c = b + TWOPI / 3.0; + if(b > TWOPI) + b -= TWOPI; + if(c > TWOPI) + c -= TWOPI; + + double am = a - PI / 2; + if(am < 0) + am += TWOPI; + + curHue = 360 - (int) (((am) *360.0) / TWOPI); + int h, s, v; + curColor.getHsv(&h, &s, &v); + + if(curHue != h) + { + newColor = true; + curColor.setHsv(curHue, s, v); + } + + double cx = (double) contentsRect().center().x(); + double cy = (double) contentsRect().center().y(); + + pa = QPointF( + cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); + pb = QPointF( + cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); + pc = QPointF( + cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); + pd = QPointF( + cx + (cos(a) * (outerRadius - (outerRadius / 10.0))), cy - (sin(a) * (outerRadius - (outerRadius / 10.0)))); + + selectorPos = pointFromColor(curColor); + } + else + { + Vertex aa(Qt::black, pa); + Vertex bb(Qt::black, pb); + Vertex cc(Qt::black, pc); + + Vertex *p1 = &aa; + Vertex *p2 = &bb; + Vertex *p3 = &cc; + if(p1->point.y() > p2->point.y()) + swap(&p1, &p2); + if(p1->point.y() > p3->point.y()) + swap(&p1, &p3); + if(p2->point.y() > p3->point.y()) + swap(&p2, &p3); + + selectorPos = movePointToTriangle(depos.x(), depos.y(), aa, bb, cc); + QColor col = colorFromPoint(selectorPos); + if(col != curColor) + { + // Ensure that hue does not change when selecting + // saturation and value. + int h, s, v; + col.getHsv(&h, &s, &v); + curColor.setHsv(curHue, s, v); + newColor = true; + } } - if (newColor) - emit colorChanged(curColor); + if(newColor) + emit colorChanged(curColor); update(); } @@ -349,74 +366,85 @@ void QtColorTriangle::mouseMoveEvent(QMouseEvent *e) void QtColorTriangle::mousePressEvent(QMouseEvent *e) { // Only respond to the left mouse button. - if (e->button() != Qt::LeftButton) - return; + if(e->button() != Qt::LeftButton) + return; QPointF depos((double) e->pos().x(), (double) e->pos().y()); - double rad = radiusAt(depos, contentsRect()); - bool newColor = false; + double rad = radiusAt(depos, contentsRect()); + bool newColor = false; // As in mouseMoveEvent, either find the a,b,c angles or the // radian position of the selector, then order an update. - if (rad > (outerRadius - (outerRadius / 5))) { - selMode = SelectingHue; - - a = angleAt(depos, contentsRect()); - b = a + TWOPI / 3.0; - c = b + TWOPI / 3.0; - if (b > TWOPI) b -= TWOPI; - if (c > TWOPI) c -= TWOPI; - - double am = a - PI/2; - if (am < 0) am += TWOPI; - - curHue = 360 - (int) ((am * 360.0) / TWOPI); - int h,s,v; - curColor.getHsv(&h, &s, &v); - - if (h != curHue) { - newColor = true; - curColor.setHsv(curHue, s, v); - } - - double cx = (double) contentsRect().center().x(); - double cy = (double) contentsRect().center().y(); - - pa = QPointF(cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); - pb = QPointF(cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); - pc = QPointF(cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); - pd = QPointF(cx + (cos(a) * (outerRadius - (outerRadius / 10.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 10.0)))); - - selectorPos = pointFromColor(curColor); - emit colorChanged(curColor); - } else { - selMode = SelectingSatValue; - - Vertex aa(Qt::black, pa); - Vertex bb(Qt::black, pb); - Vertex cc(Qt::black, pc); - - Vertex *p1 = &aa; - Vertex *p2 = &bb; - Vertex *p3 = &cc; - if (p1->point.y() > p2->point.y()) swap(&p1, &p2); - if (p1->point.y() > p3->point.y()) swap(&p1, &p3); - if (p2->point.y() > p3->point.y()) swap(&p2, &p3); - - selectorPos = movePointToTriangle(depos.x(), depos.y(), aa, bb, cc); - QColor col = colorFromPoint(selectorPos); - if (col != curColor) { - curColor = col; - newColor = true; - } + if(rad > (outerRadius - (outerRadius / 5))) + { + selMode = SelectingHue; + + a = angleAt(depos, contentsRect()); + b = a + TWOPI / 3.0; + c = b + TWOPI / 3.0; + if(b > TWOPI) + b -= TWOPI; + if(c > TWOPI) + c -= TWOPI; + + double am = a - PI / 2; + if(am < 0) + am += TWOPI; + + curHue = 360 - (int) ((am * 360.0) / TWOPI); + int h, s, v; + curColor.getHsv(&h, &s, &v); + + if(h != curHue) + { + newColor = true; + curColor.setHsv(curHue, s, v); + } + + double cx = (double) contentsRect().center().x(); + double cy = (double) contentsRect().center().y(); + + pa = QPointF( + cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); + pb = QPointF( + cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); + pc = QPointF( + cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); + pd = QPointF( + cx + (cos(a) * (outerRadius - (outerRadius / 10.0))), cy - (sin(a) * (outerRadius - (outerRadius / 10.0)))); + + selectorPos = pointFromColor(curColor); + emit colorChanged(curColor); + } + else + { + selMode = SelectingSatValue; + + Vertex aa(Qt::black, pa); + Vertex bb(Qt::black, pb); + Vertex cc(Qt::black, pc); + + Vertex *p1 = &aa; + Vertex *p2 = &bb; + Vertex *p3 = &cc; + if(p1->point.y() > p2->point.y()) + swap(&p1, &p2); + if(p1->point.y() > p3->point.y()) + swap(&p1, &p3); + if(p2->point.y() > p3->point.y()) + swap(&p2, &p3); + + selectorPos = movePointToTriangle(depos.x(), depos.y(), aa, bb, cc); + QColor col = colorFromPoint(selectorPos); + if(col != curColor) + { + curColor = col; + newColor = true; + } } - if (newColor) - emit colorChanged(curColor); + if(newColor) + emit colorChanged(curColor); update(); } @@ -428,8 +456,8 @@ void QtColorTriangle::mousePressEvent(QMouseEvent *e) */ void QtColorTriangle::mouseReleaseEvent(QMouseEvent *e) { - if (e->button() == Qt::LeftButton) - selMode = Idle; + if(e->button() == Qt::LeftButton) + selMode = Idle; } /*! @@ -437,57 +465,78 @@ void QtColorTriangle::mouseReleaseEvent(QMouseEvent *e) */ void QtColorTriangle::keyPressEvent(QKeyEvent *e) { - switch (e->key()) { - case Qt::Key_Left: { - --curHue; - if (curHue < 0) curHue += 360; - int h,s,v; - curColor.getHsv(&h, &s, &v); - QColor tmp; - tmp.setHsv(curHue, s, v); - setColor(tmp); - } - break; - case Qt::Key_Right: { - ++curHue; - if (curHue > 359) curHue -= 360; - int h,s,v; - curColor.getHsv(&h, &s, &v); - QColor tmp; - tmp.setHsv(curHue, s, v); - setColor(tmp); - } - break; - case Qt::Key_Up: { - int h,s,v; - curColor.getHsv(&h, &s, &v); - QColor tmp; - if (e->modifiers() & Qt::ShiftModifier) { - if (s > 5) s -= 5; - else s = 0; - } else { - if (v > 5) v -= 5; - else v = 0; - } - tmp.setHsv(curHue, s, v); - setColor(tmp); - } - break; - case Qt::Key_Down: { - int h,s,v; - curColor.getHsv(&h, &s, &v); - QColor tmp; - if (e->modifiers() & Qt::ShiftModifier) { - if (s < 250) s += 5; - else s = 255; - } else { - if (v < 250) v += 5; - else v = 255; - } - tmp.setHsv(curHue, s, v); - setColor(tmp); - } - break; + switch(e->key()) + { + case Qt::Key_Left: + { + --curHue; + if(curHue < 0) + curHue += 360; + int h, s, v; + curColor.getHsv(&h, &s, &v); + QColor tmp; + tmp.setHsv(curHue, s, v); + setColor(tmp); + } + break; + case Qt::Key_Right: + { + ++curHue; + if(curHue > 359) + curHue -= 360; + int h, s, v; + curColor.getHsv(&h, &s, &v); + QColor tmp; + tmp.setHsv(curHue, s, v); + setColor(tmp); + } + break; + case Qt::Key_Up: + { + int h, s, v; + curColor.getHsv(&h, &s, &v); + QColor tmp; + if(e->modifiers() & Qt::ShiftModifier) + { + if(s > 5) + s -= 5; + else + s = 0; + } + else + { + if(v > 5) + v -= 5; + else + v = 0; + } + tmp.setHsv(curHue, s, v); + setColor(tmp); + } + break; + case Qt::Key_Down: + { + int h, s, v; + curColor.getHsv(&h, &s, &v); + QColor tmp; + if(e->modifiers() & Qt::ShiftModifier) + { + if(s < 250) + s += 5; + else + s = 255; + } + else + { + if(v < 250) + v += 5; + else + v = 255; + } + tmp.setHsv(curHue, s, v); + setColor(tmp); + } + break; }; } @@ -499,23 +548,23 @@ void QtColorTriangle::keyPressEvent(QKeyEvent *e) void QtColorTriangle::resizeEvent(QResizeEvent *) { outerRadius = (contentsRect().width() - 1) / 2; - if ((contentsRect().height() - 1) / 2 < outerRadius) - outerRadius = (contentsRect().height() - 1) / 2; + if((contentsRect().height() - 1) / 2 < outerRadius) + outerRadius = (contentsRect().height() - 1) / 2; - penWidth = (int) floor(outerRadius / PENDIV); //50.0); MB + penWidth = (int) floor(outerRadius / PENDIV); // 50.0); MB ellipseSize = (int) floor(outerRadius / ELLDIV); // 12.5); MB double cx = (double) contentsRect().center().x(); double cy = (double) contentsRect().center().y(); - pa = QPointF(cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); - pb = QPointF(cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); - pc = QPointF(cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); - pd = QPointF(cx + (cos(a) * (outerRadius - (outerRadius / 10.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 10.0)))); + pa = QPointF( + cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); + pb = QPointF( + cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); + pc = QPointF( + cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); + pd = QPointF( + cx + (cos(a) * (outerRadius - (outerRadius / 10.0))), cy - (sin(a) * (outerRadius - (outerRadius / 10.0)))); // Find the current position of the selector selectorPos = pointFromColor(curColor); @@ -533,11 +582,12 @@ First copies a background image of the hue donut and its void QtColorTriangle::paintEvent(QPaintEvent *e) { QPainter p(this); - if (e->rect().intersects(contentsRect())) + if(e->rect().intersects(contentsRect())) p.setClipRegion(e->region().intersected(contentsRect())); - if (mustGenerateBackground) { - genBackground(); - mustGenerateBackground = false; + if(mustGenerateBackground) + { + genBackground(); + mustGenerateBackground = false; } // Blit the static generated background with the hue gradient onto @@ -545,7 +595,7 @@ void QtColorTriangle::paintEvent(QPaintEvent *e) QImage buf = bg.copy(); // Draw the trigon - int h,s,v; + int h, s, v; curColor.getHsv(&h, &s, &v); // Find the color with only the hue, and max value and saturation @@ -556,7 +606,7 @@ void QtColorTriangle::paintEvent(QPaintEvent *e) drawTrigon(&buf, pa, pb, pc, hueColor); // Slow step: convert the image to a pixmap - QPixmap pix = QPixmap::fromImage(buf); + QPixmap pix = QPixmap::fromImage(buf); QPainter painter(&pix); painter.setRenderHint(QPainter::Antialiasing); @@ -566,34 +616,35 @@ void QtColorTriangle::paintEvent(QPaintEvent *e) painter.drawLine(pa, pb); painter.drawLine(pb, pc); painter.drawLine(pc, pa); - + int ri, gi, bi; hueColor.getRgb(&ri, &gi, &bi); - if ((ri * 30) + (gi * 59) + (bi * 11) > 12800) - painter.setPen(QPen(Qt::black, penWidth)); + if((ri * 30) + (gi * 59) + (bi * 11) > 12800) + painter.setPen(QPen(Qt::black, penWidth)); else { painter.setPen(QPen(Qt::white, penWidth)); - //painter.setBrush(QBrush(Qt::white)); MB hierueber waere ein gefuellter kreis realisierbar + // painter.setBrush(QBrush(Qt::white)); MB hierueber waere ein gefuellter kreis realisierbar } - painter.drawEllipse((int) (pd.x() - ellipseSize / 2.0), - (int) (pd.y() - ellipseSize / 2.0), - ellipseSize, ellipseSize); + painter.drawEllipse( + (int) (pd.x() - ellipseSize / 2.0), (int) (pd.y() - ellipseSize / 2.0), ellipseSize, ellipseSize); curColor.getRgb(&ri, &gi, &bi); // Find a color for painting the selector based on the brightness // value of the color. - if ((ri * 30) + (gi * 59) + (bi * 11) > 12800) - painter.setPen(QPen(Qt::black, penWidth)); + if((ri * 30) + (gi * 59) + (bi * 11) > 12800) + painter.setPen(QPen(Qt::black, penWidth)); else - painter.setPen(QPen(Qt::white, penWidth)); + painter.setPen(QPen(Qt::white, penWidth)); // Draw the selector ellipse. - painter.drawEllipse(QRectF(selectorPos.x() - ellipseSize / 2.0, - selectorPos.y() - ellipseSize / 2.0, - ellipseSize + 0.5, ellipseSize + 0.5)); + painter.drawEllipse(QRectF( + selectorPos.x() - ellipseSize / 2.0, + selectorPos.y() - ellipseSize / 2.0, + ellipseSize + 0.5, + ellipseSize + 0.5)); // Blit p.drawPixmap(contentsRect().topLeft(), pix); @@ -608,9 +659,12 @@ Draws a trigon (polygon with three corners \a pa, \a pb and \a pc color \a color, \a pb is black and \a bc is white. Bilinear gradient. */ -void QtColorTriangle::drawTrigon(QImage *buf, const QPointF &pa, - const QPointF &pb, const QPointF &pc, - const QColor &color) +void QtColorTriangle::drawTrigon( + QImage * buf, + const QPointF &pa, + const QPointF &pb, + const QPointF &pc, + const QColor & color) { // Create three Vertex objects. A Vertex contains a double-point // coordinate and a color. @@ -626,9 +680,12 @@ void QtColorTriangle::drawTrigon(QImage *buf, const QPointF &pa, Vertex *p1 = &aa; Vertex *p2 = &bb; Vertex *p3 = &cc; - if (p1->point.y() > p2->point.y()) swap(&p1, &p2); - if (p1->point.y() > p3->point.y()) swap(&p1, &p3); - if (p2->point.y() > p3->point.y()) swap(&p2, &p3); + if(p1->point.y() > p2->point.y()) + swap(&p1, &p2); + if(p1->point.y() > p3->point.y()) + swap(&p1, &p3); + if(p2->point.y() > p3->point.y()) + swap(&p2, &p3); // All the three y deltas are >= 0 double p1p2ydist = p2->point.y() - p1->point.y(); @@ -648,33 +705,33 @@ void QtColorTriangle::drawTrigon(QImage *buf, const QPointF &pa, // left-to-right drawing of the trigon. QVarLengthArray<DoubleColor, 2000> leftColors; QVarLengthArray<DoubleColor, 2000> rightColors; - QVarLengthArray<double, 2000> leftX; - QVarLengthArray<double, 2000> rightX; + QVarLengthArray<double, 2000> leftX; + QVarLengthArray<double, 2000> rightX; leftColors.resize(int(floor(p3->point.y() + 1))); rightColors.resize(int(floor(p3->point.y() + 1))); leftX.resize(int(floor(p3->point.y() + 1))); rightX.resize(int(floor(p3->point.y() + 1))); - // Scan longy - find all left and right colors and X-values for + // Scan longy - find all left and right colors and X-values for // the tallest edge (p1-p3). DoubleColor source; DoubleColor dest; - double r, g, b; - double rdelta, gdelta, bdelta; - double x; - double xdelta; - int y1, y2; + double r, g, b; + double rdelta, gdelta, bdelta; + double x; + double xdelta; + int y1, y2; // Initialize with known values - x = p1->point.x(); + x = p1->point.x(); source = p1->color; - dest = p3->color; - r = source.r; - g = source.g; - b = source.b; - y1 = (int) floor(p1->point.y()); - y2 = (int) floor(p3->point.y()); + dest = p3->color; + r = source.r; + g = source.g; + b = source.b; + y1 = (int) floor(p1->point.y()); + y2 = (int) floor(p3->point.y()); // Find slopes (notice that if the y dists are 0, we don't care // about the slopes) @@ -685,31 +742,35 @@ void QtColorTriangle::drawTrigon(QImage *buf, const QPointF &pa, // Calculate gradients using linear approximation int y; - for (y = y1; y < y2; ++y) { - if (lefty) { - rightColors[y] = DoubleColor(r, g, b); - rightX[y] = x; - } else { - leftColors[y] = DoubleColor(r, g, b); - leftX[y] = x; - } - - r += rdelta; - g += gdelta; - b += bdelta; - x += xdelta; + for(y = y1; y < y2; ++y) + { + if(lefty) + { + rightColors[y] = DoubleColor(r, g, b); + rightX[y] = x; + } + else + { + leftColors[y] = DoubleColor(r, g, b); + leftX[y] = x; + } + + r += rdelta; + g += gdelta; + b += bdelta; + x += xdelta; } // Scan top shorty - find all left and right colors and x-values // for the topmost of the two not-tallest short edges. - x = p1->point.x(); + x = p1->point.x(); source = p1->color; - dest = p2->color; - r = source.r; - g = source.g; - b = source.b; - y1 = (int) floor(p1->point.y()); - y2 = (int) floor(p2->point.y()); + dest = p2->color; + r = source.r; + g = source.g; + b = source.b; + y1 = (int) floor(p1->point.y()); + y2 = (int) floor(p2->point.y()); // Find slopes (notice that if the y dists are 0, we don't care // about the slopes) @@ -719,31 +780,35 @@ void QtColorTriangle::drawTrigon(QImage *buf, const QPointF &pa, bdelta = p1p2ydist == 0.0 ? 0.0 : (dest.b - b) / p1p2ydist; // Calculate gradients using linear approximation - for (y = y1; y < y2; ++y) { - if (lefty) { - leftColors[y] = DoubleColor(r, g, b); - leftX[y] = x; - } else { - rightColors[y] = DoubleColor(r, g, b); - rightX[y] = x; - } - - r += rdelta; - g += gdelta; - b += bdelta; - x += xdelta; + for(y = y1; y < y2; ++y) + { + if(lefty) + { + leftColors[y] = DoubleColor(r, g, b); + leftX[y] = x; + } + else + { + rightColors[y] = DoubleColor(r, g, b); + rightX[y] = x; + } + + r += rdelta; + g += gdelta; + b += bdelta; + x += xdelta; } // Scan bottom shorty - find all left and right colors and // x-values for the bottommost of the two not-tallest short edges. - x = p2->point.x(); + x = p2->point.x(); source = p2->color; - dest = p3->color; - r = source.r; - g = source.g; - b = source.b; - y1 = (int) floor(p2->point.y()); - y2 = (int) floor(p3->point.y()); + dest = p3->color; + r = source.r; + g = source.g; + b = source.b; + y1 = (int) floor(p2->point.y()); + y2 = (int) floor(p3->point.y()); // Find slopes (notice that if the y dists are 0, we don't care // about the slopes) @@ -753,39 +818,45 @@ void QtColorTriangle::drawTrigon(QImage *buf, const QPointF &pa, bdelta = p2p3ydist == 0.0 ? 0.0 : (dest.b - b) / p2p3ydist; // Calculate gradients using linear approximation - for (y = y1; y < y2; ++y) { - if (lefty) { - leftColors[y] = DoubleColor(r, g, b); - leftX[y] = x; - } else { - rightColors[y] = DoubleColor(r, g, b); - rightX[y] = x; - } - - r += rdelta; - g += gdelta; - b += bdelta; - x += xdelta; + for(y = y1; y < y2; ++y) + { + if(lefty) + { + leftColors[y] = DoubleColor(r, g, b); + leftX[y] = x; + } + else + { + rightColors[y] = DoubleColor(r, g, b); + rightX[y] = x; + } + + r += rdelta; + g += gdelta; + b += bdelta; + x += xdelta; } // Inner loop. For each y in the left map of x-values, draw one // line from left to right. const int p3yfloor = int(floor(p3->point.y())); - for (int y = int(floor(p1->point.y())); y < p3yfloor; ++y) { - double lx = leftX[y]; - double rx = rightX[y]; + for(int y = int(floor(p1->point.y())); y < p3yfloor; ++y) + { + double lx = leftX[y]; + double rx = rightX[y]; - int lxi = (int) floor(lx); - int rxi = (int) floor(rx); - DoubleColor rc = rightColors[y]; - DoubleColor lc = leftColors[y]; + int lxi = (int) floor(lx); + int rxi = (int) floor(rx); + DoubleColor rc = rightColors[y]; + DoubleColor lc = leftColors[y]; // if the xdist is 0, don't draw anything. - double xdist = rx - lx; - if (xdist != 0.0) { - double r = lc.r; - double g = lc.g; - double b = lc.b; + double xdist = rx - lx; + if(xdist != 0.0) + { + double r = lc.r; + double g = lc.g; + double b = lc.b; double rdelta = (rc.r - r) / xdist; double gdelta = (rc.g - g) / xdist; double bdelta = (rc.b - b) / xdist; @@ -794,7 +865,8 @@ void QtColorTriangle::drawTrigon(QImage *buf, const QPointF &pa, scanline += lxi; // Inner loop 2. Draws the line from left to right. - for (int i = lxi; i < rxi; ++i) { + for(int i = lxi; i < rxi; ++i) + { *scanline++ = qRgb((int) r, (int) g, (int) b); r += rdelta; g += gdelta; @@ -810,8 +882,8 @@ Sets the color of the triangle to \a col. */ void QtColorTriangle::setColor(const QColor &col) { - if (col == curColor) - return; + if(col == curColor) + return; curColor = col; @@ -819,22 +891,25 @@ void QtColorTriangle::setColor(const QColor &col) curColor.getHsv(&h, &s, &v); // Never use an invalid hue to display colors - if (h != -1) - curHue = h; + if(h != -1) + curHue = h; a = (((360 - curHue) * TWOPI) / 360.0); a += PI / 2.0; - if (a > TWOPI) a -= TWOPI; + if(a > TWOPI) + a -= TWOPI; - b = a + TWOPI/3; - c = b + TWOPI/3; + b = a + TWOPI / 3; + c = b + TWOPI / 3; - if (b > TWOPI) b -= TWOPI; - if (c > TWOPI) c -= TWOPI; + if(b > TWOPI) + b -= TWOPI; + if(c > TWOPI) + c -= TWOPI; - double cx = (double) contentsRect().center().x(); - double cy = (double) contentsRect().center().y(); - double innerRadius = outerRadius - (outerRadius / 5.0); + double cx = (double) contentsRect().center().x(); + double cy = (double) contentsRect().center().y(); + double innerRadius = outerRadius - (outerRadius / 5.0); double pointerRadius = outerRadius - (outerRadius / 10.0); pa = QPointF(cx + (cos(a) * innerRadius), cy - (sin(a) * innerRadius)); @@ -880,13 +955,13 @@ double QtColorTriangle::angleAt(const QPointF &pos, const QRect &rect) const { double mousexdist = pos.x() - (double) rect.center().x(); double mouseydist = pos.y() - (double) rect.center().y(); - double mouserad = sqrt(mousexdist * mousexdist + mouseydist * mouseydist); - if (mouserad == 0.0) + double mouserad = sqrt(mousexdist * mousexdist + mouseydist * mouseydist); + if(mouserad == 0.0) return 0.0; double angle = acos(mousexdist / mouserad); - if (mouseydist >= 0) - angle = TWOPI - angle; + if(mouseydist >= 0) + angle = TWOPI - angle; return angle; } @@ -925,9 +1000,11 @@ Returns true if the point cos(p),sin(p) is on the arc between */ bool angleBetweenAngles(double p, double a1, double a2) { - if (a1 > a2) { - a2 += TWOPI; - if (p < PI) p += TWOPI; + if(a1 > a2) + { + a2 += TWOPI; + if(p < PI) + p += TWOPI; } return p >= a1 && p < a2; @@ -950,48 +1027,70 @@ bool angleBetweenAngles(double p, double a1, double a2) If ax and bx are equal and ay and by are equal (line is a point), this function will return true if (x,y) is equal to this point. */ -static bool pointAbovePoint(double x, double y, double px, double py, - double ax, double ay, double bx, double by) +static bool pointAbovePoint(double x, double y, double px, double py, double ax, double ay, double bx, double by) { bool result = false; - if (floor(ax) > floor(bx)) { - if (floor(ay) < floor(by)) { - // line is draw upright-to-downleft - if (floor(x) < floor(px) || floor(y) < floor(py)) - result = true; - } else if (floor(ay) > floor(by)) { + if(floor(ax) > floor(bx)) + { + if(floor(ay) < floor(by)) + { + // line is draw upright-to-downleft + if(floor(x) < floor(px) || floor(y) < floor(py)) + result = true; + } + else if(floor(ay) > floor(by)) + { // line is draw downright-to-upleft - if (floor(x) > floor(px) || floor(y) < floor(py)) - result = true; - } else { - // line is flat horizontal - if (y < ay) result = true; - } - } else if (floor(ax) < floor(bx)) { - if (floor(ay) < floor(by)) { - // line is draw upleft-to-downright - if (floor(x) < floor(px) || floor(y) > floor(py)) - result = true; - } else if (floor(ay) > floor(by)) { - // line is draw downleft-to-upright - if (floor(x) > floor(px) || floor(y) > floor(py)) - result = true; - } else { - // line is flat horizontal - if (y > ay) + if(floor(x) > floor(px) || floor(y) < floor(py)) + result = true; + } + else + { + // line is flat horizontal + if(y < ay) result = true; - } - } else { - // line is vertical - if (floor(ay) < floor(by)) { - if (x < ax) result = true; - } else if (floor(ay) > floor(by)) { - if (x > ax) result = true; - } else { - if (!(x == ax && y == ay)) - result = true; - } + } + } + else if(floor(ax) < floor(bx)) + { + if(floor(ay) < floor(by)) + { + // line is draw upleft-to-downright + if(floor(x) < floor(px) || floor(y) > floor(py)) + result = true; + } + else if(floor(ay) > floor(by)) + { + // line is draw downleft-to-upright + if(floor(x) > floor(px) || floor(y) > floor(py)) + result = true; + } + else + { + // line is flat horizontal + if(y > ay) + result = true; + } + } + else + { + // line is vertical + if(floor(ay) < floor(by)) + { + if(x < ax) + result = true; + } + else if(floor(ay) > floor(by)) + { + if(x > ax) + result = true; + } + else + { + if(!(x == ax && y == ay)) + result = true; + } } return result; @@ -1004,80 +1103,94 @@ if (ax,ay) to (bx,by) describes a line, and (x,y) is a point on it is outside the (bx,by) bounds and 0 if (x,y) is within (ax,ay) and (bx,by). */ -static int pointInLine(double x, double y, double ax, double ay, - double bx, double by) +static int pointInLine(double x, double y, double ax, double ay, double bx, double by) { - if (ax > bx) { - if (ay < by) { - // line is draw upright-to-downleft - - // if (x,y) is in on or above the upper right point, - // return -1. - if (y <= ay && x >= ax) - return -1; - - // if (x,y) is in on or below the lower left point, - // return 1. - if (y >= by && x <= bx) - return 1; - } else { - // line is draw downright-to-upleft - - // If the line is flat, only use the x coordinate. - if (floor(ay) == floor(by)) { - // if (x is to the right of the rightmost point, - // return -1. otherwise if x is to the left of the - // leftmost point, return 1. - if (x >= ax) - return -1; - else if (x <= bx) - return 1; - } else { - // if (x,y) is on or below the lower right point, - // return -1. - if (y >= ay && x >= ax) - return -1; - - // if (x,y) is on or above the upper left point, - // return 1. - if (y <= by && x <= bx) - return 1; - } - } - } else { - if (ay < by) { - // line is draw upleft-to-downright + if(ax > bx) + { + if(ay < by) + { + // line is draw upright-to-downleft + + // if (x,y) is in on or above the upper right point, + // return -1. + if(y <= ay && x >= ax) + return -1; + + // if (x,y) is in on or below the lower left point, + // return 1. + if(y >= by && x <= bx) + return 1; + } + else + { + // line is draw downright-to-upleft + + // If the line is flat, only use the x coordinate. + if(floor(ay) == floor(by)) + { + // if (x is to the right of the rightmost point, + // return -1. otherwise if x is to the left of the + // leftmost point, return 1. + if(x >= ax) + return -1; + else if(x <= bx) + return 1; + } + else + { + // if (x,y) is on or below the lower right point, + // return -1. + if(y >= ay && x >= ax) + return -1; + + // if (x,y) is on or above the upper left point, + // return 1. + if(y <= by && x <= bx) + return 1; + } + } + } + else + { + if(ay < by) + { + // line is draw upleft-to-downright // If (x,y) is on or above the upper left point, return - // -1. - if (y <= ay && x <= ax) - return -1; - - // If (x,y) is on or below the lower right point, return - // 1. - if (y >= by && x >= bx) - return 1; - } else { - // line is draw downleft-to-upright - - // If the line is flat, only use the x coordinate. - if (floor(ay) == floor(by)) { - if (x <= ax) - return -1; - else if (x >= bx) - return 1; - } else { - // If (x,y) is on or below the lower left point, return - // -1. - if (y >= ay && x <= ax) - return -1; - - // If (x,y) is on or above the upper right point, return - // 1. - if (y <= by && x >= bx) - return 1; - } - } + // -1. + if(y <= ay && x <= ax) + return -1; + + // If (x,y) is on or below the lower right point, return + // 1. + if(y >= by && x >= bx) + return 1; + } + else + { + // line is draw downleft-to-upright + + // If the line is flat, only use the x coordinate. + if(floor(ay) == floor(by)) + { + if(x <= ax) + return -1; + else if(x >= bx) + return 1; + } + else + { + // If (x,y) is on or below the lower left point, return + // -1. + if(y >= ay && x <= ax) + return -1; + + // If (x,y) is on or above the upper right point, return + // 1. + if(y <= by && x >= bx) + return 1; + } + } } // No tests proved that (x,y) was outside [(ax,ay),(bx,by)], so we @@ -1100,38 +1213,38 @@ static int pointInLine(double x, double y, double ax, double ay, Yes, it's trigonometry. */ -QPointF QtColorTriangle::movePointToTriangle(double x, double y, const Vertex &a, - const Vertex &b, const Vertex &c) const +QPointF +QtColorTriangle::movePointToTriangle(double x, double y, const Vertex &a, const Vertex &b, const Vertex &c) const { // Let v1A be the vector from (x,y) to a. // Let v2A be the vector from a to b. // Find the angle alphaA between v1A and v2A. - double v1xA = x - a.point.x(); - double v1yA = y - a.point.y(); - double v2xA = b.point.x() - a.point.x(); - double v2yA = b.point.y() - a.point.y(); - double vpA = vprod(v1xA, v1yA, v2xA, v2yA); - double cosA = vpA / (vlen(v1xA, v1yA) * vlen(v2xA, v2yA)); + double v1xA = x - a.point.x(); + double v1yA = y - a.point.y(); + double v2xA = b.point.x() - a.point.x(); + double v2yA = b.point.y() - a.point.y(); + double vpA = vprod(v1xA, v1yA, v2xA, v2yA); + double cosA = vpA / (vlen(v1xA, v1yA) * vlen(v2xA, v2yA)); double alphaA = acos(cosA); // Let v1B be the vector from x to b. // Let v2B be the vector from b to c. - double v1xB = x - b.point.x(); - double v1yB = y - b.point.y(); - double v2xB = c.point.x() - b.point.x(); - double v2yB = c.point.y() - b.point.y(); - double vpB = vprod(v1xB, v1yB, v2xB, v2yB); - double cosB = vpB / (vlen(v1xB, v1yB) * vlen(v2xB, v2yB)); + double v1xB = x - b.point.x(); + double v1yB = y - b.point.y(); + double v2xB = c.point.x() - b.point.x(); + double v2yB = c.point.y() - b.point.y(); + double vpB = vprod(v1xB, v1yB, v2xB, v2yB); + double cosB = vpB / (vlen(v1xB, v1yB) * vlen(v2xB, v2yB)); double alphaB = acos(cosB); // Let v1C be the vector from x to c. // Let v2C be the vector from c back to a. - double v1xC = x - c.point.x(); - double v1yC = y - c.point.y(); - double v2xC = a.point.x() - c.point.x(); - double v2yC = a.point.y() - c.point.y(); - double vpC = vprod(v1xC, v1yC, v2xC, v2yC); - double cosC = vpC / (vlen(v1xC, v1yC) * vlen(v2xC, v2yC)); + double v1xC = x - c.point.x(); + double v1yC = y - c.point.y(); + double v2xC = a.point.x() - c.point.x(); + double v2yC = a.point.y() - c.point.y(); + double vpC = vprod(v1xC, v1yC, v2xC, v2yC); + double cosC = vpC / (vlen(v1xC, v1yC) * vlen(v2xC, v2yC)); double alphaC = acos(cosC); // Find the radian angles between the (1,0) vector and the points @@ -1143,62 +1256,70 @@ QPointF QtColorTriangle::movePointToTriangle(double x, double y, const Vertex &a double angleP = angleAt(QPointF(x, y), contentsRect()); // If (x,y) is in the a-b area, project onto the a-b vector. - if (angleBetweenAngles(angleP, angleA, angleB)) { - // Find the distance from (x,y) to a. Then use the slope of - // the a-b vector with this distance and the angle between a-b - // and a-(x,y) to determine the point of intersection of the - // perpendicular projection from (x,y) onto a-b. - double pdist = sqrt(qsqr(x - a.point.x()) + qsqr(y - a.point.y())); + if(angleBetweenAngles(angleP, angleA, angleB)) + { + // Find the distance from (x,y) to a. Then use the slope of + // the a-b vector with this distance and the angle between a-b + // and a-(x,y) to determine the point of intersection of the + // perpendicular projection from (x,y) onto a-b. + double pdist = sqrt(qsqr(x - a.point.x()) + qsqr(y - a.point.y())); // the length of all edges is always > 0 - double p0x = a.point.x() + ((b.point.x() - a.point.x()) / vlen(v2xB, v2yB)) * cos(alphaA) * pdist; - double p0y = a.point.y() + ((b.point.y() - a.point.y()) / vlen(v2xB, v2yB)) * cos(alphaA) * pdist; - - // If (x,y) is above the a-b line, which basically means it's - // outside the triangle, then return its projection onto a-b. - if (pointAbovePoint(x, y, p0x, p0y, a.point.x(), a.point.y(), b.point.x(), b.point.y())) { - // If the projection is "outside" a, return a. If it is - // outside b, return b. Otherwise return the projection. - int n = pointInLine(p0x, p0y, a.point.x(), a.point.y(), b.point.x(), b.point.y()); - if (n < 0) - return a.point; - else if (n > 0) - return b.point; - - return QPointF(p0x, p0y); - } - } else if (angleBetweenAngles(angleP, angleB, angleC)) { - // If (x,y) is in the b-c area, project onto the b-c vector. - double pdist = sqrt(qsqr(x - b.point.x()) + qsqr(y - b.point.y())); + double p0x = a.point.x() + ((b.point.x() - a.point.x()) / vlen(v2xB, v2yB)) * cos(alphaA) * pdist; + double p0y = a.point.y() + ((b.point.y() - a.point.y()) / vlen(v2xB, v2yB)) * cos(alphaA) * pdist; + + // If (x,y) is above the a-b line, which basically means it's + // outside the triangle, then return its projection onto a-b. + if(pointAbovePoint(x, y, p0x, p0y, a.point.x(), a.point.y(), b.point.x(), b.point.y())) + { + // If the projection is "outside" a, return a. If it is + // outside b, return b. Otherwise return the projection. + int n = pointInLine(p0x, p0y, a.point.x(), a.point.y(), b.point.x(), b.point.y()); + if(n < 0) + return a.point; + else if(n > 0) + return b.point; + + return QPointF(p0x, p0y); + } + } + else if(angleBetweenAngles(angleP, angleB, angleC)) + { + // If (x,y) is in the b-c area, project onto the b-c vector. + double pdist = sqrt(qsqr(x - b.point.x()) + qsqr(y - b.point.y())); // the length of all edges is always > 0 double p0x = b.point.x() + ((c.point.x() - b.point.x()) / vlen(v2xC, v2yC)) * cos(alphaB) * pdist; - double p0y = b.point.y() + ((c.point.y() - b.point.y()) / vlen(v2xC, v2yC)) * cos(alphaB) * pdist; - - if (pointAbovePoint(x, y, p0x, p0y, b.point.x(), b.point.y(), c.point.x(), c.point.y())) { - int n = pointInLine(p0x, p0y, b.point.x(), b.point.y(), c.point.x(), c.point.y()); - if (n < 0) - return b.point; - else if (n > 0) - return c.point; - return QPointF(p0x, p0y); - } - } else if (angleBetweenAngles(angleP, angleC, angleA)) { - // If (x,y) is in the c-a area, project onto the c-a vector. - double pdist = sqrt(qsqr(x - c.point.x()) + qsqr(y - c.point.y())); + double p0y = b.point.y() + ((c.point.y() - b.point.y()) / vlen(v2xC, v2yC)) * cos(alphaB) * pdist; + + if(pointAbovePoint(x, y, p0x, p0y, b.point.x(), b.point.y(), c.point.x(), c.point.y())) + { + int n = pointInLine(p0x, p0y, b.point.x(), b.point.y(), c.point.x(), c.point.y()); + if(n < 0) + return b.point; + else if(n > 0) + return c.point; + return QPointF(p0x, p0y); + } + } + else if(angleBetweenAngles(angleP, angleC, angleA)) + { + // If (x,y) is in the c-a area, project onto the c-a vector. + double pdist = sqrt(qsqr(x - c.point.x()) + qsqr(y - c.point.y())); // the length of all edges is always > 0 double p0x = c.point.x() + ((a.point.x() - c.point.x()) / vlen(v2xA, v2yA)) * cos(alphaC) * pdist; - double p0y = c.point.y() + ((a.point.y() - c.point.y()) / vlen(v2xA, v2yA)) * cos(alphaC) * pdist; - - if (pointAbovePoint(x, y, p0x, p0y, c.point.x(), c.point.y(), a.point.x(), a.point.y())) { - int n = pointInLine(p0x, p0y, c.point.x(), c.point.y(), a.point.x(), a.point.y()); - if (n < 0) - return c.point; - else if (n > 0) - return a.point; - return QPointF(p0x, p0y); - } + double p0y = c.point.y() + ((a.point.y() - c.point.y()) / vlen(v2xA, v2yA)) * cos(alphaC) * pdist; + + if(pointAbovePoint(x, y, p0x, p0y, c.point.x(), c.point.y(), a.point.x(), a.point.y())) + { + int n = pointInLine(p0x, p0y, c.point.x(), c.point.y(), a.point.x(), a.point.y()); + if(n < 0) + return c.point; + else if(n > 0) + return a.point; + return QPointF(p0x, p0y); + } } // (x,y) is inside the triangle (inside a-b, b-c and a-c). @@ -1222,10 +1343,10 @@ QPointF QtColorTriangle::movePointToTriangle(double x, double y, const Vertex &a QPointF QtColorTriangle::pointFromColor(const QColor &col) const { // Simplifications for the corner cases. - if (col == Qt::black) - return pb; - else if (col == Qt::white) - return pc; + if(col == Qt::black) + return pb; + else if(col == Qt::white) + return pc; // Find the x and y slopes double ab_deltax = pb.x() - pa.x(); @@ -1236,7 +1357,7 @@ QPointF QtColorTriangle::pointFromColor(const QColor &col) const double ac_deltay = pc.y() - pa.y(); // Extract the h,s,v values of col. - int hue,sat,val; + int hue, sat, val; col.getHsv(&hue, &sat, &val); // Find the line that passes through the triangle where the value @@ -1254,22 +1375,24 @@ QPointF QtColorTriangle::pointFromColor(const QColor &col) const double q4 = pb.y(); // Find the intersection between these lines. - double x = 0; - double y = 0; - if (p1 != p2) { - double a = (q2 - q1) / (p2 - p1); - double c = (q4 - q3) / (p4 - p3); - double b = q1 - a * p1; - double d = q3 - c * p3; - - x = (d - b) / (a - c); - y = a * x + b; - } - else { - x = p1; - y = q3 + (x - p3) * (q4 - q3) / (p4 - p3); - } - + double x = 0; + double y = 0; + if(p1 != p2) + { + double a = (q2 - q1) / (p2 - p1); + double c = (q4 - q3) / (p4 - p3); + double b = q1 - a * p1; + double d = q3 - c * p3; + + x = (d - b) / (a - c); + y = a * x + b; + } + else + { + x = p1; + y = q3 + (x - p3) * (q4 - q3) / (p4 - p3); + } + return QPointF(x, y); } @@ -1284,8 +1407,8 @@ QColor QtColorTriangle::colorFromPoint(const QPointF &p) const { // Find the outer radius of the hue gradient. int outerRadius = (contentsRect().width() - 1) / 2; - if ((contentsRect().height() - 1) / 2 < outerRadius) - outerRadius = (contentsRect().height() - 1) / 2; + if((contentsRect().height() - 1) / 2 < outerRadius) + outerRadius = (contentsRect().height() - 1) / 2; // Find the center coordinates double cx = (double) contentsRect().center().x(); @@ -1293,16 +1416,17 @@ QColor QtColorTriangle::colorFromPoint(const QPointF &p) const // Find the a, b and c from their angles, the center of the rect // and the radius of the hue gradient donut. - QPointF pa(cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); - QPointF pb(cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); - QPointF pc(cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), - cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); + QPointF pa( + cx + (cos(a) * (outerRadius - (outerRadius / 5.0))), cy - (sin(a) * (outerRadius - (outerRadius / 5.0)))); + QPointF pb( + cx + (cos(b) * (outerRadius - (outerRadius / 5.0))), cy - (sin(b) * (outerRadius - (outerRadius / 5.0)))); + QPointF pc( + cx + (cos(c) * (outerRadius - (outerRadius / 5.0))), cy - (sin(c) * (outerRadius - (outerRadius / 5.0)))); // Find the hue value from the angle of the 'a' point. - double angle = a - PI/2.0; - if (angle < 0) angle += TWOPI; + double angle = a - PI / 2.0; + if(angle < 0) + angle += TWOPI; double hue = (360.0 * angle) / TWOPI; // Create the color of the 'a' corner point. We know that b is @@ -1320,9 +1444,12 @@ QColor QtColorTriangle::colorFromPoint(const QPointF &p) const Vertex *p1 = &aa; Vertex *p2 = &bb; Vertex *p3 = &cc; - if (p1->point.y() > p2->point.y()) swap(&p1, &p2); - if (p1->point.y() > p3->point.y()) swap(&p1, &p3); - if (p2->point.y() > p3->point.y()) swap(&p2, &p3); + if(p1->point.y() > p2->point.y()) + swap(&p1, &p2); + if(p1->point.y() > p3->point.y()) + swap(&p1, &p3); + if(p2->point.y() > p3->point.y()) + swap(&p2, &p3); // Find the slopes of all edges in the trigon. All the three y // deltas here are positive because of the above sorting. @@ -1349,41 +1476,62 @@ QColor QtColorTriangle::colorFromPoint(const QPointF &p) const // right x values. double leftx; double rightx; - if (lefty) { - if (firstshorty) { + if(lefty) + { + if(firstshorty) + { leftx = p1->point.x(); - if (floor(p1p2ydist) != 0.0) { + if(floor(p1p2ydist) != 0.0) + { leftx += (p1p2xdist * (p.y() - p1->point.y())) / p1p2ydist; - } else { + } + else + { leftx = qMin(p1->point.x(), p2->point.x()); } - } else { + } + else + { leftx = p2->point.x(); - if (floor(p2p3ydist) != 0.0) { + if(floor(p2p3ydist) != 0.0) + { leftx += (p2p3xdist * (p.y() - p2->point.y())) / p2p3ydist; - } else { + } + else + { leftx = qMin(p2->point.x(), p3->point.x()); } } rightx = p1->point.x(); rightx += (p1p3xdist * (p.y() - p1->point.y())) / p1p3ydist; - } else { + } + else + { leftx = p1->point.x(); leftx += (p1p3xdist * (p.y() - p1->point.y())) / p1p3ydist; - if (firstshorty) { + if(firstshorty) + { rightx = p1->point.x(); - if (floor(p1p2ydist) != 0.0) { + if(floor(p1p2ydist) != 0.0) + { rightx += (p1p2xdist * (p.y() - p1->point.y())) / p1p2ydist; - } else { + } + else + { rightx = qMax(p1->point.x(), p2->point.x()); } - } else { - rightx = p2->point.x(); - if (floor(p2p3ydist) != 0.0) { + } + else + { + rightx = p2->point.x(); + if(floor(p2p3ydist) != 0.0) + { rightx += (p2p3xdist * (p.y() - p2->point.y())) / p2p3ydist; - } else { + } + else + { rightx = qMax(p2->point.x(), p3->point.x()); } } @@ -1393,74 +1541,101 @@ QColor QtColorTriangle::colorFromPoint(const QPointF &p) const // are to the left and right of the selector. double rshort = 0, gshort = 0, bshort = 0; double rlong = 0, glong = 0, blong = 0; - if (firstshorty) { - if (floor(p1p2ydist) != 0.0) { - rshort = p2->color.r * (p.y() - p1->point.y()) / p1p2ydist; - gshort = p2->color.g * (p.y() - p1->point.y()) / p1p2ydist; - bshort = p2->color.b * (p.y() - p1->point.y()) / p1p2ydist; + if(firstshorty) + { + if(floor(p1p2ydist) != 0.0) + { + rshort = p2->color.r * (p.y() - p1->point.y()) / p1p2ydist; + gshort = p2->color.g * (p.y() - p1->point.y()) / p1p2ydist; + bshort = p2->color.b * (p.y() - p1->point.y()) / p1p2ydist; rshort += p1->color.r * (p2->point.y() - p.y()) / p1p2ydist; gshort += p1->color.g * (p2->point.y() - p.y()) / p1p2ydist; bshort += p1->color.b * (p2->point.y() - p.y()) / p1p2ydist; - } else { - if (lefty) { - if (p1->point.x() <= p2->point.x()) { - rshort = p1->color.r; - gshort = p1->color.g; - bshort = p1->color.b; - } else { - rshort = p2->color.r; - gshort = p2->color.g; - bshort = p2->color.b; + } + else + { + if(lefty) + { + if(p1->point.x() <= p2->point.x()) + { + rshort = p1->color.r; + gshort = p1->color.g; + bshort = p1->color.b; } - } else { - if (p1->point.x() > p2->point.x()) { - rshort = p1->color.r; - gshort = p1->color.g; - bshort = p1->color.b; - } else { - rshort = p2->color.r; - gshort = p2->color.g; - bshort = p2->color.b; + else + { + rshort = p2->color.r; + gshort = p2->color.g; + bshort = p2->color.b; + } + } + else + { + if(p1->point.x() > p2->point.x()) + { + rshort = p1->color.r; + gshort = p1->color.g; + bshort = p1->color.b; + } + else + { + rshort = p2->color.r; + gshort = p2->color.g; + bshort = p2->color.b; } } } - } else { - if (floor(p2p3ydist) != 0.0) { - rshort = p3->color.r * (p.y() - p2->point.y()) / p2p3ydist; - gshort = p3->color.g * (p.y() - p2->point.y()) / p2p3ydist; - bshort = p3->color.b * (p.y() - p2->point.y()) / p2p3ydist; + } + else + { + if(floor(p2p3ydist) != 0.0) + { + rshort = p3->color.r * (p.y() - p2->point.y()) / p2p3ydist; + gshort = p3->color.g * (p.y() - p2->point.y()) / p2p3ydist; + bshort = p3->color.b * (p.y() - p2->point.y()) / p2p3ydist; rshort += p2->color.r * (p3->point.y() - p.y()) / p2p3ydist; gshort += p2->color.g * (p3->point.y() - p.y()) / p2p3ydist; bshort += p2->color.b * (p3->point.y() - p.y()) / p2p3ydist; - } else { - if (lefty) { - if (p2->point.x() <= p3->point.x()) { - rshort = p2->color.r; - gshort = p2->color.g; - bshort = p2->color.b; - } else { - rshort = p3->color.r; - gshort = p3->color.g; - bshort = p3->color.b; + } + else + { + if(lefty) + { + if(p2->point.x() <= p3->point.x()) + { + rshort = p2->color.r; + gshort = p2->color.g; + bshort = p2->color.b; + } + else + { + rshort = p3->color.r; + gshort = p3->color.g; + bshort = p3->color.b; + } + } + else + { + if(p2->point.x() > p3->point.x()) + { + rshort = p2->color.r; + gshort = p2->color.g; + bshort = p2->color.b; } - } else { - if (p2->point.x() > p3->point.x()) { - rshort = p2->color.r; - gshort = p2->color.g; - bshort = p2->color.b; - } else { - rshort = p3->color.r; - gshort = p3->color.g; - bshort = p3->color.b; + else + { + rshort = p3->color.r; + gshort = p3->color.g; + bshort = p3->color.b; } } } } // p1p3ydist is never 0 - rlong = p3->color.r * (p.y() - p1->point.y()) / p1p3ydist; - glong = p3->color.g * (p.y() - p1->point.y()) / p1p3ydist; - blong = p3->color.b * (p.y() - p1->point.y()) / p1p3ydist; + rlong = p3->color.r * (p.y() - p1->point.y()) / p1p3ydist; + glong = p3->color.g * (p.y() - p1->point.y()) / p1p3ydist; + blong = p3->color.b * (p.y() - p1->point.y()) / p1p3ydist; rlong += p1->color.r * (p3->point.y() - p.y()) / p1p3ydist; glong += p1->color.g * (p3->point.y() - p.y()) / p1p3ydist; blong += p1->color.b * (p3->point.y() - p.y()) / p1p3ydist; @@ -1470,38 +1645,52 @@ QColor QtColorTriangle::colorFromPoint(const QPointF &p) const // wether we have a lefty trigon or not, we can determine which // colors are on the left and right edge. double rl, gl, bl, rr, gr, br; - if (lefty) { - rl = rshort; gl = gshort; bl = bshort; - rr = rlong; gr = glong; br = blong; - } else { - rl = rlong; gl = glong; bl = blong; - rr = rshort; gr = gshort; br = bshort; + if(lefty) + { + rl = rshort; + gl = gshort; + bl = bshort; + rr = rlong; + gr = glong; + br = blong; + } + else + { + rl = rlong; + gl = glong; + bl = blong; + rr = rshort; + gr = gshort; + br = bshort; } // Find the distance from the left x to the right x (xdist). Then // find the distances from the selector to each of these (saxdist // and saxdist2). These distances are used to find the color at // the selector. - double xdist = rightx - leftx; - double saxdist = p.x() - leftx; + double xdist = rightx - leftx; + double saxdist = p.x() - leftx; double saxdist2 = xdist - saxdist; // Now determine the r,g,b values of the selector using a linear // approximation. double r, g, b; - if (xdist != 0.0) { - r = (saxdist2 * rl / xdist) + (saxdist * rr / xdist); - g = (saxdist2 * gl / xdist) + (saxdist * gr / xdist); - b = (saxdist2 * bl / xdist) + (saxdist * br / xdist); - } else { - // In theory, the left and right color will be equal here. But - // because of the loss of precision, we get an error on both - // colors. The best approximation we can get is from adding - // the two errors, which in theory will eliminate the error - // but in practise will only minimize it. - r = (rl + rr) / 2; + if(xdist != 0.0) + { + r = (saxdist2 * rl / xdist) + (saxdist * rr / xdist); + g = (saxdist2 * gl / xdist) + (saxdist * gr / xdist); + b = (saxdist2 * bl / xdist) + (saxdist * br / xdist); + } + else + { + // In theory, the left and right color will be equal here. But + // because of the loss of precision, we get an error on both + // colors. The best approximation we can get is from adding + // the two errors, which in theory will eliminate the error + // but in practise will only minimize it. + r = (rl + rr) / 2; g = (gl + gr) / 2; - b = (bl + br) / 2; + b = (bl + br) / 2; } // Now floor the color components and fit them into proper @@ -1510,12 +1699,18 @@ QColor QtColorTriangle::colorFromPoint(const QPointF &p) const int ri = (int) floor(r); int gi = (int) floor(g); int bi = (int) floor(b); - if (ri < 0) ri = 0; - else if (ri > 255) ri = 255; - if (gi < 0) gi = 0; - else if (gi > 255) gi = 255; - if (bi < 0) bi = 0; - else if (bi > 255) bi = 255; + if(ri < 0) + ri = 0; + else if(ri > 255) + ri = 255; + if(gi < 0) + gi = 0; + else if(gi > 255) + gi = 255; + if(bi < 0) + bi = 0; + else if(bi > 255) + bi = 255; // Voila, we have the color at the point of the selector. return QColor(ri, gi, bi); diff --git a/src/recognition.cpp b/src/recognition.cpp index b9fdddbf4e8288a75a83b526315d033d6f777aec..b3866b3fdf4cbdc4054cee25d931f4d80d6b761a 100644 --- a/src/recognition.cpp +++ b/src/recognition.cpp @@ -18,41 +18,43 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QPointF> -#include <QRect> -#include <opencv2/opencv.hpp> -#include <opencv2/aruco.hpp> -#include <bitset> - #include "recognition.h" + +#include "codeMarkerItem.h" +#include "codeMarkerWidget.h" +#include "colorMarkerItem.h" +#include "colorMarkerWidget.h" +#include "control.h" +#include "helper.h" #include "markerCasern.h" #include "markerHermes.h" #include "markerJapan.h" -#include "colorMarkerItem.h" #include "multiColorMarkerItem.h" -#include "colorMarkerWidget.h" #include "multiColorMarkerWidget.h" -#include "codeMarkerItem.h" -#include "codeMarkerWidget.h" -#include "helper.h" -#include "tracker.h" -#include "control.h" #include "recognitionRoiItem.h" +#include "tracker.h" +#include <QPointF> +#include <QRect> +#include <bitset> +#include <opencv2/aruco.hpp> +#include <opencv2/opencv.hpp> -namespace reco { + +namespace reco +{ using namespace detail; #define ELLIPSE_DISTANCE_TO_BORDER 10 struct ColorParameters { - int h_low = 0; - int h_high = 359; - int s_low = 0; - int s_high = 255; - int v_low = 0; - int v_high = 255; + int h_low = 0; + int h_high = 359; + int s_low = 0; + int s_high = 255; + int v_low = 0; + int v_high = 255; bool inversHue = false; }; @@ -66,31 +68,31 @@ struct ColorParameters * Each component H, S and V must be in a given range, defined by the parameters. */ -void thresholdHSV (const cv::Mat &src, cv::Mat &bin, const ColorParameters ¶m) +void thresholdHSV(const cv::Mat &src, cv::Mat &bin, const ColorParameters ¶m) { int h, s, v; int x, y; - cv::Mat hsv {src.size(), src.type()}; + cv::Mat hsv{src.size(), src.type()}; cv::cvtColor(src, hsv, cv::COLOR_BGR2HSV); - for (y = 0; y < bin.rows/*binIpl->height*/; ++y) + for(y = 0; y < bin.rows; ++y) { - for (x = 0; x < bin.cols/*binIpl->width*/; ++x) + for(x = 0; x < bin.cols; ++x) { - cv::Vec3b intensity = hsv.at<cv::Vec3b>(cv::Point(x,y)); - h = intensity.val[0]; - s = intensity.val[1]; - v = intensity.val[2]; + cv::Vec3b intensity = hsv.at<cv::Vec3b>(cv::Point(x, y)); + h = intensity.val[0]; + s = intensity.val[1]; + v = intensity.val[2]; // apply the thresholds - if ((!param.inversHue && (h < param.h_low || param.h_high < h)) || - (param.inversHue && (h >= param.h_low && param.h_high >= h)) || - (s < param.s_low || param.s_high < s) || - (v < param.v_low || param.v_high < v)) + if((!param.inversHue && (h < param.h_low || param.h_high < h)) || + (param.inversHue && (h >= param.h_low && param.h_high >= h)) || (s < param.s_low || param.s_high < s) || + (v < param.v_low || param.v_high < v)) { bin.at<uchar>(cv::Point(x, y)) = 0; - }else + } + else { bin.at<uchar>(cv::Point(x, y)) = 255; } @@ -98,18 +100,18 @@ void thresholdHSV (const cv::Mat &src, cv::Mat &bin, const ColorParameters ¶ } } #ifndef STEREO_DISABLED -void thresholdHSV (const IplImage *srcIpl, IplImage *binIpl, const ColorParameters ¶m) +void thresholdHSV(const IplImage *srcIpl, IplImage *binIpl, const ColorParameters ¶m) { const Mat src = cvarrToMat(srcIpl); - Mat bin = cvarrToMat(binIpl); - thresholdHSV(src,bin,param); + Mat bin = cvarrToMat(binIpl); + thresholdHSV(src, bin, param); } #endif -void setColorParameter(const QColor &fromColor, const QColor &toColor, bool inversHue, ColorParameters ¶m) +void setColorParameter(const QColor &fromColor, const QColor &toColor, bool inversHue, ColorParameters ¶m) { - if (fromColor.hue() > toColor.hue()) + if(fromColor.hue() > toColor.hue()) { param.h_low = toColor.hue(); param.h_high = fromColor.hue(); @@ -121,12 +123,12 @@ void setColorParameter(const QColor &fromColor, const QColor &toColor, bool inve } // attention: full range of V is [0,1] or [0.256), // depending on the range of the RGB image - //param.h_low *= 255./359.; - //param.h_high *= 255./359.; + // param.h_low *= 255./359.; + // param.h_high *= 255./359.; // hue scheint nach Konversion bgr nach hsv in opencv nur zwischen 0..179 zu laufen param.h_low /= 2; param.h_high /= 2; - if (fromColor.saturation() > toColor.saturation()) + if(fromColor.saturation() > toColor.saturation()) { param.s_low = toColor.saturation(); param.s_high = fromColor.saturation(); @@ -136,7 +138,7 @@ void setColorParameter(const QColor &fromColor, const QColor &toColor, bool inve param.s_low = fromColor.saturation(); param.s_high = toColor.saturation(); } - if (fromColor.value() > toColor.value()) + if(fromColor.value() > toColor.value()) { param.v_low = toColor.value(); param.v_high = fromColor.value(); @@ -160,26 +162,31 @@ void setColorParameter(const QColor &fromColor, const QColor &toColor, bool inve */ Vec2F autoCorrectColorMarker(Vec2F &boxImageCentre, Control *controlWidget) { - Petrack *mainWindow = controlWidget->getMainWindow(); - cv::Point2f tp = mainWindow->getExtrCalibration()->getImagePoint( - cv::Point3f(-controlWidget->getCalibCoord3DTransX()-controlWidget->getCalibExtrTrans1(), - -controlWidget->getCalibCoord3DTransY()-controlWidget->getCalibExtrTrans2(), 0)); - Vec2F pixUnderCam(tp.x, tp.y); // CvPoint - Vec2F boxImageCentreWithBorder = boxImageCentre; + Petrack * mainWindow = controlWidget->getMainWindow(); + cv::Point2f tp = mainWindow->getExtrCalibration()->getImagePoint(cv::Point3f( + -controlWidget->getCalibCoord3DTransX() - controlWidget->getCalibExtrTrans1(), + -controlWidget->getCalibCoord3DTransY() - controlWidget->getCalibExtrTrans2(), + 0)); + Vec2F pixUnderCam(tp.x, tp.y); // CvPoint + Vec2F boxImageCentreWithBorder = boxImageCentre; boxImageCentreWithBorder += Vec2F(mainWindow->getImageBorderSize(), mainWindow->getImageBorderSize()); pixUnderCam += Vec2F(mainWindow->getImageBorderSize(), mainWindow->getImageBorderSize()); - float angle = 90 - mainWindow->getImageItem()->getAngleToGround(boxImageCentreWithBorder.x(), boxImageCentreWithBorder.y(), 175);// Hoehe 175 cm ist egal, da auf jeder Hoehe gleicher Winkel + float angle = 90 - mainWindow->getImageItem()->getAngleToGround( + boxImageCentreWithBorder.x(), + boxImageCentreWithBorder.y(), + 175); // Hoehe 175 cm ist egal, da auf jeder Hoehe gleicher Winkel - Vec2F moveDir = boxImageCentreWithBorder-pixUnderCam; + Vec2F moveDir = boxImageCentreWithBorder - pixUnderCam; moveDir.normalize(); cv::Point3f p3x1, p3x2; - p3x1 = mainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(boxImageCentre.x(),boxImageCentre.y()),175); - p3x2 = mainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(boxImageCentre.x()+moveDir.x(),boxImageCentre.y()+moveDir.y()),175); - p3x1 = p3x1-p3x2; + p3x1 = mainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(boxImageCentre.x(), boxImageCentre.y()), 175); + p3x2 = mainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(boxImageCentre.x() + moveDir.x(), boxImageCentre.y() + moveDir.y()), 175); + p3x1 = p3x1 - p3x2; Vec2F cmPerPixel(p3x1.x, p3x1.y); - return (0.12*angle/cmPerPixel.length())*moveDir; // Maik Dissertation Seite 138 + return (0.12 * angle / cmPerPixel.length()) * moveDir; // Maik Dissertation Seite 138 } /** @@ -198,86 +205,109 @@ Vec2F autoCorrectColorMarker(Vec2F &boxImageCentre, Control *controlWidget) * @param options all options, mostly forwarded from the UI * @return vector of detected ColorBlobs (see struct ColorBlob for details) */ -[[nodiscard]] std::vector<ColorBlob> detail::findColorBlob(const ColorBlobDetectionParams &options){ +[[nodiscard]] std::vector<ColorBlob> detail::findColorBlob(const ColorBlobDetectionParams &options) +{ std::vector<ColorBlob> colorBlobs; - ColorParameters param; + ColorParameters param; setColorParameter(options.fromColor, options.toColor, options.invHue, param); // Marker Color is set according to the color which is searched // Calculating is only neccessary for casern-marker like markers - const QColor markerColor = [param](){ - if (param.inversHue) + const QColor markerColor = [param]() + { + if(param.inversHue) { - return QColor::fromHsv(2*((param.h_low+(param.h_high-param.h_low)/2+90)%180), - (param.s_high + param.s_low)/2, - (param.v_high + param.v_low)/2); + return QColor::fromHsv( + 2 * ((param.h_low + (param.h_high - param.h_low) / 2 + 90) % 180), + (param.s_high + param.s_low) / 2, + (param.v_high + param.v_low) / 2); } - return QColor::fromHsv(2*(param.h_low+(param.h_high-param.h_low)/2), - (param.s_high + param.s_low)/2, - (param.v_high + param.v_low)/2); - }(); // Lambda so markerColor can be const + return QColor::fromHsv( + 2 * (param.h_low + (param.h_high - param.h_low) / 2), + (param.s_high + param.s_low) / 2, + (param.v_high + param.v_low) / 2); + }(); // Lambda so markerColor can be const - cv::Mat img = options.img; + cv::Mat img = options.img; cv::Mat binary = options.binary; // color thresholding - thresholdHSV(img , binary, param); + thresholdHSV(img, binary, param); // close small holes: radius ( hole ) < radius ( close ) - if (options.useClose) + if(options.useClose) { const int radiusClose = options.radiusClose; - cv::morphologyEx(binary,binary,cv::MORPH_CLOSE,getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(2*radiusClose+1, 2*radiusClose+1),cv::Point(radiusClose, radiusClose))); + cv::morphologyEx( + binary, + binary, + cv::MORPH_CLOSE, + getStructuringElement( + cv::MORPH_ELLIPSE, + cv::Size(2 * radiusClose + 1, 2 * radiusClose + 1), + cv::Point(radiusClose, radiusClose))); } // remove small blobs: radius ( blob ) < radius ( open ) - if (options.useOpen) + if(options.useOpen) { const int radiusOpen = options.radiusOpen; - cv::morphologyEx(binary,binary,cv::MORPH_OPEN,getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(2*radiusOpen+1, 2*radiusOpen+1),cv::Point(radiusOpen, radiusOpen))); + cv::morphologyEx( + binary, + binary, + cv::MORPH_OPEN, + getStructuringElement( + cv::MORPH_ELLIPSE, + cv::Size(2 * radiusOpen + 1, 2 * radiusOpen + 1), + cv::Point(radiusOpen, radiusOpen))); } std::vector<std::vector<cv::Point>> contours; - cv::findContours(binary,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE); + cv::findContours(binary, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); - for(const auto& contour : contours){ + for(const auto &contour : contours) + { double area = cv::contourArea(contour); cv::RotatedRect box = cv::minAreaRect(contour); - float maxExpansion; + float maxExpansion; double ratio; - if (box.size.height > box.size.width) + if(box.size.height > box.size.width) { - ratio = static_cast<double>(box.size.height/box.size.width); + ratio = static_cast<double>(box.size.height / box.size.width); maxExpansion = box.size.height; } else { - ratio = static_cast<double>(box.size.width/box.size.height); + ratio = static_cast<double>(box.size.width / box.size.height); maxExpansion = box.size.width; } // contour at border of roi, than neglect because of object going out of region has moving center - bool atEdge = std::any_of(contour.cbegin(), contour.cend(), [&](const cv::Point& p){ - return (p.x <= 1) || (p.x >= img.cols-2) || - (p.y <= 1) || (p.y >= img.rows-2); - }); + bool atEdge = std::any_of( + contour.cbegin(), + contour.cend(), + [&](const cv::Point &p) + { return (p.x <= 1) || (p.x >= img.cols - 2) || (p.y <= 1) || (p.y >= img.rows - 2); }); - if(atEdge){ + if(atEdge) + { continue; } - if(area < options.minArea || area > options.maxArea){ + if(area < options.minArea || area > options.maxArea) + { continue; } - if(ratio > options.maxRatio){ + if(ratio > options.maxRatio) + { continue; } // centre of rect in the coordinates of the whole image (instead of ROI) Vec2F boxImageCentre = options.offset; - boxImageCentre.setX(boxImageCentre.x()+static_cast<double>(box.center.x)); - boxImageCentre.setY(boxImageCentre.y()+static_cast<double>(box.center.y)); + boxImageCentre.setX(boxImageCentre.x() + static_cast<double>(box.center.x)); + boxImageCentre.setY(boxImageCentre.y() + static_cast<double>(box.center.y)); // TODO maybe use move constructor to increase perf for contour(then not const anymore) colorBlobs.push_back({box, boxImageCentre, markerColor, contour, static_cast<double>(maxExpansion)}); @@ -293,82 +323,82 @@ Vec2F autoCorrectColorMarker(Vec2F &boxImageCentre, Control *controlWidget) * @param[in] bS bordersize * @param[in,out] cropRect cropRect to restrict/resize */ -void detail::restrictPositionBlackDot(ColorBlob& blob, ImageItem *imageItem, int bS, cv::Rect& cropRect) +void detail::restrictPositionBlackDot(ColorBlob &blob, ImageItem *imageItem, int bS, cv::Rect &cropRect) { - double xy,x1, x2, y1, y2; + double xy, x1, x2, y1, y2; Vec2F &boxImageCentre = blob.imageCenter; - xy=imageItem->getAngleToGround(boxImageCentre.x()+bS, boxImageCentre.y()+bS, 175); - x1=imageItem->getAngleToGround(boxImageCentre.x()+bS+10, boxImageCentre.y()+bS, 175); - x2=imageItem->getAngleToGround(boxImageCentre.x()+bS-10, boxImageCentre.y()+bS, 175); - y1=imageItem->getAngleToGround(boxImageCentre.x()+bS, boxImageCentre.y()+bS+10, 175); - y2=imageItem->getAngleToGround(boxImageCentre.x()+bS, boxImageCentre.y()+bS-10, 175); - - double subFactorBig = 1.-.75*(90.-xy)/90.; // -.5 //in 1.0..0.25 // xy in 0..90 - constexpr double subFactorSmall = .85; // .9 - if (x1>x2) // Person links von Achse + xy = imageItem->getAngleToGround(boxImageCentre.x() + bS, boxImageCentre.y() + bS, 175); + x1 = imageItem->getAngleToGround(boxImageCentre.x() + bS + 10, boxImageCentre.y() + bS, 175); + x2 = imageItem->getAngleToGround(boxImageCentre.x() + bS - 10, boxImageCentre.y() + bS, 175); + y1 = imageItem->getAngleToGround(boxImageCentre.x() + bS, boxImageCentre.y() + bS + 10, 175); + y2 = imageItem->getAngleToGround(boxImageCentre.x() + bS, boxImageCentre.y() + bS - 10, 175); + + double subFactorBig = 1. - .75 * (90. - xy) / 90.; // -.5 //in 1.0..0.25 // xy in 0..90 + constexpr double subFactorSmall = .85; // .9 + if(x1 > x2) // Person links von Achse { - if (y1>y2) // Person links oben von Achse + if(y1 > y2) // Person links oben von Achse { - if (x1>y1) // starker Beschnitt rechts, kleiner Beschnitt unten + if(x1 > y1) // starker Beschnitt rechts, kleiner Beschnitt unten { - cropRect.width *= subFactorBig; // ist int + cropRect.width *= subFactorBig; // ist int cropRect.height *= subFactorSmall; // ist int } else // starker Beschnitt unten, kleiner Beschnitt rechts { cropRect.width *= subFactorSmall; // ist int - cropRect.height *= subFactorBig; // ist int + cropRect.height *= subFactorBig; // ist int } } else // Person links unten von Achse { - if (x1>y2) // starker Beschnitt rechts, kleiner Beschnitt oben + if(x1 > y2) // starker Beschnitt rechts, kleiner Beschnitt oben { - cropRect.y = cropRect.y+cropRect.height*(1-subFactorSmall); - cropRect.width *= subFactorBig; // ist int + cropRect.y = cropRect.y + cropRect.height * (1 - subFactorSmall); + cropRect.width *= subFactorBig; // ist int cropRect.height *= subFactorSmall; // ist int } else // starker Beschnitt oben, kleiner Beschnitt rechts { - cropRect.y = cropRect.y+cropRect.height*(1-subFactorBig); + cropRect.y = cropRect.y + cropRect.height * (1 - subFactorBig); cropRect.width *= subFactorSmall; // ist int - cropRect.height *= subFactorBig; // ist int + cropRect.height *= subFactorBig; // ist int } } } else // Person rechts von Achse { - if (y1>y2) // Person rechts oben von Achse + if(y1 > y2) // Person rechts oben von Achse { - if (x2>y1) // starker Beschnitt links, kleiner Beschnitt unten + if(x2 > y1) // starker Beschnitt links, kleiner Beschnitt unten { - cropRect.x = cropRect.x+cropRect.width*(1-subFactorBig); - cropRect.width *= subFactorBig; // ist int + cropRect.x = cropRect.x + cropRect.width * (1 - subFactorBig); + cropRect.width *= subFactorBig; // ist int cropRect.height *= subFactorSmall; // ist int } else // starker Beschnitt unten, kleiner Beschnitt links { - cropRect.x = cropRect.x+cropRect.width*(1-subFactorSmall); + cropRect.x = cropRect.x + cropRect.width * (1 - subFactorSmall); cropRect.width *= subFactorSmall; // ist int - cropRect.height *= subFactorBig; // ist int + cropRect.height *= subFactorBig; // ist int } } else // Person rechts unten von Achse { - if (x2>y2) // starker Beschnitt links, kleiner Beschnitt oben + if(x2 > y2) // starker Beschnitt links, kleiner Beschnitt oben { - cropRect.x = cropRect.x+cropRect.width*(1-subFactorBig); - cropRect.y = cropRect.y+cropRect.height*(1-subFactorSmall); - cropRect.width *= subFactorBig; // ist int + cropRect.x = cropRect.x + cropRect.width * (1 - subFactorBig); + cropRect.y = cropRect.y + cropRect.height * (1 - subFactorSmall); + cropRect.width *= subFactorBig; // ist int cropRect.height *= subFactorSmall; // ist int } else // starker Beschnitt oben, kleiner Beschnitt links { - cropRect.x = cropRect.x+cropRect.width*(1-subFactorSmall); - cropRect.y = cropRect.y+cropRect.height*(1-subFactorBig); + cropRect.x = cropRect.x + cropRect.width * (1 - subFactorSmall); + cropRect.y = cropRect.y + cropRect.height * (1 - subFactorBig); cropRect.width *= subFactorSmall; // ist int - cropRect.height *= subFactorBig; // ist int + cropRect.height *= subFactorBig; // ist int } } } @@ -384,18 +414,18 @@ void detail::restrictPositionBlackDot(ColorBlob& blob, ImageItem *imageItem, int * @param midHue midHue used for weigthed conversion * @return image converted to grayscale */ -cv::Mat detail::customBgr2Gray(const cv::Mat& subImg, const QColor& midHue) +cv::Mat detail::customBgr2Gray(const cv::Mat &subImg, const QColor &midHue) { cv::Mat subGray; - float scaleR = midHue.redF(); - float scaleG = midHue.greenF(); - float scaleB = midHue.blueF(); - float scaleSum = scaleR+scaleG+scaleB; - scaleR/=scaleSum; - scaleG/=scaleSum; - scaleB/=scaleSum; - cv::Mat bgrToGray = (cv::Mat_<double>(1,3) << scaleB, scaleG, scaleR); + float scaleR = midHue.redF(); + float scaleG = midHue.greenF(); + float scaleB = midHue.blueF(); + float scaleSum = scaleR + scaleG + scaleB; + scaleR /= scaleSum; + scaleG /= scaleSum; + scaleB /= scaleSum; + cv::Mat bgrToGray = (cv::Mat_<double>(1, 3) << scaleB, scaleG, scaleR); // Performs the matrix-vector multiplication MxN for each pixel of subImg, where M is bgrToGray // and N is a vector of all channels of a pixel, the result will be saved in subGray. @@ -420,94 +450,110 @@ cv::Mat detail::customBgr2Gray(const cv::Mat& subImg, const QColor& midHue) * @param crossList list of all detected people * @param options BlackDotOptions struct mostly forwarding all options from UI */ -void detail::refineWithBlackDot(std::vector<ColorBlob>& blobs, const cv::Mat& img, QList<TrackPoint>& crossList, const BlackDotOptions& options) +void detail::refineWithBlackDot( + std::vector<ColorBlob> &blobs, + const cv::Mat & img, + QList<TrackPoint> & crossList, + const BlackDotOptions & options) { - constexpr int border=4; // zusaetzlicher rand um subrects - const int bS = options.borderSize; - const bool restrictPosition = options.restrictPosition; - ImageItem *imageItem = options.imageItem; - const QColor midHue = options.midHue; - const double dotSize = options.dotSize; - const bool ignoreWithoutMarker = options.ignoreWithoutMarker; - const bool autoCorrect = options.autoCorrect; - const bool autoCorrectOnlyExport = options.autoCorrectOnlyExport; - Control *controlWidget = options.controlWidget; - - for(ColorBlob& blob : blobs) + constexpr int border = 4; // zusaetzlicher rand um subrects + const int bS = options.borderSize; + const bool restrictPosition = options.restrictPosition; + ImageItem * imageItem = options.imageItem; + const QColor midHue = options.midHue; + const double dotSize = options.dotSize; + const bool ignoreWithoutMarker = options.ignoreWithoutMarker; + const bool autoCorrect = options.autoCorrect; + const bool autoCorrectOnlyExport = options.autoCorrectOnlyExport; + Control * controlWidget = options.controlWidget; + + for(ColorBlob &blob : blobs) { - cv::Rect cropRect; + cv::Rect cropRect; cv::RotatedRect &box = blob.box; - cropRect.x = std::max(1, myRound(box.center.x-box.size.width/2-border)); - cropRect.y = std::max(1, myRound(box.center.y-box.size.height/2-border)); + cropRect.x = std::max(1, myRound(box.center.x - box.size.width / 2 - border)); + cropRect.y = std::max(1, myRound(box.center.y - box.size.height / 2 - border)); // 1. rundet kaufmaennisch, 2. dann rundet zur naechst kleiner geraden zahl // min wegen bildrand - cropRect.width = std::min(img.cols-cropRect.x-1, 2*border+(myRound(blob.maxExpansion) & -2)); - cropRect.height = std::min(img.rows-cropRect.y-1, 2*border+(myRound(blob.maxExpansion) & -2));//cropRect.height = cropRect.width; + cropRect.width = std::min(img.cols - cropRect.x - 1, 2 * border + (myRound(blob.maxExpansion) & -2)); + cropRect.height = std::min( + img.rows - cropRect.y - 1, + 2 * border + (myRound(blob.maxExpansion) & -2)); // cropRect.height = cropRect.width; - if (restrictPosition) + if(restrictPosition) { restrictPositionBlackDot(blob, imageItem, bS, cropRect); } // cvtColor results in really dark images, especially with red shades // so using custom conversion weighted by midHue - cv::Mat subImg = img(cropRect); + cv::Mat subImg = img(cropRect); cv::Mat subGray = customBgr2Gray(subImg, midHue); cv::Mat subBW; - double maxThreshold = std::max(std::max(getValue(subGray, subGray.cols/2, subGray.rows/2).value(), - getValue(subGray, subGray.cols/4, subGray.rows/2).value()), - getValue(subGray, 3*subGray.cols/4, subGray.rows/2).value()); - int step = static_cast<int>((maxThreshold-5))/5; - int minGrey = 300; + double maxThreshold = std::max( + std::max( + getValue(subGray, subGray.cols / 2, subGray.rows / 2).value(), + getValue(subGray, subGray.cols / 4, subGray.rows / 2).value()), + getValue(subGray, 3 * subGray.cols / 4, subGray.rows / 2).value()); + int step = static_cast<int>((maxThreshold - 5)) / 5; + int minGrey = 300; Vec2F subCenter; - for (int threshold = 5; threshold < maxThreshold; threshold += step) + for(int threshold = 5; threshold < maxThreshold; threshold += step) { - cv::threshold(subGray,subBW,threshold,255,cv::THRESH_BINARY); + cv::threshold(subGray, subBW, threshold, 255, cv::THRESH_BINARY); // find contours and store them all as a list std::vector<std::vector<cv::Point>> subContours; - cv::findContours(subBW,subContours,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE); + cv::findContours(subBW, subContours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); // test each contour - for(auto& subContour : subContours) + for(auto &subContour : subContours) { - if (subContour.size() > 5) // This is number point in contour + if(subContour.size() > 5) // This is number point in contour { cv::RotatedRect subBox = cv::minAreaRect(subContour); - double subRatio; - double subMaxExpansion; - if (subBox.size.height > subBox.size.width) + double subRatio; + double subMaxExpansion; + if(subBox.size.height > subBox.size.width) { - subRatio = subBox.size.height/subBox.size.width; + subRatio = subBox.size.height / subBox.size.width; subMaxExpansion = subBox.size.height; } else { - subRatio = subBox.size.width/subBox.size.height; + subRatio = subBox.size.width / subBox.size.height; subMaxExpansion = subBox.size.width; } - QPointF cmPerPixel =imageItem->getCmPerPixel(cropRect.x+subBox.center.x, cropRect.y+subBox.center.y, controlWidget->mapDefaultHeight->value()); - double cmPerPixelAvg = (cmPerPixel.x()+cmPerPixel.y())/2.; - double markerSize = dotSize/cmPerPixelAvg;//war: 5cm// war WDG: = 16; war GymBay: = headSize / 4.5; + QPointF cmPerPixel = imageItem->getCmPerPixel( + cropRect.x + subBox.center.x, + cropRect.y + subBox.center.y, + controlWidget->mapDefaultHeight->value()); + double cmPerPixelAvg = (cmPerPixel.x() + cmPerPixel.y()) / 2.; + double markerSize = + dotSize / cmPerPixelAvg; // war: 5cm// war WDG: = 16; war GymBay: = headSize / 4.5; // maximalseitenverhaeltnis && minimal und maximaldurchmesser - if (subRatio < 1.8 && subMaxExpansion < markerSize*1.5 && subMaxExpansion > markerSize/2)//1.5 + if(subRatio < 1.8 && subMaxExpansion < markerSize * 1.5 && subMaxExpansion > markerSize / 2) // 1.5 { - double subContourArea = cv::contourArea(subContour,true); - int cx = myRound(subBox.center.x); - int cy = myRound(subBox.center.y); + double subContourArea = cv::contourArea(subContour, true); + int cx = myRound(subBox.center.x); + int cy = myRound(subBox.center.y); // darker inside && dark inside && mittelpunkt in kopfkontur int xygrey = getValue(subGray, cx, cy).value(); // debout << "xygrey: " << xygrey << endl; - if (subContourArea>0 && xygrey<std::min(150.,2*maxThreshold/3) && (0<cv::pointPolygonTest(blob.contour,cv::Point2f(cropRect.x+subBox.center.x, cropRect.y+subBox.center.y),false))) // dark inside + if(subContourArea > 0 && xygrey < std::min(150., 2 * maxThreshold / 3) && + (0 < cv::pointPolygonTest( + blob.contour, + cv::Point2f(cropRect.x + subBox.center.x, cropRect.y + subBox.center.y), + false))) // dark inside { - if (minGrey > xygrey) + if(minGrey > xygrey) { minGrey = xygrey; - subCenter.set(cropRect.x+subBox.center.x, cropRect.y+subBox.center.y); + subCenter.set(cropRect.x + subBox.center.x, cropRect.y + subBox.center.y); } } } @@ -515,22 +561,30 @@ void detail::refineWithBlackDot(std::vector<ColorBlob>& blobs, const cv::Mat& im } } - if (minGrey <260) // mit gefundenem schwarzem punkt + if(minGrey < 260) // mit gefundenem schwarzem punkt { - crossList.append(TrackPoint(subCenter, 100, Vec2F(box.center.x, box.center.y), blob.color)); // 100 beste qualitaet + crossList.append( + TrackPoint(subCenter, 100, Vec2F(box.center.x, box.center.y), blob.color)); // 100 beste qualitaet } - else if (!ignoreWithoutMarker) + else if(!ignoreWithoutMarker) { - if (autoCorrect && !autoCorrectOnlyExport) + if(autoCorrect && !autoCorrectOnlyExport) { Vec2F moveDir = autoCorrectColorMarker(blob.imageCenter, controlWidget); - crossList.append(TrackPoint(Vec2F(box.center.x, box.center.y)+moveDir, 100, Vec2F(box.center.x, box.center.y), blob.color)); // 100 beste qualitaet + crossList.append(TrackPoint( + Vec2F(box.center.x, box.center.y) + moveDir, + 100, + Vec2F(box.center.x, box.center.y), + blob.color)); // 100 beste qualitaet } else - crossList.append(TrackPoint(Vec2F(box.center.x, box.center.y), 90, Vec2F(box.center.x, box.center.y), blob.color)); // 100 beste qualitaet + crossList.append(TrackPoint( + Vec2F(box.center.x, box.center.y), + 90, + Vec2F(box.center.x, box.center.y), + blob.color)); // 100 beste qualitaet } - } } @@ -550,35 +604,46 @@ void detail::refineWithBlackDot(std::vector<ColorBlob>& blobs, const cv::Mat& im * @param crossList list of all detected people * @param options all options, mostly forwarded from the GUI */ -void detail::refineWithAruco(std::vector<ColorBlob> &blobs, const cv::Mat& img, QList<TrackPoint> &crossList, ArucoOptions& options) +void detail::refineWithAruco( + std::vector<ColorBlob> &blobs, + const cv::Mat & img, + QList<TrackPoint> & crossList, + ArucoOptions & options) { - constexpr int border=4; // zusaetzlicher rand um subrects + constexpr int border = 4; // zusaetzlicher rand um subrects - Control *controlWidget = options.controlWidget; - bool ignoreWithoutMarker = options.ignoreWithoutMarker; - bool autoCorrect = options.autoCorrect; - bool autoCorrectOnlyExport = options.autoCorrectOnlyExport; + Control *controlWidget = options.controlWidget; + bool ignoreWithoutMarker = options.ignoreWithoutMarker; + bool autoCorrect = options.autoCorrect; + bool autoCorrectOnlyExport = options.autoCorrectOnlyExport; - CodeMarkerOptions& codeOpt = options.codeOpt; - for(ColorBlob& blob : blobs) + CodeMarkerOptions &codeOpt = options.codeOpt; + for(ColorBlob &blob : blobs) { - // cropRect has coordinates of rechtangele around color blob with respect to lower left corner (as in the beginning of useBlackDot) - cv::Rect cropRect; - const cv::RotatedRect &box = blob.box; - int extendRect = myRound(blob.maxExpansion*.3); // scalar to increase area of cropRect for better detection of codemarkers when marker appears to stick out of the colored head because of tilted heads; value of .3 chosen arbitrarily after discussion - cropRect.x = std::max(1, myRound(box.center.x-box.size.width/2.-border)); - cropRect.y = std::max(1, myRound(box.center.y-box.size.height/2.-border)); - cropRect.width = std::min(img.cols-cropRect.x-extendRect-1, 2*border+((myRound(blob.maxExpansion)+extendRect) & -2)); - cropRect.height = std::min(img.rows-cropRect.y-extendRect-1, 2*border+((myRound(blob.maxExpansion)+extendRect) & -2)); + // cropRect has coordinates of rechtangele around color blob with respect to lower left corner (as in the + // beginning of useBlackDot) + cv::Rect cropRect; + const cv::RotatedRect &box = blob.box; + int extendRect = myRound( + blob.maxExpansion * + .3); // scalar to increase area of cropRect for better detection of codemarkers when marker appears to stick + // out of the colored head because of tilted heads; value of .3 chosen arbitrarily after discussion + cropRect.x = std::max(1, myRound(box.center.x - box.size.width / 2. - border)); + cropRect.y = std::max(1, myRound(box.center.y - box.size.height / 2. - border)); + cropRect.width = std::min( + img.cols - cropRect.x - extendRect - 1, 2 * border + ((myRound(blob.maxExpansion) + extendRect) & -2)); + cropRect.height = std::min( + img.rows - cropRect.y - extendRect - 1, 2 * border + ((myRound(blob.maxExpansion) + extendRect) & -2)); cv::Mat subImg = img(cropRect); // --> shallow copy (points to original data) int lengthini = crossList.size(); // initial length of crossList (before findCodeMarker() is called) - Vec2F offsetCropRect2Roi; // needed for drawing detected ArucoCode-Candidates correctly -> passed on to findCodeMarker()-Function + Vec2F offsetCropRect2Roi; // needed for drawing detected ArucoCode-Candidates correctly -> passed on to + // findCodeMarker()-Function offsetCropRect2Roi.setX(cropRect.x); offsetCropRect2Roi.setY(cropRect.y); - if (subImg.empty()) + if(subImg.empty()) continue; // TODO: Use Reference to actual codeMarkerOptions in MulticolorMarkerOptions // NOTE: For now, add as parameter of findMulticolorMarker @@ -586,13 +651,15 @@ void detail::refineWithAruco(std::vector<ColorBlob> &blobs, const cv::Mat& img, findCodeMarker(subImg, crossList, options.method, codeOpt); // The next three statements each: - // - set the offset of subImg with regards to ROI //(ROI to original image is archieved later in the code for all methods) + // - set the offset of subImg with regards to ROI //(ROI to original image is archieved later in the code for + // all methods) // - add the functionality of autocorrection // - deal with functionality of ignore/not ignore heads without identified ArucoMarker - if (ignoreWithoutMarker && lengthini!=crossList.size()) // if CodeMarker-Call returns crossList containing a new element (identified the ArucoMarker) + if(ignoreWithoutMarker && lengthini != crossList.size()) // if CodeMarker-Call returns crossList containing a + // new element (identified the ArucoMarker) { Vec2F moveDir; - if (autoCorrect && !autoCorrectOnlyExport) + if(autoCorrect && !autoCorrectOnlyExport) { moveDir = autoCorrectColorMarker(blob.imageCenter, controlWidget); } @@ -604,26 +671,36 @@ void detail::refineWithAruco(std::vector<ColorBlob> &blobs, const cv::Mat& img, crossList.back().setColPoint(Vec2F(box.center.x, box.center.y)); crossList.back() = crossList.back() + (Vec2F(cropRect.x, cropRect.y) + moveDir); } - else if(!ignoreWithoutMarker && (lengthini==crossList.size())) // in case ignoreWithoutMarker is checked and CodeMarker-Call returns empty crossList (could not identify a marker) the center of the smallest rectangle around the colorblobb is used as position + else if(!ignoreWithoutMarker && (lengthini == crossList.size())) // in case ignoreWithoutMarker is checked and + // CodeMarker-Call returns empty crossList + // (could not identify a marker) the center of + // the smallest rectangle around the colorblobb + // is used as position { offsetCropRect2Roi.setX(0); // set to zero as cooridinates are directly used from cropRect offsetCropRect2Roi.setY(0); Vec2F moveDir; - if (autoCorrect && !autoCorrectOnlyExport) + if(autoCorrect && !autoCorrectOnlyExport) { moveDir = autoCorrectColorMarker(blob.imageCenter, controlWidget); } else { - moveDir = Vec2F(0,0); + moveDir = Vec2F(0, 0); } - crossList.append(TrackPoint(Vec2F(box.center.x, box.center.y) + moveDir, 90, Vec2F(box.center.x, box.center.y), blob.color)); // 100 beste qualitaet + crossList.append(TrackPoint( + Vec2F(box.center.x, box.center.y) + moveDir, + 90, + Vec2F(box.center.x, box.center.y), + blob.color)); // 100 beste qualitaet } - else if(!ignoreWithoutMarker && (crossList.size()!=lengthini)) // in case ignoreWithoutMarker is checked and CodeMarker-Call returns non-empty crossList (could identify a marker) + else if(!ignoreWithoutMarker && (crossList.size() != lengthini)) // in case ignoreWithoutMarker is checked and + // CodeMarker-Call returns non-empty crossList + // (could identify a marker) { Vec2F moveDir; - if (autoCorrect && !autoCorrectOnlyExport) + if(autoCorrect && !autoCorrectOnlyExport) { moveDir = autoCorrectColorMarker(blob.imageCenter, controlWidget); } @@ -636,7 +713,7 @@ void detail::refineWithAruco(std::vector<ColorBlob> &blobs, const cv::Mat& img, crossList.back() = crossList.back() + (Vec2F(cropRect.x, cropRect.y) + moveDir); } } - codeOpt.setOffsetCropRect2Roi(Vec2F{0,0}); + codeOpt.setOffsetCropRect2Roi(Vec2F{0, 0}); } /** @@ -652,107 +729,123 @@ void detail::refineWithAruco(std::vector<ColorBlob> &blobs, const cv::Mat& img, * @param ignoreWithoutMarker (is ignored->overwritten by cmWidget->ignoreWithoutDot->isChecked()) * @param offset */ -void findMultiColorMarker(cv::Mat &img, QList<TrackPoint> &crossList, Control *controlWidget, bool ignoreWithoutMarker, Vec2F &offset, RecognitionMethod method, CodeMarkerOptions& codeOpt) +void findMultiColorMarker( + cv::Mat & img, + QList<TrackPoint> &crossList, + Control * controlWidget, + bool ignoreWithoutMarker, + Vec2F & offset, + RecognitionMethod method, + CodeMarkerOptions &codeOpt) { - Petrack *mainWindow = controlWidget->getMainWindow(); - MultiColorMarkerItem* cmItem = mainWindow->getMultiColorMarkerItem(); - MultiColorMarkerWidget* cmWidget = mainWindow->getMultiColorMarkerWidget(); - int bS = mainWindow->getImageBorderSize(); + Petrack * mainWindow = controlWidget->getMainWindow(); + MultiColorMarkerItem * cmItem = mainWindow->getMultiColorMarkerItem(); + MultiColorMarkerWidget *cmWidget = mainWindow->getMultiColorMarkerWidget(); + int bS = mainWindow->getImageBorderSize(); RectPlotItem *rectPlotItem = controlWidget->getColorPlot()->getMapItem(); - bool useClose = cmWidget->useClose->isChecked(); - bool useOpen = cmWidget->useOpen->isChecked(); - int radiusClose = cmWidget->closeRadius->value(); - int radiusOpen = cmWidget->openRadius->value(); - double dotSize = cmWidget->dotSize->value(); - int minArea = cmWidget->minArea->value(), maxArea = cmWidget->maxArea->value(); - double maxRatio = cmWidget->maxRatio->value(); - bool useBlackDot = cmWidget->useDot->isChecked(); - bool useCodeMarker = cmWidget->useCodeMarker->isChecked(); - bool restrictPosition = cmWidget->restrictPosition->isChecked(); - ignoreWithoutMarker = cmWidget->ignoreWithoutDot->isChecked(); // ueberschreiben von uebergeordnetem ignoreWithoutMarker - bool autoCorrect = cmWidget->autoCorrect->isChecked(); + bool useClose = cmWidget->useClose->isChecked(); + bool useOpen = cmWidget->useOpen->isChecked(); + int radiusClose = cmWidget->closeRadius->value(); + int radiusOpen = cmWidget->openRadius->value(); + double dotSize = cmWidget->dotSize->value(); + int minArea = cmWidget->minArea->value(), maxArea = cmWidget->maxArea->value(); + double maxRatio = cmWidget->maxRatio->value(); + bool useBlackDot = cmWidget->useDot->isChecked(); + bool useCodeMarker = cmWidget->useCodeMarker->isChecked(); + bool restrictPosition = cmWidget->restrictPosition->isChecked(); + ignoreWithoutMarker = + cmWidget->ignoreWithoutDot->isChecked(); // ueberschreiben von uebergeordnetem ignoreWithoutMarker + bool autoCorrect = cmWidget->autoCorrect->isChecked(); bool autoCorrectOnlyExport = cmWidget->autoCorrectOnlyExport->isChecked(); - for (int j = 0; j < rectPlotItem->mapNum(); j++) + for(int j = 0; j < rectPlotItem->mapNum(); j++) { int nr; - if (j == controlWidget->mapNr->value()) - nr = rectPlotItem->mapNum()-1; - else if (j == rectPlotItem->mapNum()-1) + if(j == controlWidget->mapNr->value()) + nr = rectPlotItem->mapNum() - 1; + else if(j == rectPlotItem->mapNum() - 1) nr = controlWidget->mapNr->value(); else nr = j; ColorBlobDetectionParams param; - param.fromColor = rectPlotItem->getMap(nr).fromColor(); - param.toColor = rectPlotItem->getMap(nr).toColor(); - param.invHue = rectPlotItem->getMap(nr).invHue(); - param.minArea = minArea; - param.maxArea = maxArea; - param.maxRatio = maxRatio; - param.useClose = useClose; + param.fromColor = rectPlotItem->getMap(nr).fromColor(); + param.toColor = rectPlotItem->getMap(nr).toColor(); + param.invHue = rectPlotItem->getMap(nr).invHue(); + param.minArea = minArea; + param.maxArea = maxArea; + param.maxRatio = maxRatio; + param.useClose = useClose; param.radiusClose = radiusClose; - param.useOpen = useOpen; - param.radiusOpen = radiusOpen; - param.offset = offset; - param.img = img; - param.binary = cmItem->createMask(img.cols, img.rows); + param.useOpen = useOpen; + param.radiusOpen = radiusOpen; + param.offset = offset; + param.img = img; + param.binary = cmItem->createMask(img.cols, img.rows); auto blobs = findColorBlob(param); - if (useBlackDot) + if(useBlackDot) { ColorParameters colParam; - setColorParameter(rectPlotItem->getMap(nr).fromColor(), rectPlotItem->getMap(nr).toColor(), rectPlotItem->getMap(nr).invHue(), colParam); + setColorParameter( + rectPlotItem->getMap(nr).fromColor(), + rectPlotItem->getMap(nr).toColor(), + rectPlotItem->getMap(nr).invHue(), + colParam); // zentralen farbton heraussuchen QColor midHue; - if (colParam.inversHue) - midHue.setHsv(2*((colParam.h_low+(colParam.h_high-colParam.h_low)/2+90)%180),255,255); + if(colParam.inversHue) + midHue.setHsv(2 * ((colParam.h_low + (colParam.h_high - colParam.h_low) / 2 + 90) % 180), 255, 255); else - midHue.setHsv(2*(colParam.h_low+(colParam.h_high-colParam.h_low)/2),255,255); + midHue.setHsv(2 * (colParam.h_low + (colParam.h_high - colParam.h_low) / 2), 255, 255); BlackDotOptions options; - options.ignoreWithoutMarker = ignoreWithoutMarker; - options.autoCorrect = autoCorrect; + options.ignoreWithoutMarker = ignoreWithoutMarker; + options.autoCorrect = autoCorrect; options.autoCorrectOnlyExport = autoCorrectOnlyExport; - options.restrictPosition = restrictPosition; - options.borderSize = bS; - options.midHue = midHue; - options.dotSize = dotSize; - options.controlWidget = controlWidget; - options.imageItem = mainWindow->getImageItem(); + options.restrictPosition = restrictPosition; + options.borderSize = bS; + options.midHue = midHue; + options.dotSize = dotSize; + options.controlWidget = controlWidget; + options.imageItem = mainWindow->getImageItem(); // adds to crosslist refineWithBlackDot(blobs, img, crossList, options); - }else if (useCodeMarker) + } + else if(useCodeMarker) { ArucoOptions options{ - controlWidget, - ignoreWithoutMarker, - autoCorrect, - autoCorrectOnlyExport, - method, - codeOpt - }; + controlWidget, ignoreWithoutMarker, autoCorrect, autoCorrectOnlyExport, method, codeOpt}; // adds to crosslist refineWithAruco(blobs, img, crossList, options); - }else + } + else { Vec2F moveDir; - for(ColorBlob& blob : blobs) + for(ColorBlob &blob : blobs) { - if (autoCorrect && !autoCorrectOnlyExport) + if(autoCorrect && !autoCorrectOnlyExport) { moveDir = autoCorrectColorMarker(blob.imageCenter, controlWidget); - crossList.append(TrackPoint(Vec2F(blob.box.center.x, blob.box.center.y)+moveDir, 100, Vec2F(blob.box.center.x, blob.box.center.y), blob.color)); // 100 beste qualitaet + crossList.append(TrackPoint( + Vec2F(blob.box.center.x, blob.box.center.y) + moveDir, + 100, + Vec2F(blob.box.center.x, blob.box.center.y), + blob.color)); // 100 beste qualitaet } else { - crossList.append(TrackPoint(Vec2F(blob.box.center.x, blob.box.center.y), 100, Vec2F(blob.box.center.x, blob.box.center.y), blob.color)); // 100 beste qualitaet + crossList.append(TrackPoint( + Vec2F(blob.box.center.x, blob.box.center.y), + 100, + Vec2F(blob.box.center.x, blob.box.center.y), + blob.color)); // 100 beste qualitaet } } } @@ -771,84 +864,93 @@ void findMultiColorMarker(cv::Mat &img, QList<TrackPoint> &crossList, Control *c */ void findColorMarker(cv::Mat &img, QList<TrackPoint> &crossList, Control *controlWidget) { - ColorParameters param; - ColorMarkerItem* cmItem = controlWidget->getMainWindow()->getColorMarkerItem(); - ColorMarkerWidget* cmWidget = controlWidget->getMainWindow()->getColorMarkerWidget(); + ColorParameters param; + ColorMarkerItem * cmItem = controlWidget->getMainWindow()->getColorMarkerItem(); + ColorMarkerWidget *cmWidget = controlWidget->getMainWindow()->getColorMarkerWidget(); QColor fromColor = cmWidget->fromColor->palette().color(QPalette::Button); - QColor toColor = cmWidget->toColor->palette().color(QPalette::Button); + QColor toColor = cmWidget->toColor->palette().color(QPalette::Button); setColorParameter(fromColor, toColor, cmWidget->inversHue->isChecked(), param); // run detection - cv::Mat binary; + cv::Mat binary; // erzeuge speicherplatz fuer mask // abfrage wird in createMask gemacht - //if (cmItem->getMask() == NULL || (cmItem->getMask() != NULL && (cmItem->getMask()->width != img->width || cmItem->getMask()->height != img->height))) + // if (cmItem->getMask() == NULL || (cmItem->getMask() != NULL && (cmItem->getMask()->width != img->width || + // cmItem->getMask()->height != img->height))) binary = cmItem->createMask(img.cols, img.rows); // erzeugt binary mask mit groesse von img // color thresholding - thresholdHSV(img , binary, param); + thresholdHSV(img, binary, param); // close small holes: radius ( hole ) < radius ( close ) - if (cmWidget->useClose->isChecked()) + if(cmWidget->useClose->isChecked()) { int radius_close = cmWidget->closeRadius->value(); // siehe : http://opencv.willowgarage.com/documentation/c/image_filtering.html#createstructuringelementex - cv::morphologyEx(binary,binary,cv::MORPH_OPEN, - getStructuringElement( cv::MORPH_ELLIPSE, - cv::Size(2*radius_close+1,2*radius_close+1), - cv::Point(radius_close,radius_close))); + cv::morphologyEx( + binary, + binary, + cv::MORPH_OPEN, + getStructuringElement( + cv::MORPH_ELLIPSE, + cv::Size(2 * radius_close + 1, 2 * radius_close + 1), + cv::Point(radius_close, radius_close))); } // remove small blobs: radius ( blob ) < radius ( open ) - if (cmWidget->useOpen->isChecked()) + if(cmWidget->useOpen->isChecked()) { - int radius_open = cmWidget->openRadius->value(); - cv::morphologyEx(binary,binary,cv::MORPH_CLOSE, - getStructuringElement( cv::MORPH_ELLIPSE, - cv::Size(2*radius_open+1,2*radius_open+1), - cv::Point(radius_open))); + int radius_open = cmWidget->openRadius->value(); + cv::morphologyEx( + binary, + binary, + cv::MORPH_CLOSE, + getStructuringElement( + cv::MORPH_ELLIPSE, cv::Size(2 * radius_open + 1, 2 * radius_open + 1), cv::Point(radius_open))); } - std::vector<std::vector<cv::Point> > contours; - double area; - QColor col; - cv::RotatedRect box; - double ratio; - bool atEdge; + std::vector<std::vector<cv::Point>> contours; + double area; + QColor col; + cv::RotatedRect box; + double ratio; + bool atEdge; - cv::Mat clone = binary.clone();//(cvarrToMat(binary),true); + cv::Mat clone = binary.clone(); //(cvarrToMat(binary),true); - cv::findContours(clone,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE); + cv::findContours(clone, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // test each contour - while (!contours.empty()) + while(!contours.empty()) { std::vector<cv::Point> contour = contours.back(); - area = cv::contourArea(contour); - box = cv::minAreaRect(contour); + area = cv::contourArea(contour); + box = cv::minAreaRect(contour); - if (box.size.height > box.size.width) + if(box.size.height > box.size.width) { - ratio = box.size.height/box.size.width; + ratio = box.size.height / box.size.width; } else { - ratio = box.size.width/box.size.height; + ratio = box.size.width / box.size.height; } // contour at border of roi, than neglect because of object going out of region has moving center atEdge = false; - for(size_t i=0; i<contour.size(); i++) - if ((contour.at(i).x <= 1) || (contour.at(i).x >= img.cols-2) || - (contour.at(i).y <= 1) || (contour.at(i).y >= img.rows-2)) + for(size_t i = 0; i < contour.size(); i++) + if((contour.at(i).x <= 1) || (contour.at(i).x >= img.cols - 2) || (contour.at(i).y <= 1) || + (contour.at(i).y >= img.rows - 2)) atEdge = true; - if (!atEdge && area >= cmWidget->minArea->value() && area <= cmWidget->maxArea->value() && ratio <= cmWidget->maxRatio->value()) + if(!atEdge && area >= cmWidget->minArea->value() && area <= cmWidget->maxArea->value() && + ratio <= cmWidget->maxRatio->value()) { // eine mittelung waere ggf sinnvoll, aber am rand aufpassen - col.setRgb(getValue(img,myRound(box.center.x),myRound(box.center.y)).rgb()); - crossList.append(TrackPoint(Vec2F(box.center.x, box.center.y), 100, Vec2F(box.center.x, box.center.y), col)); // 100 beste qualitaet + col.setRgb(getValue(img, myRound(box.center.x), myRound(box.center.y)).rgb()); + crossList.append(TrackPoint( + Vec2F(box.center.x, box.center.y), 100, Vec2F(box.center.x, box.center.y), col)); // 100 beste qualitaet } // take the next contour @@ -862,81 +964,100 @@ void findColorMarker(cv::Mat &img, QList<TrackPoint> &crossList, Control *contro * @param crossList[out] list of detected TrackPoints * @param controlWidget */ -void detail::findCodeMarker(cv::Mat &img, QList<TrackPoint> &crossList, RecognitionMethod recoMethod, const CodeMarkerOptions& opt) +void detail::findCodeMarker( + cv::Mat & img, + QList<TrackPoint> & crossList, + RecognitionMethod recoMethod, + const CodeMarkerOptions &opt) { CodeMarkerItem *codeMarkerItem = opt.getCodeMarkerItem(); - Control *controlWidget = opt.getControlWidget(); - const auto& par = opt.getDetectorParams(); + Control * controlWidget = opt.getControlWidget(); + const auto & par = opt.getDetectorParams(); - cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::PREDEFINED_DICTIONARY_NAME(opt.getIndexOfMarkerDict())); + cv::Ptr<cv::aruco::Dictionary> dictionary = + cv::aruco::getPredefinedDictionary(cv::aruco::PREDEFINED_DICTIONARY_NAME(opt.getIndexOfMarkerDict())); - if (opt.getIndexOfMarkerDict() == 17) //for usage of DICT_mip_36h12 as it is not predifined in opencv + if(opt.getIndexOfMarkerDict() == 17) // for usage of DICT_mip_36h12 as it is not predifined in opencv { dictionary = detail::getDictMip36h12(); } cv::Ptr<cv::aruco::DetectorParameters> detectorParams = cv::aruco::DetectorParameters::create(); - double minMarkerPerimeterRate = 0.03, maxMarkerPerimeterRate = 4, minCornerDistanceRate = 0.05, minMarkerDistanceRate = 0.05; + double minMarkerPerimeterRate = 0.03, maxMarkerPerimeterRate = 4, minCornerDistanceRate = 0.05, + minMarkerDistanceRate = 0.05; Petrack *mainWindow = controlWidget->getMainWindow(); int bS = mainWindow->getImageBorderSize(); - if (controlWidget->getCalibCoordDimension() == 0) // 3D + if(controlWidget->getCalibCoordDimension() == 0) // 3D { - QRect rect(myRound(mainWindow->getRecoRoiItem()->rect().x()), - myRound(mainWindow->getRecoRoiItem()->rect().y()), - myRound(mainWindow->getRecoRoiItem()->rect().width()), - myRound(mainWindow->getRecoRoiItem()->rect().height())); - QPointF p1 = mainWindow->getImageItem()->getCmPerPixel(rect.x(),rect.y(),controlWidget->mapDefaultHeight->value()), - p2 = mainWindow->getImageItem()->getCmPerPixel(rect.x()+rect.width(),rect.y(),controlWidget->mapDefaultHeight->value()), - p3 = mainWindow->getImageItem()->getCmPerPixel(rect.x(),rect.y()+rect.height(),controlWidget->mapDefaultHeight->value()), - p4 = mainWindow->getImageItem()->getCmPerPixel(rect.x()+rect.width(),rect.y()+rect.height(),controlWidget->mapDefaultHeight->value()); - - double cmPerPixel_min = std::min(std::min(std::min(p1.x(), p1.y()), std::min(p2.x(), p2.y())), - std::min(std::min(p3.x(), p3.y()), std::min(p4.x(), p4.y()))); - double cmPerPixel_max = std::max(std::max(std::max(p1.x(), p1.y()), std::max(p2.x(), p2.y())), - std::max(std::max(p3.x(), p3.y()), std::max(p4.x(), p4.y()))); - - if (recoMethod == RecognitionMethod::Code) // for usage of codemarker with CodeMarker-function (-> without MulticolorMarker) + QRect rect( + myRound(mainWindow->getRecoRoiItem()->rect().x()), + myRound(mainWindow->getRecoRoiItem()->rect().y()), + myRound(mainWindow->getRecoRoiItem()->rect().width()), + myRound(mainWindow->getRecoRoiItem()->rect().height())); + QPointF p1 = mainWindow->getImageItem()->getCmPerPixel( + rect.x(), rect.y(), controlWidget->mapDefaultHeight->value()), + p2 = mainWindow->getImageItem()->getCmPerPixel( + rect.x() + rect.width(), rect.y(), controlWidget->mapDefaultHeight->value()), + p3 = mainWindow->getImageItem()->getCmPerPixel( + rect.x(), rect.y() + rect.height(), controlWidget->mapDefaultHeight->value()), + p4 = mainWindow->getImageItem()->getCmPerPixel( + rect.x() + rect.width(), rect.y() + rect.height(), controlWidget->mapDefaultHeight->value()); + + double cmPerPixel_min = std::min( + std::min(std::min(p1.x(), p1.y()), std::min(p2.x(), p2.y())), + std::min(std::min(p3.x(), p3.y()), std::min(p4.x(), p4.y()))); + double cmPerPixel_max = std::max( + std::max(std::max(p1.x(), p1.y()), std::max(p2.x(), p2.y())), + std::max(std::max(p3.x(), p3.y()), std::max(p4.x(), p4.y()))); + + if(recoMethod == + RecognitionMethod::Code) // for usage of codemarker with CodeMarker-function (-> without MulticolorMarker) { - minMarkerPerimeterRate = (par.getMinMarkerPerimeter()*4./cmPerPixel_max)/std::max(rect.width(),rect.height()); - maxMarkerPerimeterRate = (par.getMaxMarkerPerimeter()*4./cmPerPixel_min)/std::max(rect.width(),rect.height()); - } else if (recoMethod == RecognitionMethod::MultiColor) // for usage of codemarker with MulticolorMarker + minMarkerPerimeterRate = + (par.getMinMarkerPerimeter() * 4. / cmPerPixel_max) / std::max(rect.width(), rect.height()); + maxMarkerPerimeterRate = + (par.getMaxMarkerPerimeter() * 4. / cmPerPixel_min) / std::max(rect.width(), rect.height()); + } + else if(recoMethod == RecognitionMethod::MultiColor) // for usage of codemarker with MulticolorMarker { - minMarkerPerimeterRate = (par.getMinMarkerPerimeter()*4./cmPerPixel_max)/std::max(img.cols,img.rows); - maxMarkerPerimeterRate = (par.getMaxMarkerPerimeter()*4./cmPerPixel_min)/std::max(img.cols,img.rows); + minMarkerPerimeterRate = (par.getMinMarkerPerimeter() * 4. / cmPerPixel_max) / std::max(img.cols, img.rows); + maxMarkerPerimeterRate = (par.getMaxMarkerPerimeter() * 4. / cmPerPixel_min) / std::max(img.cols, img.rows); } minCornerDistanceRate = par.getMinCornerDistance(); minMarkerDistanceRate = par.getMinMarkerDistance(); - } else // 2D { - double cmPerPixel = mainWindow->getImageItem()->getCmPerPixel(); - minMarkerPerimeterRate = (par.getMinMarkerPerimeter()*4/cmPerPixel)/std::max(mainWindow->getImage()->width()-bS,mainWindow->getImage()->height()-bS); - maxMarkerPerimeterRate = (par.getMaxMarkerPerimeter()*4/cmPerPixel)/std::max(mainWindow->getImage()->width()-bS,mainWindow->getImage()->height()-bS); + double cmPerPixel = mainWindow->getImageItem()->getCmPerPixel(); + minMarkerPerimeterRate = (par.getMinMarkerPerimeter() * 4 / cmPerPixel) / + std::max(mainWindow->getImage()->width() - bS, mainWindow->getImage()->height() - bS); + maxMarkerPerimeterRate = (par.getMaxMarkerPerimeter() * 4 / cmPerPixel) / + std::max(mainWindow->getImage()->width() - bS, mainWindow->getImage()->height() - bS); minCornerDistanceRate = par.getMinCornerDistance(); minMarkerDistanceRate = par.getMinMarkerDistance(); } - detectorParams->adaptiveThreshWinSizeMin = par.getAdaptiveThreshWinSizeMin(); - detectorParams->adaptiveThreshWinSizeMax = par.getAdaptiveThreshWinSizeMax(); - detectorParams->adaptiveThreshWinSizeStep = par.getAdaptiveThreshWinSizeStep(); - detectorParams->adaptiveThreshConstant = par.getAdaptiveThreshConstant(); - detectorParams->minMarkerPerimeterRate = minMarkerPerimeterRate; - detectorParams->maxMarkerPerimeterRate = maxMarkerPerimeterRate; - detectorParams->polygonalApproxAccuracyRate = par.getPolygonalApproxAccuracyRate(); - detectorParams->minCornerDistanceRate = minCornerDistanceRate; - detectorParams->minDistanceToBorder = par.getMinDistanceToBorder(); - detectorParams->minMarkerDistanceRate = minMarkerDistanceRate; + detectorParams->adaptiveThreshWinSizeMin = par.getAdaptiveThreshWinSizeMin(); + detectorParams->adaptiveThreshWinSizeMax = par.getAdaptiveThreshWinSizeMax(); + detectorParams->adaptiveThreshWinSizeStep = par.getAdaptiveThreshWinSizeStep(); + detectorParams->adaptiveThreshConstant = par.getAdaptiveThreshConstant(); + detectorParams->minMarkerPerimeterRate = minMarkerPerimeterRate; + detectorParams->maxMarkerPerimeterRate = maxMarkerPerimeterRate; + detectorParams->polygonalApproxAccuracyRate = par.getPolygonalApproxAccuracyRate(); + detectorParams->minCornerDistanceRate = minCornerDistanceRate; + detectorParams->minDistanceToBorder = par.getMinDistanceToBorder(); + detectorParams->minMarkerDistanceRate = minMarkerDistanceRate; // No refinement is default value // TODO Check if this is the best MEthod for our usecase - if(par.getDoCornerRefinement()){ - detectorParams->cornerRefinementMethod = cv::aruco::CornerRefineMethod::CORNER_REFINE_SUBPIX; + if(par.getDoCornerRefinement()) + { + detectorParams->cornerRefinementMethod = cv::aruco::CornerRefineMethod::CORNER_REFINE_SUBPIX; } detectorParams->cornerRefinementWinSize = par.getCornerRefinementWinSize(); detectorParams->cornerRefinementMaxIterations = par.getCornerRefinementMaxIterations(); @@ -948,126 +1069,145 @@ void detail::findCodeMarker(cv::Mat &img, QList<TrackPoint> &crossList, Recognit detectorParams->minOtsuStdDev = par.getMinOtsuStdDev(); detectorParams->errorCorrectionRate = par.getErrorCorrectionRate(); - std::vector<int> ids; - std::vector<std::vector<cv::Point2f> > corners, rejected; + std::vector<int> ids; + std::vector<std::vector<cv::Point2f>> corners, rejected; ids.clear(); corners.clear(); rejected.clear(); cv::aruco::detectMarkers(img, dictionary, corners, ids, detectorParams, rejected); - codeMarkerItem->addDetectedMarkers(corners,ids, opt.getOffsetCropRect2Roi()); + codeMarkerItem->addDetectedMarkers(corners, ids, opt.getOffsetCropRect2Roi()); codeMarkerItem->addRejectedMarkers(rejected, opt.getOffsetCropRect2Roi()); // detected code markers - for(size_t i = 0; i<ids.size(); i++) + for(size_t i = 0; i < ids.size(); i++) { - double x = (corners.at(i).at(0).x+corners.at(i).at(1).x+corners.at(i).at(2).x+corners.at(i).at(3).x)*0.25; - double y = (corners.at(i).at(0).y+corners.at(i).at(1).y+corners.at(i).at(2).y+corners.at(i).at(3).y)*0.25; + double x = + (corners.at(i).at(0).x + corners.at(i).at(1).x + corners.at(i).at(2).x + corners.at(i).at(3).x) * 0.25; + double y = + (corners.at(i).at(0).y + corners.at(i).at(1).y + corners.at(i).at(2).y + corners.at(i).at(3).y) * 0.25; - crossList.append(TrackPoint(Vec2F(x,y), 100, ids.at(i))); // 100 beste qualitaet + crossList.append(TrackPoint(Vec2F(x, y), 100, ids.at(i))); // 100 beste qualitaet } } -void findContourMarker(cv::Mat &img, QList<TrackPoint> *crossList, int markerBrightness, bool ignoreWithoutMarker, bool autoWB, RecognitionMethod recoMethod, float headSize) +void findContourMarker( + cv::Mat & img, + QList<TrackPoint> *crossList, + int markerBrightness, + bool ignoreWithoutMarker, + bool autoWB, + RecognitionMethod recoMethod, + float headSize) { - int threshold, plus; - size_t count; - double angle; - MarkerHermesList markerHermesList; - MarkerCasernList markerCasernList; - MarkerJapanList markerJapanList(headSize); - cv::Size sz = cv::Size(img.cols & -2, img.rows & -2); - cv::Mat gray = cv::Mat(sz,CV_8UC1); - cv::Mat tgray; - cv::Mat grayFix; - std::vector<std::vector<cv::Point> > contours; + int threshold, plus; + size_t count; + double angle; + MarkerHermesList markerHermesList; + MarkerCasernList markerCasernList; + MarkerJapanList markerJapanList(headSize); + cv::Size sz = cv::Size(img.cols & -2, img.rows & -2); + cv::Mat gray = cv::Mat(sz, CV_8UC1); + cv::Mat tgray; + cv::Mat grayFix; + std::vector<std::vector<cv::Point>> contours; cv::RotatedRect box; - int expansion; - double contourArea; + int expansion; + double contourArea; - if (img.channels() == 3) + if(img.channels() == 3) { - tgray = cv::Mat(sz,CV_8UC1);//cvCreateImage(sz, 8, 1); - cv::cvtColor(img,tgray,cv::COLOR_RGB2GRAY); + tgray = cv::Mat(sz, CV_8UC1); // cvCreateImage(sz, 8, 1); + cv::cvtColor(img, tgray, cv::COLOR_RGB2GRAY); } // try several threshold levels - plus = (250-72)/10; + plus = (250 - 72) / 10; // andere richtung der schwellwertanpassung koennte andere ergebnisse leifern // cw->markerBrightness->value()==markerBrightness hat default 50 - for (threshold = 60+markerBrightness; threshold < 251 ; threshold += plus) //70..255, 20 //155+cw->temp2->value() + for(threshold = 60 + markerBrightness; threshold < 251; threshold += plus) // 70..255, 20 //155+cw->temp2->value() { - if (img.channels() == 3) + if(img.channels() == 3) { - cv::threshold(tgray,gray,threshold, 255, cv::THRESH_BINARY); + cv::threshold(tgray, gray, threshold, 255, cv::THRESH_BINARY); } - else if (img.channels() == 1) - cv::threshold(img,gray,threshold,255, cv::THRESH_BINARY);//cvThreshold(img, gray, threshold, 255, CV_THRESH_BINARY); + else if(img.channels() == 1) + cv::threshold( + img, + gray, + threshold, + 255, + cv::THRESH_BINARY); // cvThreshold(img, gray, threshold, 255, CV_THRESH_BINARY); else - debout << "Error: Wrong number of channels: " << img.channels() <<std::endl; + debout << "Error: Wrong number of channels: " << img.channels() << std::endl; grayFix = gray.clone(); // find contours and store them all as a list - findContours(gray,contours,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE); + findContours(gray, contours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE); // test each contour - while (!contours.empty()) + while(!contours.empty()) { std::vector<cv::Point> contour = contours.back(); - //koennten auch interessant sein: - //MinAreaRect2 - //MinEnclosingCircle - // um kreise zu suchen koennte auch cvHoughCircles genutzt werden + // koennten auch interessant sein: + // MinAreaRect2 + // MinEnclosingCircle + // um kreise zu suchen koennte auch cvHoughCircles genutzt werden count = contour.size(); // man koennte das Seitenverhaeltnis, contour-gesamtlaenge vorher ueberpruefen, um cont rauszuwerfen - if (count > 5) + if(count > 5) { // Fits ellipse to current contour. cv::Mat pointsf; cv::Mat(contour).convertTo(pointsf, CV_32F); box = fitEllipse(pointsf); - expansion = box.size.width > box.size.height ? myRound(box.size.width*0.5) : myRound(box.size.height*0.5); + expansion = + box.size.width > box.size.height ? myRound(box.size.width * 0.5) : myRound(box.size.height * 0.5); - if (box.center.x-expansion > ELLIPSE_DISTANCE_TO_BORDER && box.center.x+expansion < gray.cols-ELLIPSE_DISTANCE_TO_BORDER && - box.center.y-expansion > ELLIPSE_DISTANCE_TO_BORDER && box.center.y+expansion < gray.rows-ELLIPSE_DISTANCE_TO_BORDER) + if(box.center.x - expansion > ELLIPSE_DISTANCE_TO_BORDER && + box.center.x + expansion < gray.cols - ELLIPSE_DISTANCE_TO_BORDER && + box.center.y - expansion > ELLIPSE_DISTANCE_TO_BORDER && + box.center.y + expansion < gray.rows - ELLIPSE_DISTANCE_TO_BORDER) { - angle = (box.angle)/180.*PI; - if (box.size.width<box.size.height) { - angle -= PI / 2; + angle = (box.angle) / 180. * PI; + if(box.size.width < box.size.height) + { + angle -= PI / 2; } - contourArea = cv::contourArea(contour,true); + contourArea = cv::contourArea(contour, true); - //contourArea koennte mit MyEllipse.area() verglichen werden und bei grossen abweichungen verworfen werden!!! - MyEllipse e(box.center.x, box.center.y, box.size.width*0.5, box.size.height*0.5, angle); - if (recoMethod == RecognitionMethod::Casern) // Casern + // contourArea koennte mit MyEllipse.area() verglichen werden und bei grossen abweichungen verworfen + // werden!!! + MyEllipse e(box.center.x, box.center.y, box.size.width * 0.5, box.size.height * 0.5, angle); + if(recoMethod == RecognitionMethod::Casern) // Casern markerCasernList.mayAddEllipse(grayFix, e, (contourArea > 0)); - else if (recoMethod == RecognitionMethod::Hermes) // Hermes + else if(recoMethod == RecognitionMethod::Hermes) // Hermes markerHermesList.mayAddEllipse(grayFix, e, (contourArea > 0)); - else if (recoMethod == RecognitionMethod::Japan) // Japan + else if(recoMethod == RecognitionMethod::Japan) // Japan markerJapanList.mayAddEllipse(grayFix, e, (contourArea > 0)); } } contours.pop_back(); } } - if (recoMethod == RecognitionMethod::Casern) // Casern + if(recoMethod == RecognitionMethod::Casern) // Casern { markerCasernList.organize(img, autoWB); markerCasernList.toCrossList(crossList, ignoreWithoutMarker); } - else if (recoMethod == RecognitionMethod::Hermes) // Hermes + else if(recoMethod == RecognitionMethod::Hermes) // Hermes { markerHermesList.organize(img, autoWB); markerHermesList.toCrossList(crossList, ignoreWithoutMarker); } - else if (recoMethod == RecognitionMethod::Japan) // Japan + else if(recoMethod == RecognitionMethod::Japan) // Japan { markerJapanList.organize(img, autoWB); markerJapanList.toCrossList(crossList, ignoreWithoutMarker); @@ -1086,26 +1226,34 @@ void findContourMarker(cv::Mat &img, QList<TrackPoint> *crossList, int markerBri * * @return List of detected TrackPoints */ -QList<TrackPoint> Recognizer::getMarkerPos(cv::Mat &img, QRect &roi, Control *controlWidget, int borderSize, BackgroundFilter *bgFilter) +QList<TrackPoint> +Recognizer::getMarkerPos(cv::Mat &img, QRect &roi, Control *controlWidget, int borderSize, BackgroundFilter *bgFilter) { - int markerBrightness = controlWidget->markerBrightness->value(); + int markerBrightness = controlWidget->markerBrightness->value(); bool ignoreWithoutMarker = (controlWidget->markerIgnoreWithout->checkState() == Qt::Checked); - bool autoWB = (controlWidget->recoAutoWB->checkState() == Qt::Checked); + bool autoWB = (controlWidget->recoAutoWB->checkState() == Qt::Checked); - cv::Mat tImg; + cv::Mat tImg; cv::Rect rect; - tImg = getRoi(img, roi, rect, !((mRecoMethod == RecognitionMethod::Color) || (mRecoMethod == RecognitionMethod::MultiColor) || (mRecoMethod == RecognitionMethod::Code))); - - if (tImg.empty()) + tImg = getRoi( + img, + roi, + rect, + !((mRecoMethod == RecognitionMethod::Color) || (mRecoMethod == RecognitionMethod::MultiColor) || + (mRecoMethod == RecognitionMethod::Code))); + + if(tImg.empty()) return QList<TrackPoint>{}; QList<TrackPoint> crossList; // offset of rect - Vec2F v(rect.x-borderSize, rect.y-borderSize); + Vec2F v(rect.x - borderSize, rect.y - borderSize); - switch (mRecoMethod) { + switch(mRecoMethod) + { case RecognitionMethod::MultiColor: - findMultiColorMarker(tImg, crossList, controlWidget, ignoreWithoutMarker, v, mRecoMethod, mCodeMarkerOptions); + findMultiColorMarker( + tImg, crossList, controlWidget, ignoreWithoutMarker, v, mRecoMethod, mCodeMarkerOptions); break; case RecognitionMethod::Color: findColorMarker(tImg, crossList, controlWidget); @@ -1113,13 +1261,23 @@ QList<TrackPoint> Recognizer::getMarkerPos(cv::Mat &img, QRect &roi, Control *co case RecognitionMethod::Code: findCodeMarker(tImg, crossList, mRecoMethod, mCodeMarkerOptions); break; - case RecognitionMethod::Casern: [[fallthrough]]; - case RecognitionMethod::Hermes: [[fallthrough]]; + case RecognitionMethod::Casern: + [[fallthrough]]; + case RecognitionMethod::Hermes: + [[fallthrough]]; case RecognitionMethod::Japan: - findContourMarker(tImg, &crossList, markerBrightness, ignoreWithoutMarker, autoWB, mRecoMethod, controlWidget->getMainWindow()->getHeadSize()); + findContourMarker( + tImg, + &crossList, + markerBrightness, + ignoreWithoutMarker, + autoWB, + mRecoMethod, + controlWidget->getMainWindow()->getHeadSize()); break; case RecognitionMethod::Stereo: - throw std::invalid_argument("Stereo marker are not handled in getMarkerPos, but in PersonList::calcPersonPos"); + throw std::invalid_argument( + "Stereo marker are not handled in getMarkerPos, but in PersonList::calcPersonPos"); } // must be set because else hovermoveevent of recognitionRec moves also the colorMaskItem @@ -1130,17 +1288,19 @@ QList<TrackPoint> Recognizer::getMarkerPos(cv::Mat &img, QRect &roi, Control *co controlWidget->getMainWindow()->getCodeMarkerItem()->setRect(v); // set cross position relative to original image size - for (auto& point : crossList){ + for(auto &point : crossList) + { point += v; point.setColPoint(point.colPoint() + v); } - if (bgFilter->getEnabled()) // nur fuer den fall von bgSubtraction durchfuehren + if(bgFilter->getEnabled()) // nur fuer den fall von bgSubtraction durchfuehren { crossList.erase( - std::remove_if(crossList.begin(), crossList.end(), [bgFilter](TrackPoint& tp){ - return !bgFilter->isForeground(tp.x(), tp.y()); - }), + std::remove_if( + crossList.begin(), + crossList.end(), + [bgFilter](TrackPoint &tp) { return !bgFilter->isForeground(tp.x(), tp.y()); }), crossList.end()); } @@ -1159,7 +1319,8 @@ void CodeMarkerOptions::setOffsetCropRect2Roi(const Vec2F &newOffsetCropRect2Roi void CodeMarkerOptions::setDetectorParams(ArucoCodeParams params) { - if(params != detectorParams){ + if(params != detectorParams) + { detectorParams = params; emit detectorParamsChanged(); } @@ -1167,7 +1328,8 @@ void CodeMarkerOptions::setDetectorParams(ArucoCodeParams params) void CodeMarkerOptions::setIndexOfMarkerDict(int idx) { - if(idx != indexOfMarkerDict){ + if(idx != indexOfMarkerDict) + { indexOfMarkerDict = idx; emit indexOfMarkerDictChanged(); } @@ -1183,23 +1345,59 @@ void CodeMarkerOptions::setIndexOfMarkerDict(int idx) */ cv::Ptr<cv::aruco::Dictionary> detail::getDictMip36h12() { - std::array<uint64_t, 250> bitListDictMip36h12 {0xd2b63a09dUL,0x6001134e5UL,0x1206fbe72UL,0xff8ad6cb4UL,0x85da9bc49UL,0xb461afe9cUL,0x6db51fe13UL,0x5248c541fUL,0x8f34503UL,0x8ea462eceUL,0xeac2be76dUL,0x1af615c44UL,0xb48a49f27UL,0x2e4e1283bUL,0x78b1f2fa8UL,0x27d34f57eUL,0x89222fff1UL,0x4c1669406UL,0xbf49b3511UL,0xdc191cd5dUL,0x11d7c3f85UL,0x16a130e35UL,0xe29f27effUL,0x428d8ae0cUL,0x90d548477UL,0x2319cbc93UL,0xc3b0c3dfcUL,0x424bccc9UL,0x2a081d630UL,0x762743d96UL,0xd0645bf19UL,0xf38d7fd60UL,0xc6cbf9a10UL,0x3c1be7c65UL,0x276f75e63UL,0x4490a3f63UL,0xda60acd52UL,0x3cc68df59UL,0xab46f9daeUL,0x88d533d78UL,0xb6d62ec21UL,0xb3c02b646UL,0x22e56d408UL,0xac5f5770aUL,0xaaa993f66UL,0x4caa07c8dUL,0x5c9b4f7b0UL,0xaa9ef0e05UL,0x705c5750UL,0xac81f545eUL,0x735b91e74UL,0x8cc35cee4UL,0xe44694d04UL,0xb5e121de0UL,0x261017d0fUL,0xf1d439eb5UL,0xa1a33ac96UL,0x174c62c02UL,0x1ee27f716UL,0x8b1c5ece9UL,0x6a05b0c6aUL,0xd0568dfcUL,0x192d25e5fUL,0x1adbeccc8UL,0xcfec87f00UL,0xd0b9dde7aUL,0x88dcef81eUL,0x445681cb9UL,0xdbb2ffc83UL,0xa48d96df1UL,0xb72cc2e7dUL,0xc295b53fUL,0xf49832704UL,0x9968edc29UL,0x9e4e1af85UL,0x8683e2d1bUL,0x810b45c04UL,0x6ac44bfe2UL,0x645346615UL,0x3990bd598UL,0x1c9ed0f6aUL,0xc26729d65UL,0x83993f795UL,0x3ac05ac5dUL,0x357adff3bUL,0xd5c05565UL,0x2f547ef44UL,0x86c115041UL,0x640fd9e5fUL,0xce08bbcf7UL,0x109bb343eUL,0xc21435c92UL,0x35b4dfce4UL,0x459752cf2UL,0xec915b82cUL,0x51881eed0UL,0x2dda7dc97UL,0x2e0142144UL,0x42e890f99UL,0x9a8856527UL,0x8e80d9d80UL,0x891cbcf34UL,0x25dd82410UL,0x239551d34UL,0x8fe8f0c70UL,0x94106a970UL,0x82609b40cUL,0xfc9caf36UL,0x688181d11UL,0x718613c08UL,0xf1ab7629UL,0xa357bfc18UL,0x4c03b7a46UL,0x204dedce6UL,0xad6300d37UL,0x84cc4cd09UL,0x42160e5c4UL,0x87d2adfa8UL,0x7850e7749UL,0x4e750fc7cUL,0xbf2e5dfdaUL,0xd88324da5UL,0x234b52f80UL,0x378204514UL,0xabdf2ad53UL,0x365e78ef9UL,0x49caa6ca2UL,0x3c39ddf3UL,0xc68c5385dUL,0x5bfcbbf67UL,0x623241e21UL,0xabc90d5ccUL,0x388c6fe85UL,0xda0e2d62dUL,0x10855dfe9UL,0x4d46efd6bUL,0x76ea12d61UL,0x9db377d3dUL,0xeed0efa71UL,0xe6ec3ae2fUL,0x441faee83UL,0xba19c8ff5UL,0x313035eabUL,0x6ce8f7625UL,0x880dab58dUL,0x8d3409e0dUL,0x2be92ee21UL,0xd60302c6cUL,0x469ffc724UL,0x87eebeed3UL,0x42587ef7aUL,0x7a8cc4e52UL,0x76a437650UL,0x999e41ef4UL,0x7d0969e42UL,0xc02baf46bUL,0x9259f3e47UL,0x2116a1dc0UL,0x9f2de4d84UL,0xeffac29UL,0x7b371ff8cUL,0x668339da9UL,0xd010aee3fUL,0x1cd00b4c0UL,0x95070fc3bUL,0xf84c9a770UL,0x38f863d76UL,0x3646ff045UL,0xce1b96412UL,0x7a5d45da8UL,0x14e00ef6cUL,0x5e95abfd8UL,0xb2e9cb729UL,0x36c47dd7UL,0xb8ee97c6bUL,0xe9e8f657UL,0xd4ad2ef1aUL,0x8811c7f32UL,0x47bde7c31UL,0x3adadfb64UL,0x6e5b28574UL,0x33e67cd91UL,0x2ab9fdd2dUL,0x8afa67f2bUL,0xe6a28fc5eUL,0x72049cdbdUL,0xae65dac12UL,0x1251a4526UL,0x1089ab841UL,0xe2f096ee0UL,0xb0caee573UL,0xfd6677e86UL,0x444b3f518UL,0xbe8b3a56aUL,0x680a75cfcUL,0xac02baea8UL,0x97d815e1cUL,0x1d4386e08UL,0x1a14f5b0eUL,0xe658a8d81UL,0xa3868efa7UL,0x3668a9673UL,0xe8fc53d85UL,0x2e2b7edd5UL,0x8b2470f13UL,0xf69795f32UL,0x4589ffc8eUL,0x2e2080c9cUL,0x64265f7dUL,0x3d714dd10UL,0x1692c6ef1UL,0x3e67f2f49UL,0x5041dad63UL,0x1a1503415UL,0x64c18c742UL,0xa72eec35UL,0x1f0f9dc60UL,0xa9559bc67UL,0xf32911d0dUL,0x21c0d4ffcUL,0xe01cef5b0UL,0x4e23a3520UL,0xaa4f04e49UL,0xe1c4fcc43UL,0x208e8f6e8UL,0x8486774a5UL,0x9e98c7558UL,0x2c59fb7dcUL,0x9446a4613UL,0x8292dcc2eUL,0x4d61631UL,0xd05527809UL,0xa0163852dUL,0x8f657f639UL,0xcca6c3e37UL,0xcb136bc7aUL,0xfc5a83e53UL,0x9aa44fc30UL,0xbdec1bd3cUL,0xe020b9f7cUL,0x4b8f35fb0UL,0xb8165f637UL,0x33dc88d69UL,0x10a2f7e4dUL,0xc8cb5ff53UL,0xde259ff6bUL,0x46d070dd4UL,0x32d3b9741UL,0x7075f1c04UL,0x4d58dbea0UL}; - - int markerSize = 6; + std::array<uint64_t, 250> bitListDictMip36h12{ + 0xd2b63a09dUL, 0x6001134e5UL, 0x1206fbe72UL, 0xff8ad6cb4UL, 0x85da9bc49UL, 0xb461afe9cUL, 0x6db51fe13UL, + 0x5248c541fUL, 0x8f34503UL, 0x8ea462eceUL, 0xeac2be76dUL, 0x1af615c44UL, 0xb48a49f27UL, 0x2e4e1283bUL, + 0x78b1f2fa8UL, 0x27d34f57eUL, 0x89222fff1UL, 0x4c1669406UL, 0xbf49b3511UL, 0xdc191cd5dUL, 0x11d7c3f85UL, + 0x16a130e35UL, 0xe29f27effUL, 0x428d8ae0cUL, 0x90d548477UL, 0x2319cbc93UL, 0xc3b0c3dfcUL, 0x424bccc9UL, + 0x2a081d630UL, 0x762743d96UL, 0xd0645bf19UL, 0xf38d7fd60UL, 0xc6cbf9a10UL, 0x3c1be7c65UL, 0x276f75e63UL, + 0x4490a3f63UL, 0xda60acd52UL, 0x3cc68df59UL, 0xab46f9daeUL, 0x88d533d78UL, 0xb6d62ec21UL, 0xb3c02b646UL, + 0x22e56d408UL, 0xac5f5770aUL, 0xaaa993f66UL, 0x4caa07c8dUL, 0x5c9b4f7b0UL, 0xaa9ef0e05UL, 0x705c5750UL, + 0xac81f545eUL, 0x735b91e74UL, 0x8cc35cee4UL, 0xe44694d04UL, 0xb5e121de0UL, 0x261017d0fUL, 0xf1d439eb5UL, + 0xa1a33ac96UL, 0x174c62c02UL, 0x1ee27f716UL, 0x8b1c5ece9UL, 0x6a05b0c6aUL, 0xd0568dfcUL, 0x192d25e5fUL, + 0x1adbeccc8UL, 0xcfec87f00UL, 0xd0b9dde7aUL, 0x88dcef81eUL, 0x445681cb9UL, 0xdbb2ffc83UL, 0xa48d96df1UL, + 0xb72cc2e7dUL, 0xc295b53fUL, 0xf49832704UL, 0x9968edc29UL, 0x9e4e1af85UL, 0x8683e2d1bUL, 0x810b45c04UL, + 0x6ac44bfe2UL, 0x645346615UL, 0x3990bd598UL, 0x1c9ed0f6aUL, 0xc26729d65UL, 0x83993f795UL, 0x3ac05ac5dUL, + 0x357adff3bUL, 0xd5c05565UL, 0x2f547ef44UL, 0x86c115041UL, 0x640fd9e5fUL, 0xce08bbcf7UL, 0x109bb343eUL, + 0xc21435c92UL, 0x35b4dfce4UL, 0x459752cf2UL, 0xec915b82cUL, 0x51881eed0UL, 0x2dda7dc97UL, 0x2e0142144UL, + 0x42e890f99UL, 0x9a8856527UL, 0x8e80d9d80UL, 0x891cbcf34UL, 0x25dd82410UL, 0x239551d34UL, 0x8fe8f0c70UL, + 0x94106a970UL, 0x82609b40cUL, 0xfc9caf36UL, 0x688181d11UL, 0x718613c08UL, 0xf1ab7629UL, 0xa357bfc18UL, + 0x4c03b7a46UL, 0x204dedce6UL, 0xad6300d37UL, 0x84cc4cd09UL, 0x42160e5c4UL, 0x87d2adfa8UL, 0x7850e7749UL, + 0x4e750fc7cUL, 0xbf2e5dfdaUL, 0xd88324da5UL, 0x234b52f80UL, 0x378204514UL, 0xabdf2ad53UL, 0x365e78ef9UL, + 0x49caa6ca2UL, 0x3c39ddf3UL, 0xc68c5385dUL, 0x5bfcbbf67UL, 0x623241e21UL, 0xabc90d5ccUL, 0x388c6fe85UL, + 0xda0e2d62dUL, 0x10855dfe9UL, 0x4d46efd6bUL, 0x76ea12d61UL, 0x9db377d3dUL, 0xeed0efa71UL, 0xe6ec3ae2fUL, + 0x441faee83UL, 0xba19c8ff5UL, 0x313035eabUL, 0x6ce8f7625UL, 0x880dab58dUL, 0x8d3409e0dUL, 0x2be92ee21UL, + 0xd60302c6cUL, 0x469ffc724UL, 0x87eebeed3UL, 0x42587ef7aUL, 0x7a8cc4e52UL, 0x76a437650UL, 0x999e41ef4UL, + 0x7d0969e42UL, 0xc02baf46bUL, 0x9259f3e47UL, 0x2116a1dc0UL, 0x9f2de4d84UL, 0xeffac29UL, 0x7b371ff8cUL, + 0x668339da9UL, 0xd010aee3fUL, 0x1cd00b4c0UL, 0x95070fc3bUL, 0xf84c9a770UL, 0x38f863d76UL, 0x3646ff045UL, + 0xce1b96412UL, 0x7a5d45da8UL, 0x14e00ef6cUL, 0x5e95abfd8UL, 0xb2e9cb729UL, 0x36c47dd7UL, 0xb8ee97c6bUL, + 0xe9e8f657UL, 0xd4ad2ef1aUL, 0x8811c7f32UL, 0x47bde7c31UL, 0x3adadfb64UL, 0x6e5b28574UL, 0x33e67cd91UL, + 0x2ab9fdd2dUL, 0x8afa67f2bUL, 0xe6a28fc5eUL, 0x72049cdbdUL, 0xae65dac12UL, 0x1251a4526UL, 0x1089ab841UL, + 0xe2f096ee0UL, 0xb0caee573UL, 0xfd6677e86UL, 0x444b3f518UL, 0xbe8b3a56aUL, 0x680a75cfcUL, 0xac02baea8UL, + 0x97d815e1cUL, 0x1d4386e08UL, 0x1a14f5b0eUL, 0xe658a8d81UL, 0xa3868efa7UL, 0x3668a9673UL, 0xe8fc53d85UL, + 0x2e2b7edd5UL, 0x8b2470f13UL, 0xf69795f32UL, 0x4589ffc8eUL, 0x2e2080c9cUL, 0x64265f7dUL, 0x3d714dd10UL, + 0x1692c6ef1UL, 0x3e67f2f49UL, 0x5041dad63UL, 0x1a1503415UL, 0x64c18c742UL, 0xa72eec35UL, 0x1f0f9dc60UL, + 0xa9559bc67UL, 0xf32911d0dUL, 0x21c0d4ffcUL, 0xe01cef5b0UL, 0x4e23a3520UL, 0xaa4f04e49UL, 0xe1c4fcc43UL, + 0x208e8f6e8UL, 0x8486774a5UL, 0x9e98c7558UL, 0x2c59fb7dcUL, 0x9446a4613UL, 0x8292dcc2eUL, 0x4d61631UL, + 0xd05527809UL, 0xa0163852dUL, 0x8f657f639UL, 0xcca6c3e37UL, 0xcb136bc7aUL, 0xfc5a83e53UL, 0x9aa44fc30UL, + 0xbdec1bd3cUL, 0xe020b9f7cUL, 0x4b8f35fb0UL, 0xb8165f637UL, 0x33dc88d69UL, 0x10a2f7e4dUL, 0xc8cb5ff53UL, + 0xde259ff6bUL, 0x46d070dd4UL, 0x32d3b9741UL, 0x7075f1c04UL, 0x4d58dbea0UL}; + + int markerSize = 6; cv::Ptr<cv::aruco::Dictionary> dictionary = new cv::aruco::Dictionary(); - dictionary->markerSize = markerSize; - dictionary->maxCorrectionBits = 3; + dictionary->markerSize = markerSize; + dictionary->maxCorrectionBits = 3; // transform from hexadecimal notation to format in dictionary class - for (auto code : bitListDictMip36h12) + for(auto code : bitListDictMip36h12) { - std::bitset<36> bits(code); + std::bitset<36> bits(code); std::array<uchar, 36> codeAsVector{}; - for (std::size_t i = 0; i < bits.size(); ++i) + for(std::size_t i = 0; i < bits.size(); ++i) { codeAsVector[i] = bits[i]; } - cv::Mat markerBits (markerSize, markerSize, CV_8UC1, codeAsVector.data()); + cv::Mat markerBits(markerSize, markerSize, CV_8UC1, codeAsVector.data()); cv::Mat markerCompressed = cv::aruco::Dictionary::getByteListFromBits(markerBits); dictionary->bytesList.push_back(markerCompressed); } @@ -1214,7 +1412,8 @@ double ArucoCodeParams::getMaxMarkerPerimeter() const void ArucoCodeParams::setMaxMarkerPerimeter(double newMaxMarkerPerimeter) { - if(newMaxMarkerPerimeter < minMarkerPerimeter){ + if(newMaxMarkerPerimeter < minMarkerPerimeter) + { throw std::invalid_argument("Max perimeter length needs to be at least as big as min perimiter length"); } maxMarkerPerimeter = newMaxMarkerPerimeter; @@ -1227,7 +1426,8 @@ double ArucoCodeParams::getMinCornerDistance() const void ArucoCodeParams::setMinCornerDistance(double newMinCornerDistance) { - if(newMinCornerDistance < 0){ + if(newMinCornerDistance < 0) + { throw std::invalid_argument("Min corner distance cannot be negative"); } minCornerDistance = newMinCornerDistance; @@ -1250,10 +1450,12 @@ int ArucoCodeParams::getAdaptiveThreshWinSizeMin() const void ArucoCodeParams::setAdaptiveThreshWinSizeMin(int newAdaptiveThreshWinSizeMin) { - if(newAdaptiveThreshWinSizeMin > adaptiveThreshWinSizeMax){ + if(newAdaptiveThreshWinSizeMin > adaptiveThreshWinSizeMax) + { throw std::invalid_argument("Min adaptiveTreshWinSize needs to be at most as large as max"); } - if(newAdaptiveThreshWinSizeMin < 3){ + if(newAdaptiveThreshWinSizeMin < 3) + { throw std::invalid_argument("Min winsize must be at least 3"); } adaptiveThreshWinSizeMin = newAdaptiveThreshWinSizeMin; @@ -1266,10 +1468,12 @@ int ArucoCodeParams::getAdaptiveThreshWinSizeMax() const void ArucoCodeParams::setAdaptiveThreshWinSizeMax(int newAdaptiveThreshWinSizeMax) { - if(newAdaptiveThreshWinSizeMax < adaptiveThreshWinSizeMin){ + if(newAdaptiveThreshWinSizeMax < adaptiveThreshWinSizeMin) + { throw std::invalid_argument("Max adaptiveThreshWinSize needs to be at least as large as the minimum"); } - if(newAdaptiveThreshWinSizeMax < 3){ + if(newAdaptiveThreshWinSizeMax < 3) + { throw std::invalid_argument("Max adaptive winsize needs to be at lest 3"); } adaptiveThreshWinSizeMax = newAdaptiveThreshWinSizeMax; @@ -1282,7 +1486,8 @@ int ArucoCodeParams::getAdaptiveThreshWinSizeStep() const void ArucoCodeParams::setAdaptiveThreshWinSizeStep(int newAdaptiveThreshWinSizeStep) { - if(newAdaptiveThreshWinSizeStep <= 0){ + if(newAdaptiveThreshWinSizeStep <= 0) + { throw std::invalid_argument("Winsize step needs to be larger than 0"); } adaptiveThreshWinSizeStep = newAdaptiveThreshWinSizeStep; @@ -1315,7 +1520,8 @@ int ArucoCodeParams::getMinDistanceToBorder() const void ArucoCodeParams::setMinDistanceToBorder(int newMinDistanceToBorder) { - if(newMinDistanceToBorder < 0){ + if(newMinDistanceToBorder < 0) + { throw std::invalid_argument("Min distance to border cannot be negative"); } minDistanceToBorder = newMinDistanceToBorder; @@ -1338,7 +1544,8 @@ int ArucoCodeParams::getCornerRefinementWinSize() const void ArucoCodeParams::setCornerRefinementWinSize(int newCornerRefinementWinSize) { - if(newCornerRefinementWinSize < 1){ + if(newCornerRefinementWinSize < 1) + { throw std::invalid_argument("Winsize needs to be at least 1"); } cornerRefinementWinSize = newCornerRefinementWinSize; @@ -1351,7 +1558,8 @@ int ArucoCodeParams::getCornerRefinementMaxIterations() const void ArucoCodeParams::setCornerRefinementMaxIterations(int newCornerRefinementMaxIterations) { - if(newCornerRefinementMaxIterations < 1){ + if(newCornerRefinementMaxIterations < 1) + { throw std::invalid_argument("Max iterations needs to be at least 1"); } cornerRefinementMaxIterations = newCornerRefinementMaxIterations; @@ -1364,7 +1572,8 @@ double ArucoCodeParams::getCornerRefinementMinAccuracy() const void ArucoCodeParams::setCornerRefinementMinAccuracy(double newCornerRefinementMinAccuracy) { - if(newCornerRefinementMinAccuracy <= 0){ + if(newCornerRefinementMinAccuracy <= 0) + { throw std::invalid_argument("Min accuracy needs to be larger than 0"); } cornerRefinementMinAccuracy = newCornerRefinementMinAccuracy; @@ -1377,7 +1586,8 @@ int ArucoCodeParams::getMarkerBorderBits() const void ArucoCodeParams::setMarkerBorderBits(int newMarkerBorderBits) { - if(newMarkerBorderBits < 1){ + if(newMarkerBorderBits < 1) + { throw std::invalid_argument("Marker Borderbits needs to be at least 1"); } markerBorderBits = newMarkerBorderBits; @@ -1420,7 +1630,8 @@ double ArucoCodeParams::getMinOtsuStdDev() const void ArucoCodeParams::setMinOtsuStdDev(double newMinOtsuStdDev) { - if(newMinOtsuStdDev <= 0){ + if(newMinOtsuStdDev <= 0) + { throw std::invalid_argument("Min Otsu stddev needs to be larger than 0"); } minOtsuStdDev = newMinOtsuStdDev; @@ -1443,10 +1654,12 @@ double ArucoCodeParams::getMinMarkerPerimeter() const void ArucoCodeParams::setMinMarkerPerimeter(double newMinMarkerPerimeter) { - if(newMinMarkerPerimeter > maxMarkerPerimeter){ + if(newMinMarkerPerimeter > maxMarkerPerimeter) + { throw std::invalid_argument("Min marker perimeter needs to be at most as large as the max perimeter."); } - if(newMinMarkerPerimeter <= 0){ + if(newMinMarkerPerimeter <= 0) + { throw std::invalid_argument("Min marker perimeter must be larger than 0"); } minMarkerPerimeter = newMinMarkerPerimeter; diff --git a/src/recognitionRoiItem.cpp b/src/recognitionRoiItem.cpp index d4c38c47a0268db2aee13b83c51159121e054c2c..872a4dbddf20f4e78afe9dba19a9335ef092cd9f 100644 --- a/src/recognitionRoiItem.cpp +++ b/src/recognitionRoiItem.cpp @@ -18,40 +18,41 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> +#include "recognitionRoiItem.h" -#include "petrack.h" #include "control.h" +#include "petrack.h" #include "view.h" -#include "recognitionRoiItem.h" -RecognitionRoiItem::RecognitionRoiItem(QWidget *wParent, QGraphicsItem *parent) - : QGraphicsRectItem(parent) +#include <QtWidgets> + +RecognitionRoiItem::RecognitionRoiItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsRectItem(parent) { - mMainWindow = (class Petrack*) wParent; + mMainWindow = (class Petrack *) wParent; mControlWidget = mMainWindow->getControlWidget(); - setRect(0, 0, 0, 0); //qreal x, qreal y, qreal width, qreal height + setRect(0, 0, 0, 0); // qreal x, qreal y, qreal width, qreal height QPen pen(Qt::green); setPen(pen); setAcceptHoverEvents(true); setFlags(ItemIsMovable); // default in control - hide(); // default in control + hide(); // default in control } -void RecognitionRoiItem::mousePressEvent(QGraphicsSceneMouseEvent * event) +void RecognitionRoiItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (!mControlWidget->getRecoRoiFix()) + if(!mControlWidget->getRecoRoiFix()) { - mPressRect = QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); + mPressRect = + QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); mPressPos = event->pos(); - if ((event->pos()).x() < DISTANCE_TO_BORDER+mPressRect.x()) + if((event->pos()).x() < DISTANCE_TO_BORDER + mPressRect.x()) { - if ((event->pos()).y() < DISTANCE_TO_BORDER+mPressRect.y()) + if((event->pos()).y() < DISTANCE_TO_BORDER + mPressRect.y()) { mPressLocation = topLeft; setCursor(Qt::SizeFDiagCursor); } - else if ((event->pos()).y() > mPressRect.height()+mPressRect.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > mPressRect.height() + mPressRect.y() - DISTANCE_TO_BORDER) { mPressLocation = bottomLeft; setCursor(Qt::SizeBDiagCursor); @@ -62,14 +63,14 @@ void RecognitionRoiItem::mousePressEvent(QGraphicsSceneMouseEvent * event) setCursor(Qt::SizeHorCursor); } } - else if ((event->pos()).x() > mPressRect.width()+mPressRect.x()-DISTANCE_TO_BORDER) + else if((event->pos()).x() > mPressRect.width() + mPressRect.x() - DISTANCE_TO_BORDER) { - if ((event->pos()).y() < DISTANCE_TO_BORDER+mPressRect.y()) + if((event->pos()).y() < DISTANCE_TO_BORDER + mPressRect.y()) { mPressLocation = topRight; setCursor(Qt::SizeBDiagCursor); } - else if ((event->pos()).y() > mPressRect.height()+mPressRect.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > mPressRect.height() + mPressRect.y() - DISTANCE_TO_BORDER) { mPressLocation = bottomRight; setCursor(Qt::SizeFDiagCursor); @@ -80,12 +81,12 @@ void RecognitionRoiItem::mousePressEvent(QGraphicsSceneMouseEvent * event) setCursor(Qt::SizeHorCursor); } } - else if ((event->pos()).y() < DISTANCE_TO_BORDER+mPressRect.y()) + else if((event->pos()).y() < DISTANCE_TO_BORDER + mPressRect.y()) { mPressLocation = top; setCursor(Qt::SizeVerCursor); } - else if ((event->pos()).y() > mPressRect.height()+mPressRect.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > mPressRect.height() + mPressRect.y() - DISTANCE_TO_BORDER) { mPressLocation = bottom; setCursor(Qt::SizeVerCursor); @@ -100,10 +101,10 @@ void RecognitionRoiItem::mousePressEvent(QGraphicsSceneMouseEvent * event) QGraphicsRectItem::mousePressEvent(event); } -void RecognitionRoiItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) +void RecognitionRoiItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { mMainWindow->setRecognitionChanged(true); - if( !mMainWindow->isLoading() ) + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); QGraphicsRectItem::mouseReleaseEvent(event); @@ -112,63 +113,78 @@ void RecognitionRoiItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) // event, of moving mouse while mouse button is pressed void RecognitionRoiItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (!mControlWidget->getRecoRoiFix()) + if(!mControlWidget->getRecoRoiFix()) { - QImage *img = mMainWindow->getImage(); - QPoint diff = QPoint(myRound((event->pos()-mPressPos).x()), myRound((event->pos()-mPressPos).y())); + QImage *img = mMainWindow->getImage(); + QPoint diff = QPoint(myRound((event->pos() - mPressPos).x()), myRound((event->pos() - mPressPos).y())); // raender des bildes nicht ueberscheiten // swappen des rechtecks vermeiden, damit keine negativen width... - if (img != nullptr) + if(img != nullptr) { - if (mPressLocation == inside || mPressLocation == topLeft || mPressLocation == left || mPressLocation == bottomLeft) + if(mPressLocation == inside || mPressLocation == topLeft || mPressLocation == left || + mPressLocation == bottomLeft) { - if (mPressRect.x()+diff.x() < -mMainWindow->getImageBorderSize()) - diff.setX(-mPressRect.x()-mMainWindow->getImageBorderSize()); - if (mPressLocation != inside && mPressRect.width()-diff.x() < MIN_SIZE) - diff.setX(mPressRect.width()-MIN_SIZE); + if(mPressRect.x() + diff.x() < -mMainWindow->getImageBorderSize()) + diff.setX(-mPressRect.x() - mMainWindow->getImageBorderSize()); + if(mPressLocation != inside && mPressRect.width() - diff.x() < MIN_SIZE) + diff.setX(mPressRect.width() - MIN_SIZE); } - if (mPressLocation == inside || mPressLocation == topLeft || mPressLocation == top || mPressLocation == topRight) + if(mPressLocation == inside || mPressLocation == topLeft || mPressLocation == top || + mPressLocation == topRight) { - if (mPressRect.y()+diff.y() < -mMainWindow->getImageBorderSize()) - diff.setY(-mPressRect.y()-mMainWindow->getImageBorderSize()); - if (mPressLocation != inside && mPressRect.height()-diff.y() < MIN_SIZE) - diff.setY(mPressRect.height()-MIN_SIZE); + if(mPressRect.y() + diff.y() < -mMainWindow->getImageBorderSize()) + diff.setY(-mPressRect.y() - mMainWindow->getImageBorderSize()); + if(mPressLocation != inside && mPressRect.height() - diff.y() < MIN_SIZE) + diff.setY(mPressRect.height() - MIN_SIZE); } - if (mPressLocation == inside || mPressLocation == topRight || mPressLocation == right || mPressLocation == bottomRight) + if(mPressLocation == inside || mPressLocation == topRight || mPressLocation == right || + mPressLocation == bottomRight) { - if (mPressRect.x()+diff.x()+mPressRect.width() > img->width()-mMainWindow->getImageBorderSize()) - diff.setX(img->width()-mPressRect.x()-mPressRect.width()-mMainWindow->getImageBorderSize()); - if (mPressLocation != inside && mPressRect.width()+diff.x() < MIN_SIZE) - diff.setX(-mPressRect.width()+MIN_SIZE); + if(mPressRect.x() + diff.x() + mPressRect.width() > img->width() - mMainWindow->getImageBorderSize()) + diff.setX(img->width() - mPressRect.x() - mPressRect.width() - mMainWindow->getImageBorderSize()); + if(mPressLocation != inside && mPressRect.width() + diff.x() < MIN_SIZE) + diff.setX(-mPressRect.width() + MIN_SIZE); } - if (mPressLocation == inside || mPressLocation == bottomLeft || mPressLocation == bottom || mPressLocation == bottomRight) + if(mPressLocation == inside || mPressLocation == bottomLeft || mPressLocation == bottom || + mPressLocation == bottomRight) { - if (mPressRect.y()+diff.y()+mPressRect.height() > img->height()-mMainWindow->getImageBorderSize()) - diff.setY(img->height()-mPressRect.y()-mPressRect.height()-mMainWindow->getImageBorderSize()); - if (mPressLocation != inside && mPressRect.height()+diff.y() < MIN_SIZE) - diff.setY(-mPressRect.height()+MIN_SIZE); + if(mPressRect.y() + diff.y() + mPressRect.height() > img->height() - mMainWindow->getImageBorderSize()) + diff.setY(img->height() - mPressRect.y() - mPressRect.height() - mMainWindow->getImageBorderSize()); + if(mPressLocation != inside && mPressRect.height() + diff.y() < MIN_SIZE) + diff.setY(-mPressRect.height() + MIN_SIZE); } } - if (mPressLocation == topLeft) - setRect(mPressRect.x()+diff.x(), mPressRect.y()+diff.y(), mPressRect.width()-diff.x(), mPressRect.height()-diff.y()); - // setRect(mPressRect.x()+diff.x(), mPressRect.y()+mPressRect.x()+diff.x(), mPressRect.y()+diff.y(), mPressRect.width()-diff.x(), mPressRect.height()-diff.y()diff.y(), mPressRect.width()-diff.x(), mPressRect.height()-diff.y()); - else if (mPressLocation == topRight) - setRect(mPressRect.x(), mPressRect.y()+diff.y(), mPressRect.width()+diff.x(), mPressRect.height()-diff.y()); - else if (mPressLocation == bottomLeft) - setRect(mPressRect.x()+diff.x(), mPressRect.y(), mPressRect.width()-diff.x(), mPressRect.height()+diff.y()); - else if (mPressLocation == bottomRight) - setRect(mPressRect.x(), mPressRect.y(), mPressRect.width()+diff.x(), mPressRect.height()+diff.y()); - else if (mPressLocation == left) - setRect(mPressRect.x()+diff.x(), mPressRect.y(), mPressRect.width()-diff.x(), mPressRect.height()); - else if (mPressLocation == right) - setRect(mPressRect.x(), mPressRect.y(), mPressRect.width()+diff.x(), mPressRect.height()); - else if (mPressLocation == top) - setRect(mPressRect.x(), mPressRect.y()+diff.y(), mPressRect.width(), mPressRect.height()-diff.y()); - else if (mPressLocation == bottom) - setRect(mPressRect.x(), mPressRect.y(), mPressRect.width(), mPressRect.height()+diff.y()); + if(mPressLocation == topLeft) + setRect( + mPressRect.x() + diff.x(), + mPressRect.y() + diff.y(), + mPressRect.width() - diff.x(), + mPressRect.height() - diff.y()); + else if(mPressLocation == topRight) + setRect( + mPressRect.x(), + mPressRect.y() + diff.y(), + mPressRect.width() + diff.x(), + mPressRect.height() - diff.y()); + else if(mPressLocation == bottomLeft) + setRect( + mPressRect.x() + diff.x(), + mPressRect.y(), + mPressRect.width() - diff.x(), + mPressRect.height() + diff.y()); + else if(mPressLocation == bottomRight) + setRect(mPressRect.x(), mPressRect.y(), mPressRect.width() + diff.x(), mPressRect.height() + diff.y()); + else if(mPressLocation == left) + setRect(mPressRect.x() + diff.x(), mPressRect.y(), mPressRect.width() - diff.x(), mPressRect.height()); + else if(mPressLocation == right) + setRect(mPressRect.x(), mPressRect.y(), mPressRect.width() + diff.x(), mPressRect.height()); + else if(mPressLocation == top) + setRect(mPressRect.x(), mPressRect.y() + diff.y(), mPressRect.width(), mPressRect.height() - diff.y()); + else if(mPressLocation == bottom) + setRect(mPressRect.x(), mPressRect.y(), mPressRect.width(), mPressRect.height() + diff.y()); else // entspricht: if (mPressLocation == inside) - setRect(mPressRect.x()+diff.x(), mPressRect.y()+diff.y(), mPressRect.width(), mPressRect.height()); - // nicht, da sonst koordinatensystem verschoben wird: QGraphicsRectItem::mouseMoveEvent(event); // drag + setRect(mPressRect.x() + diff.x(), mPressRect.y() + diff.y(), mPressRect.width(), mPressRect.height()); + // nicht, da sonst koordinatensystem verschoben wird: QGraphicsRectItem::mouseMoveEvent(event); // drag } else // drag mach ich selber QGraphicsRectItem::mouseMoveEvent(event); @@ -180,42 +196,46 @@ void RecognitionRoiItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) QPointF pos = event->scenePos(); pos.setX(pos.x() + mMainWindow->getImageBorderSize()); pos.setY(pos.y() + mMainWindow->getImageBorderSize()); - // abfrage auf width() ..., da durch rectLinie die recoBox etwas groesser ist als das Bild und + // abfrage auf width() ..., da durch rectLinie die recoBox etwas groesser ist als das Bild und // es bei mMainWindow->setMousePosOnImage(pos); zum fehler beim bildzugriff kommen kann!!! - if (mMainWindow->getImage() && //(pos.x() > 0) && (pos.y() > 0) && - (pos.x() < mMainWindow->getImage()->width()) && (pos.y() < mMainWindow->getImage()->height())) + if(mMainWindow->getImage() && //(pos.x() > 0) && (pos.y() > 0) && + (pos.x() < mMainWindow->getImage()->width()) && (pos.y() < mMainWindow->getImage()->height())) { mMainWindow->setMousePosOnImage(pos); - if (!mControlWidget->getRecoRoiFix()) + if(!mControlWidget->getRecoRoiFix()) { - QRect r = QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); - if ((event->pos()).x() < DISTANCE_TO_BORDER+r.x()) + QRect r = + QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); + if((event->pos()).x() < DISTANCE_TO_BORDER + r.x()) { - if ((event->pos()).y() < DISTANCE_TO_BORDER+r.y()) + if((event->pos()).y() < DISTANCE_TO_BORDER + r.y()) setCursor(Qt::SizeFDiagCursor); - else if ((event->pos()).y() > r.height()+r.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > r.height() + r.y() - DISTANCE_TO_BORDER) setCursor(Qt::SizeBDiagCursor); else setCursor(Qt::SizeHorCursor); } - else if ((event->pos()).x() > r.width()+r.x()-DISTANCE_TO_BORDER) + else if((event->pos()).x() > r.width() + r.x() - DISTANCE_TO_BORDER) { - if ((event->pos()).y() < DISTANCE_TO_BORDER+r.y()) + if((event->pos()).y() < DISTANCE_TO_BORDER + r.y()) setCursor(Qt::SizeBDiagCursor); - else if ((event->pos()).y() > r.height()+r.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > r.height() + r.y() - DISTANCE_TO_BORDER) setCursor(Qt::SizeFDiagCursor); else setCursor(Qt::SizeHorCursor); } - else if (((event->pos()).y() < DISTANCE_TO_BORDER+r.y()) || ((event->pos()).y() > r.height()+r.y()-DISTANCE_TO_BORDER)) + else if( + ((event->pos()).y() < DISTANCE_TO_BORDER + r.y()) || + ((event->pos()).y() > r.height() + r.y() - DISTANCE_TO_BORDER)) setCursor(Qt::SizeVerCursor); else setCursor(Qt::OpenHandCursor); } else // wird nur einmal durchaufen - ruecksetzen in control.cpp { - setAcceptHoverEvents(false); // verhoindert nicht, dass wenn objekt darunter liegt, was andereen cursor haette - cursor wird weiterhin beim drueberfahren auf cross gesetzt + setAcceptHoverEvents(false); // verhoindert nicht, dass wenn objekt darunter liegt, was andereen cursor + // haette - cursor wird weiterhin beim drueberfahren auf cross gesetzt setCursor(Qt::CrossCursor); } } @@ -227,28 +247,36 @@ void RecognitionRoiItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) void RecognitionRoiItem::checkRect() { cv::Mat img = mMainWindow->getImageFiltered(); - if (!img.empty()) + if(!img.empty()) { // not QImage *img = mMainWindow->getImage(); as size is not adapted yet - QRect r = QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); - if (r.x() > img.cols-mMainWindow->getImageBorderSize()-MIN_SIZE || - r.y() > img.rows-mMainWindow->getImageBorderSize()-MIN_SIZE || - r.x()+r.width() < -mMainWindow->getImageBorderSize()+MIN_SIZE || - r.y()+r.height() < -mMainWindow->getImageBorderSize()+MIN_SIZE) + QRect r = + QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); + if(r.x() > img.cols - mMainWindow->getImageBorderSize() - MIN_SIZE || + r.y() > img.rows - mMainWindow->getImageBorderSize() - MIN_SIZE || + r.x() + r.width() < -mMainWindow->getImageBorderSize() + MIN_SIZE || + r.y() + r.height() < -mMainWindow->getImageBorderSize() + MIN_SIZE) setRect(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), img.cols, img.rows); else { - if (r.x() < -mMainWindow->getImageBorderSize()) - setRect(-mMainWindow->getImageBorderSize(), r.y(), r.width()+(mMainWindow->getImageBorderSize()+r.x()), r.height()); - if (r.y() < -mMainWindow->getImageBorderSize()) - setRect(r.x(), -mMainWindow->getImageBorderSize(), r.width(), r.height()+(mMainWindow->getImageBorderSize()+r.y())); - if (r.x()+mMainWindow->getImageBorderSize()+r.width() > img.cols) + if(r.x() < -mMainWindow->getImageBorderSize()) + setRect( + -mMainWindow->getImageBorderSize(), + r.y(), + r.width() + (mMainWindow->getImageBorderSize() + r.x()), + r.height()); + if(r.y() < -mMainWindow->getImageBorderSize()) + setRect( + r.x(), + -mMainWindow->getImageBorderSize(), + r.width(), + r.height() + (mMainWindow->getImageBorderSize() + r.y())); + if(r.x() + mMainWindow->getImageBorderSize() + r.width() > img.cols) { - //debout << r.x()+mMainWindow->getImageBorderSize()+r.width() << endl; - setRect(r.x(), r.y(), img.cols-r.x()-mMainWindow->getImageBorderSize(), r.height()); + setRect(r.x(), r.y(), img.cols - r.x() - mMainWindow->getImageBorderSize(), r.height()); } - if (r.y()+mMainWindow->getImageBorderSize()+r.height() > img.rows) - setRect(r.x(), r.y(), r.width(), img.rows-r.y()-mMainWindow->getImageBorderSize()); + if(r.y() + mMainWindow->getImageBorderSize() + r.height() > img.rows) + setRect(r.x(), r.y(), r.width(), img.rows - r.y() - mMainWindow->getImageBorderSize()); } } else diff --git a/src/skeletonTree.cpp b/src/skeletonTree.cpp index 8fb1e8f2839e872f3a2a9283a82768a865b1ddc9..eac1142232e9e5932bdefbe637284c7c2c87b686 100644 --- a/src/skeletonTree.cpp +++ b/src/skeletonTree.cpp @@ -17,9 +17,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <algorithm> #include "skeletonTree.h" +#include <algorithm> + //--SkeletonNode @@ -28,10 +29,7 @@ * @param[in] id The identifier of this node. * @param[in] point The position of this node. */ -SkeletonNode::SkeletonNode(const uint8_t& id, cv::Point3f point) - :mId(id), mPoint(std::move(point)) -{ -} +SkeletonNode::SkeletonNode(const uint8_t &id, cv::Point3f point) : mId(id), mPoint(std::move(point)) {} /** * @brief Gets the Child with the specified id. @@ -43,9 +41,11 @@ SkeletonNode::SkeletonNode(const uint8_t& id, cv::Point3f point) * * @return A const reference to the child with the specified id. * @throw std::out_of_range -*/ -const SkeletonNode &SkeletonNode::getChildById(uint8_t id) const { - auto foundValue = std::find_if(mChildren.begin(), mChildren.end(), [id](const SkeletonNode& node){return node.getId() == id;}); + */ +const SkeletonNode &SkeletonNode::getChildById(uint8_t id) const +{ + auto foundValue = + std::find_if(mChildren.begin(), mChildren.end(), [id](const SkeletonNode &node) { return node.getId() == id; }); if(foundValue == mChildren.end()) { throw std::out_of_range("Id" + std::to_string(id) + " in children not found"); @@ -64,16 +64,15 @@ const SkeletonNode &SkeletonNode::getChildById(uint8_t id) const { * @param[in, out] lines The array to append the new lines. * */ -void SkeletonTree::recurseSkeleton(const SkeletonNode& node, std::vector<SkeletonLine>& lines) +void SkeletonTree::recurseSkeleton(const SkeletonNode &node, std::vector<SkeletonLine> &lines) { - for(const SkeletonNode& child : node.getChildren()){ - lines.push_back( - {/*Direct initialization of SkeletonLine struct*/ - /*.start =*/ node.getPos(), - /*.start_id =*/ node.getId(), - /*.end =*/ child.getPos(), - /*.end_id =*/ child.getId()} - ); + for(const SkeletonNode &child : node.getChildren()) + { + lines.push_back({/*Direct initialization of SkeletonLine struct*/ + /*.start =*/node.getPos(), + /*.start_id =*/node.getId(), + /*.end =*/child.getPos(), + /*.end_id =*/child.getId()}); recurseSkeleton(child, lines); } } diff --git a/src/skeletonTreeFactory.cpp b/src/skeletonTreeFactory.cpp index d254d73ac7402fdbb431b95b1045775c608fc566..02ff6ac75eaffb8f2791ffba5eea3ed610ada0d2 100644 --- a/src/skeletonTreeFactory.cpp +++ b/src/skeletonTreeFactory.cpp @@ -17,10 +17,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <opencv2/core/matx.hpp> -#include "vector.h" #include "skeletonTreeFactory.h" +#include "vector.h" + +#include <opencv2/core/matx.hpp> + /** * @brief Static method to construct a SkeletonTree. * @@ -31,48 +33,46 @@ * @return The constructed Skeleton. * */ -SkeletonTree SkeletonTreeFactory::generateTree(const XSenseStruct& points) +SkeletonTree SkeletonTreeFactory::generateTree(const XSenseStruct &points) { + // Start from the root + SkeletonNode root(0, points.mRoot); + SkeletonNode &neck = root.addChild(SkeletonNode(1, points.mNeck)); - //Start from the root - SkeletonNode root(0, points.mRoot); - SkeletonNode& neck = root.addChild(SkeletonNode(1, points.mNeck)); - - //continue with the neck + // continue with the neck neck.addChild(SkeletonNode(2, points.mHeadTop)); - SkeletonNode& lShoulder = neck.addChild(SkeletonNode(3, points.mShldrL)); + SkeletonNode &lShoulder = neck.addChild(SkeletonNode(3, points.mShldrL)); - //add the left arm - SkeletonNode& lElbow = lShoulder.addChild(SkeletonNode(4, points.mElbowL)); - SkeletonNode& lWrist = lElbow.addChild(SkeletonNode(5, points.mWristL)); + // add the left arm + SkeletonNode &lElbow = lShoulder.addChild(SkeletonNode(4, points.mElbowL)); + SkeletonNode &lWrist = lElbow.addChild(SkeletonNode(5, points.mWristL)); lWrist.addChild(SkeletonNode(6, points.mHandL)); - //add the right arm - SkeletonNode& rShoulder = neck.addChild(SkeletonNode(7, points.mShldrR)); - SkeletonNode& rElbow = rShoulder.addChild(SkeletonNode(8, points.mElbowR)); - SkeletonNode& rWrist = rElbow.addChild(SkeletonNode(9, points.mWristR)); + // add the right arm + SkeletonNode &rShoulder = neck.addChild(SkeletonNode(7, points.mShldrR)); + SkeletonNode &rElbow = rShoulder.addChild(SkeletonNode(8, points.mElbowR)); + SkeletonNode &rWrist = rElbow.addChild(SkeletonNode(9, points.mWristR)); rWrist.addChild(SkeletonNode(10, points.mHandR)); - //add the left leg - SkeletonNode& lHip = root.addChild(SkeletonNode(11, points.mHipL)); - SkeletonNode& lKnee = lHip.addChild(SkeletonNode(12, points.mKneeL)); - SkeletonNode& lHeel = lKnee.addChild(SkeletonNode(13, points.mHeelL)); + // add the left leg + SkeletonNode &lHip = root.addChild(SkeletonNode(11, points.mHipL)); + SkeletonNode &lKnee = lHip.addChild(SkeletonNode(12, points.mKneeL)); + SkeletonNode &lHeel = lKnee.addChild(SkeletonNode(13, points.mHeelL)); lHeel.addChild(SkeletonNode(14, points.mToeL)); - SkeletonNode& rHip = root.addChild(SkeletonNode(15, points.mHipR)); - SkeletonNode& rKnee = rHip.addChild(SkeletonNode(16, points.mKneeR)); - SkeletonNode& rHeel = rKnee.addChild(SkeletonNode(17, points.mHeelR)); + SkeletonNode &rHip = root.addChild(SkeletonNode(15, points.mHipR)); + SkeletonNode &rKnee = rHip.addChild(SkeletonNode(16, points.mKneeR)); + SkeletonNode &rHeel = rKnee.addChild(SkeletonNode(17, points.mHeelR)); rHeel.addChild(SkeletonNode(18, points.mToeR)); - //calculate view direction of the head - cv::Point3f headUp = points.mHeadTop - points.mNeck; + // calculate view direction of the head + cv::Point3f headUp = points.mHeadTop - points.mNeck; cv::Point3f rightVector = points.mEarR - points.mEarL; - //the direction is calculated using the cross product + // the direction is calculated using the cross product cv::Point3f dir = headUp.cross(rightVector); SkeletonTree skeleton(std::move(root), Vec3F(dir)); return skeleton; } - diff --git a/src/stereoAviFile.cpp b/src/stereoAviFile.cpp index c6f7d79fde30c25bfc1faa0b4ae20d7028a01fb1..75aba64ed1a44d0ecd5e95b9745af475af66ca19 100644 --- a/src/stereoAviFile.cpp +++ b/src/stereoAviFile.cpp @@ -30,8 +30,8 @@ //============================================================================= // Project Includes //============================================================================= -#include "stereoAviFile.h" #include "helper.h" +#include "stereoAviFile.h" // // Extra temp data bytes. @@ -40,17 +40,18 @@ StereoAviFile::StereoAviFile() { - m_pTempBuffer = NULL; + m_pTempBuffer = NULL; - m_iTimeIndex = -1; + m_iTimeIndex = -1; - m_iCols = 0; - m_iRows = 0; - m_iBPP = 0; - m_iSize = 0; - m_iRowInc = 0; + m_iCols = 0; + m_iRows = 0; + m_iBPP = 0; + m_iSize = 0; + m_iRowInc = 0; - mCamera = cameraRight; // wie in petrack.cpp right als default genommen da reference image in triclops auch right ist + mCamera = + cameraRight; // wie in petrack.cpp right als default genommen da reference image in triclops auch right ist mImageLeft = NULL; mImageRight = NULL; @@ -61,105 +62,103 @@ StereoAviFile::~StereoAviFile() { close(); - if ( m_pTempBuffer != NULL ) + if(m_pTempBuffer != NULL) { - delete [] m_pTempBuffer; + delete[] m_pTempBuffer; m_pTempBuffer = NULL; } } // if return false there may be some allocated memory left!!! // stereoImg is used to use the same img for a bunch of files -bool StereoAviFile::open(const char* pszFilename, IplImage* stereoImgLeft, IplImage* stereoImgRight) +bool StereoAviFile::open(const char *pszFilename, IplImage *stereoImgLeft, IplImage *stereoImgRight) { - - if (pszFilename == NULL) + if(pszFilename == NULL) return false; - m_vcReader = cvCreateFileCapture(pszFilename); + m_vcReader = cvCreateFileCapture(pszFilename); - m_iTimeIndex = -1; // damit das erste readframe wirklich einen frame auch bei index=0 liesst + m_iTimeIndex = -1; // damit das erste readframe wirklich einen frame auch bei index=0 liesst - m_iCols = cvGetCaptureProperty(m_vcReader,CV_CAP_PROP_FRAME_WIDTH); // bi.biWidth; - m_iRows = cvGetCaptureProperty(m_vcReader,CV_CAP_PROP_FRAME_HEIGHT); // bi.biHeight; - m_iBPP = 8; // bi.biBitCount; - m_iRowInc = m_iCols * (m_iBPP / 8); - m_iSize = m_iRows * m_iRowInc; - m_pTempBuffer = new unsigned char[m_iSize]; + m_iCols = cvGetCaptureProperty(m_vcReader, CV_CAP_PROP_FRAME_WIDTH); // bi.biWidth; + m_iRows = cvGetCaptureProperty(m_vcReader, CV_CAP_PROP_FRAME_HEIGHT); // bi.biHeight; + m_iBPP = 8; // bi.biBitCount; + m_iRowInc = m_iCols * (m_iBPP / 8); + m_iSize = m_iRows * m_iRowInc; + m_pTempBuffer = new unsigned char[m_iSize]; - //if (stereoImg != NULL) - mImageLeft = stereoImgLeft; // Attention: nur 1280x960 image wird angelegt fuer bumblebee!!! - mImageRight = stereoImgRight; - // CvSize size; - // size.width = m_iCols; - // size.height = m_iRows; - //cvCreateImage(size, 8, 1); + // if (stereoImg != NULL) + mImageLeft = stereoImgLeft; // Attention: nur 1280x960 image wird angelegt fuer bumblebee!!! + mImageRight = stereoImgRight; + // CvSize size; + // size.width = m_iCols; + // size.height = m_iRows; + // cvCreateImage(size, 8, 1); - return true; + return true; } -IplImage* StereoAviFile::getFrame(enum Camera camera) +IplImage *StereoAviFile::getFrame(enum Camera camera) { - if (camera == cameraLeft) + if(camera == cameraLeft) return mImageLeft; - else if (camera == cameraRight) + else if(camera == cameraRight) return mImageRight; else return NULL; } -IplImage* StereoAviFile::readFrame(int index) +IplImage *StereoAviFile::readFrame(int index) { - if (index != m_iTimeIndex) + if(index != m_iTimeIndex) { - int x,y; + int x, y; // Pointer to the data information in the IplImage - //char *data = mImage->imageData; - char *dataLeft = mImageLeft->imageData; - char *dataRight = mImageRight->imageData; + // char *data = mImage->imageData; + char *dataLeft = mImageLeft->imageData; + char *dataRight = mImageRight->imageData; char *yDataLeft = dataLeft; char *yDataRight = dataRight; - char *p = (char *) m_pTempBuffer; - //if (mCamera == cameraLeft) - // ++p; //p+=2*mImage->height*mImage->height; - // This loop is optimized so it has to calculate the least amount of indexes - // Optimizing the access to the pointer data is useless (no difference in performance when tested) - for (y = 0; y < mImageLeft->height; ++y) + char *p = (char *) m_pTempBuffer; + // if (mCamera == cameraLeft) + // ++p; //p+=2*mImage->height*mImage->height; + // This loop is optimized so it has to calculate the least amount of indexes + // Optimizing the access to the pointer data is useless (no difference in performance when tested) + for(y = 0; y < mImageLeft->height; ++y) { - for (x = 0; x < mImageLeft->width; ++x) + for(x = 0; x < mImageLeft->width; ++x) { - *dataRight = *p; + *dataRight = *p; ++dataRight; ++p; *dataLeft = *p; ++dataLeft; - ++p; //p+=2; + ++p; // p+=2; } - //p += mImage->width; // die linke oder rechte kamera ueberspringen - dataLeft = (yDataLeft += mImageLeft->widthStep); // because sometimes widthStep != width + // p += mImage->width; // die linke oder rechte kamera ueberspringen + dataLeft = (yDataLeft += mImageLeft->widthStep); // because sometimes widthStep != width dataRight = (yDataRight += mImageRight->widthStep); } m_iTimeIndex = index; } - if (mCamera == cameraLeft) + if(mCamera == cameraLeft) return mImageLeft; else return mImageRight; - //return mImage; + // return mImage; } bool StereoAviFile::close() { - - if ( m_pTempBuffer != NULL ) + if(m_pTempBuffer != NULL) { - delete [] m_pTempBuffer; + delete[] m_pTempBuffer; m_pTempBuffer = NULL; } - //cvReleaseImage(&mImage); wird nun in animation.cpp angelegt + // cvReleaseImage(&mImage); wird nun in animation.cpp angelegt // // Release the library. diff --git a/src/stereoContext.cpp b/src/stereoContext.cpp index 0d7a09c58be85fee26c50e73102721bd057eff53..0d60facc3b1c1a47c97775451933faab29aab613 100644 --- a/src/stereoContext.cpp +++ b/src/stereoContext.cpp @@ -18,16 +18,17 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QDir> - #include "stereoContext.h" -#include "stereoWidget.h" -#include "helper.h" -#include "petrack.h" + #include "animation.h" #include "control.h" #include "ellipse.h" +#include "helper.h" #include "person.h" +#include "petrack.h" +#include "stereoWidget.h" + +#include <QDir> #ifdef STEREO @@ -35,59 +36,58 @@ //#define TMP_STEREO_SEQ_DISP // neben der Einzelbildfolge soll auch das berechnete Hoehenfeld eingelesen werden //#define STEREO_SEQ_FILEBASE "D:/diss/personModel/ownPerson/movie/one/one_" //#define STEREO_SEQ_FILEBASE "D:/diss/personModel/ownPerson/movie/withHermesMarker/more_" -#define STEREO_SEQ_FILEBASE "D:/diss/personModel/ownPerson/movie/schraeg/d1/d1.0_" -#define STEREO_SEQ_FIRST_FRAME 1 //18 -#define STEREO_SEQ_LAST_FRAME 132 // maximal 127 bei kleiner stereo-datein 165 +#define STEREO_SEQ_FILEBASE "D:/diss/personModel/ownPerson/movie/schraeg/d1/d1.0_" +#define STEREO_SEQ_FIRST_FRAME 1 // 18 +#define STEREO_SEQ_LAST_FRAME 132 // maximal 127 bei kleiner stereo-datein 165 #define STEREO_SEQ_MAX_PERS_HEIGHT 180 // war direkt neben dem load, aber sollte ggf in init() auch benutzt werden #ifdef TMP_STEREO_SEQ - static IplImage* tempLeftImg = NULL; - static IplImage* tempRightImg = NULL; +static IplImage *tempLeftImg = NULL; +static IplImage *tempRightImg = NULL; #endif #endif -using namespace::cv; +using namespace ::cv; -pet::StereoContext::StereoContext(Petrack* main) +pet::StereoContext::StereoContext(Petrack *main) { - mMain = main; + mMain = main; mAnimation = main->getAnimation(); - mStatus = clean; + mStatus = clean; QString calFile, calFileInt; - QDate fileDate = mAnimation->getFileInfo(). lastModified().date(); + QDate fileDate = mAnimation->getFileInfo().lastModified().date(); QString version; - if ((mAnimation->getFileBase()).contains("cam1")) + if((mAnimation->getFileBase()).contains("cam1")) { - if (fileDate < QDate(2009, 11, 30)) + if(fileDate < QDate(2009, 11, 30)) { - version = "old"; + version = "old"; calFileInt = ":/calibCam1"; } else { - version = "new"; + version = "new"; calFileInt = ":/calibCam1New"; } - calFile = QDir::tempPath()+"/"+"cam1_7280765.cal"; - + calFile = QDir::tempPath() + "/" + "cam1_7280765.cal"; } - else if ((mAnimation->getFileBase()).contains("cam2")) + else if((mAnimation->getFileBase()).contains("cam2")) { - if (fileDate < QDate(2009, 11, 30)) + if(fileDate < QDate(2009, 11, 30)) { - version = "old"; + version = "old"; calFileInt = ":/calibCam2"; } else { - version = "new"; + version = "new"; calFileInt = ":/calibCam2New"; } - calFile = QDir::tempPath()+"/"+"cam2_7280791.cal"; + calFile = QDir::tempPath() + "/" + "cam2_7280791.cal"; } else { @@ -101,62 +101,63 @@ pet::StereoContext::StereoContext(Petrack* main) calFp.open(QIODevice::WriteOnly); calFp.write(calFpInt.readAll()); calFp.close(); - if (!QFile::exists(calFile)) + if(!QFile::exists(calFile)) { - debout << "Error: Calibration file "<< calFile <<" could not be created!" << std::endl; + debout << "Error: Calibration file " << calFile << " could not be created!" << std::endl; return; } - debout << "Using " << calFile << " (" << version <<") for calibration." << std::endl; + debout << "Using " << calFile << " (" << version << ") for calibration." << std::endl; #ifdef STEREO TriclopsError triclopsError; - triclopsError = triclopsGetDefaultContextFromFile(&mTriclopsContext, (char *) calFile.toLatin1().data()); - if (triclopsError != TriclopsErrorOk) + triclopsError = triclopsGetDefaultContextFromFile(&mTriclopsContext, (char *) calFile.toLatin1().data()); + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; - triclopsError = triclopsSetResolution(mTriclopsContext, 960, 1280); //240, 320 // 1536, 2048 - if (triclopsError != TriclopsErrorOk) + triclopsError = triclopsSetResolution(mTriclopsContext, 960, 1280); // 240, 320 // 1536, 2048 + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; triclopsError = triclopsSetSubpixelInterpolation(mTriclopsContext, 1); // turn on sub-pixel interpolation - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; - triclopsError = triclopsSetStrictSubpixelValidation(mTriclopsContext, 1); // make sure strict subpixel validation is on - if (triclopsError != TriclopsErrorOk) + triclopsError = + triclopsSetStrictSubpixelValidation(mTriclopsContext, 1); // make sure strict subpixel validation is on + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; -// triclopsError = triclopsSetDisparityMapping(mTriclopsContext, 0,255); -// if (triclopsError != TriclopsErrorOk) -// debout << triclopsErrorToString(triclopsError) << endl; -// triclopsError = triclopsSetDisparityMappingOn(mTriclopsContext, 1); // !!! ausschalten, wenn disparity map fuer 3d-auswertung genutzt wird - nur zum angucken besser -// if (triclopsError != TriclopsErrorOk) -// debout << triclopsErrorToString(triclopsError) << endl; + // triclopsError = triclopsSetDisparityMapping(mTriclopsContext, 0,255); + // if (triclopsError != TriclopsErrorOk) + // debout << triclopsErrorToString(triclopsError) << endl; + // triclopsError = triclopsSetDisparityMappingOn(mTriclopsContext, 1); // !!! ausschalten, wenn disparity map + // fuer 3d-auswertung genutzt wird - nur zum angucken besser if (triclopsError != TriclopsErrorOk) + // debout << triclopsErrorToString(triclopsError) << endl; - //triclopsSetRectImgQuality(...) entzerrung soll verbessert werden + // triclopsSetRectImgQuality(...) entzerrung soll verbessert werden triclopsError = triclopsSetStereoQuality(mTriclopsContext, TriStereoQlty_ENHANCED); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; // lets turn off all validation except subpixel and surface // this works quite well triclopsError = triclopsSetTextureValidation(mTriclopsContext, 0); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; triclopsError = triclopsSetUniquenessValidation(mTriclopsContext, 0); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; // turn on surface validation triclopsError = triclopsSetSurfaceValidation(mTriclopsContext, 1); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; triclopsError = triclopsSetSurfaceValidationSize(mTriclopsContext, 200); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; triclopsError = triclopsSetSurfaceValidationDifference(mTriclopsContext, 0.5); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; // turn on back-forth validation triclopsError = triclopsSetBackForthValidation(mTriclopsContext, 1); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; triclopsGetSurfaceValidationMapping(mTriclopsContext, &mSurfaceValue); @@ -176,9 +177,9 @@ pet::StereoContext::StereoContext(Petrack* main) } pet::StereoContext::~StereoContext() -{ +{ #ifdef STEREO - if (mTriclopsContext) + if(mTriclopsContext) triclopsDestroyContext(mTriclopsContext); #endif } @@ -188,12 +189,12 @@ pet::StereoContext::~StereoContext() // default: IplImage *viewImg = NULL void pet::StereoContext::init(Mat &viewImg) // = NULL { -// static IplImage *lastViewImg = NULL; -// if (viewImg == NULL) // for edge mask -// viewImg = lastViewImg; -// lastViewImg = viewImg; + // static IplImage *lastViewImg = NULL; + // if (viewImg == NULL) // for edge mask + // viewImg = lastViewImg; + // lastViewImg = viewImg; - if (!viewImg.empty() && (viewImg.cols != 1280 || viewImg.rows != 960)) + if(!viewImg.empty() && (viewImg.cols != 1280 || viewImg.rows != 960)) { debout << "Warning: no images beside 1280x960!" << endl; return; @@ -205,73 +206,75 @@ void pet::StereoContext::init(Mat &viewImg) // = NULL TriclopsError triclopsError; - if (!viewImg.empty() && (mAnimation->getCaptureStereo()->getCamera() == cameraLeft)) + if(!viewImg.empty() && (mAnimation->getCaptureStereo()->getCamera() == cameraLeft)) { - leftImg = cvCreateImage(cvSize(viewImg.cols,viewImg.rows),8,viewImg.channels()); + leftImg = cvCreateImage(cvSize(viewImg.cols, viewImg.rows), 8, viewImg.channels()); IplImage tmpImg = viewImg; - cvCopy(&tmpImg,leftImg); - //leftImg = viewImg; - }else - leftImg = mAnimation->getCaptureStereo()->getFrame(cameraLeft); - if (!viewImg.empty() && (mAnimation->getCaptureStereo()->getCamera() == cameraRight)) + cvCopy(&tmpImg, leftImg); + // leftImg = viewImg; + } + else + leftImg = mAnimation->getCaptureStereo()->getFrame(cameraLeft); + if(!viewImg.empty() && (mAnimation->getCaptureStereo()->getCamera() == cameraRight)) { - rightImg = cvCreateImage(cvSize(viewImg.cols,viewImg.rows),8,viewImg.channels()); + rightImg = cvCreateImage(cvSize(viewImg.cols, viewImg.rows), 8, viewImg.channels()); IplImage tmpImg = viewImg; - cvCopy(&tmpImg,rightImg); - //rightImg = viewImg; - - }else + cvCopy(&tmpImg, rightImg); + // rightImg = viewImg; + } + else rightImg = mAnimation->getCaptureStereo()->getFrame(cameraRight); // Background subtraction -// if (brightContrastChanged || borderChanged || calibChanged) -// mBackgroundFilter.reset(); // alle gesammelten hintergrundinfos werden verworfen und bg.changed auf true gesetzt -// if (imageChanged || mBackgroundFilter.changed()) -// mIplImgFiltered = mBackgroundFilter.apply(mIplImgFiltered); -// else -// mIplImgFiltered = mBackgroundFilter.getLastResult(); - -// leftImg = mBackgroundFilterLeft.apply(leftImg); -// rightImg = mBackgroundFilterRight.apply(rightImg); - - - - -//// um ptgrey die schon entzerrten virtuellen Bilder unterzuschieben -//// dazu muesste zudem 2x der bereich um triclopsGetImage auskommentiert werden -//#ifdef TMP_STEREO_SEQ -// // temporaere code um stereo-einzelbildfolge einzulesen: -// if (tempLeftImg != NULL) -// cvReleaseImage(&tempLeftImg); - -// QString fn = QString(STEREO_SEQ_FILEBASE) + QString("left_%1.png").arg(mAnimation->getCurrentFrameNum()%(STEREO_SEQ_LAST_FRAME-STEREO_SEQ_FIRST_FRAME+1) + STEREO_SEQ_FIRST_FRAME, 3, 10, QChar('0')); // [2,159] -// leftImg=cvLoadImage((char *) fn.toAscii().data(), CV_LOAD_IMAGE_GRAYSCALE); //-1); - -// // temporaere code um stereo-einzelbildfolge einzulesen: ----------------------------------------------------------------------------------------------------- -// if (tempRightImg != NULL) -// cvReleaseImage(&tempRightImg); -// fn = QString(STEREO_SEQ_FILEBASE) + QString("right_%1.png").arg(mAnimation->getCurrentFrameNum()%(STEREO_SEQ_LAST_FRAME-STEREO_SEQ_FIRST_FRAME+1) + STEREO_SEQ_FIRST_FRAME, 3, 10, QChar('0')); // [2,159] -// rightImg=cvLoadImage((char *) fn.toAscii().data(), CV_LOAD_IMAGE_GRAYSCALE); //-1); -//#endif - - - + // if (brightContrastChanged || borderChanged || calibChanged) + // mBackgroundFilter.reset(); // alle gesammelten hintergrundinfos werden verworfen und bg.changed auf + // true gesetzt + // if (imageChanged || mBackgroundFilter.changed()) + // mIplImgFiltered = mBackgroundFilter.apply(mIplImgFiltered); + // else + // mIplImgFiltered = mBackgroundFilter.getLastResult(); + + // leftImg = mBackgroundFilterLeft.apply(leftImg); + // rightImg = mBackgroundFilterRight.apply(rightImg); + + + //// um ptgrey die schon entzerrten virtuellen Bilder unterzuschieben + //// dazu muesste zudem 2x der bereich um triclopsGetImage auskommentiert werden + //#ifdef TMP_STEREO_SEQ + // // temporaere code um stereo-einzelbildfolge einzulesen: + // if (tempLeftImg != NULL) + // cvReleaseImage(&tempLeftImg); + + // QString fn = QString(STEREO_SEQ_FILEBASE) + + // QString("left_%1.png").arg(mAnimation->getCurrentFrameNum()%(STEREO_SEQ_LAST_FRAME-STEREO_SEQ_FIRST_FRAME+1) + // + STEREO_SEQ_FIRST_FRAME, 3, 10, QChar('0')); // [2,159] leftImg=cvLoadImage((char *) + // fn.toAscii().data(), CV_LOAD_IMAGE_GRAYSCALE); //-1); + + // // temporaere code um stereo-einzelbildfolge einzulesen: + // ----------------------------------------------------------------------------------------------------- + // if (tempRightImg != NULL) + // cvReleaseImage(&tempRightImg); + // fn = QString(STEREO_SEQ_FILEBASE) + + // QString("right_%1.png").arg(mAnimation->getCurrentFrameNum()%(STEREO_SEQ_LAST_FRAME-STEREO_SEQ_FIRST_FRAME+1) + // + STEREO_SEQ_FIRST_FRAME, 3, 10, QChar('0')); // [2,159] rightImg=cvLoadImage((char *) + // fn.toAscii().data(), CV_LOAD_IMAGE_GRAYSCALE); //-1); + //#endif triclopsError = triclopsBuildRGBTriclopsInput( - leftImg->width, - leftImg->height, - leftImg->widthStep, - 0, - 0, - (unsigned char *) rightImg->imageData, - (unsigned char *) leftImg->imageData, - NULL, - &mTriclopsInput); - if (triclopsError != TriclopsErrorOk) + leftImg->width, + leftImg->height, + leftImg->widthStep, + 0, + 0, + (unsigned char *) rightImg->imageData, + (unsigned char *) leftImg->imageData, + NULL, + &mTriclopsInput); + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; #endif - //cvInitImageHeader(&mDisparity, cvSize(mTriDisparity.ncols, mTriDisparity.nrows), 16, 1); + // cvInitImageHeader(&mDisparity, cvSize(mTriDisparity.ncols, mTriDisparity.nrows), 16, 1); cvInitImageHeader(&mDisparity, cvSize(leftImg->width, leftImg->height), 16, 1); setStatus(buildInput); @@ -281,28 +284,27 @@ void pet::StereoContext::init(Mat &viewImg) // = NULL void pet::StereoContext::preprocess() { - if (mStatus & buildInput) + if(mStatus & buildInput) { - #ifdef STEREO TriclopsError triclopsError; triclopsError = triclopsSetEdgeCorrelation(mTriclopsContext, mMain->getStereoWidget()->useEdge->isChecked()); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; triclopsError = triclopsSetEdgeMask(mTriclopsContext, mMain->getStereoWidget()->edgeMaskSize->value()); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << " for the edge mask size!" << endl; // Preprocessing the images triclopsError = triclopsPreprocess(mTriclopsContext, &mTriclopsInput); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) debout << triclopsErrorToString(triclopsError) << endl; setStatus(preprocessed); #endif -// TriclopsBool b; -// triclopsGetLowpass(mTriclopsContext, &b); -// debout << b <<endl; == true !!!! + // TriclopsBool b; + // triclopsGetLowpass(mTriclopsContext, &b); + // debout << b <<endl; == true !!!! } } @@ -311,21 +313,21 @@ IplImage *pet::StereoContext::getRectified(enum Camera camera) { #ifdef TIME_MEASUREMENT // "==========: " - debout << "in rectify: " << getElapsedTime() <<endl; + debout << "in rectify: " << getElapsedTime() << endl; #endif - if ((camera != cameraRight) && (camera != cameraLeft)) + if((camera != cameraRight) && (camera != cameraLeft)) camera = mAnimation->getCaptureStereo()->getCamera(); - if (mStatus & preprocessed) + if(mStatus & preprocessed) { #ifdef STEREO TriclopsError triclopsError; - if (camera == cameraLeft) + if(camera == cameraLeft) { triclopsError = triclopsGetImage(mTriclopsContext, TriImg_RECTIFIED, TriCam_LEFT, &mTriRectLeft); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) { debout << triclopsErrorToString(triclopsError) << endl; return NULL; @@ -338,54 +340,53 @@ IplImage *pet::StereoContext::getRectified(enum Camera camera) mRectLeft.imageData = (char *) mTriRectLeft.data; // mRectLeft.depth = 8; // mRectLeft.nChannels = 1; - addStatus(rectified); // nicht set, da rectified image kann mehrmals abgefragt werden, wobei die disp schon fertig gerechnet wurde - - - - -// IplImage* tempImg = cvLoadImage(D:/diss/personModel/ownPerson/movie/left_090.png, -1); -// // Is it created? -// if (tempImg == NULL) -// return NULL; -// // delete first old data -// //cvReleaseImage(&mImage); darf nicht freigegeben werden -> absturz, aber speicher wird woanders freigegeben, keine speicheranhaeufung -// // We create and copy the frame to our IplImage pointer -// cvReleaseImage(&mImage); // lieber vorher loeschen statt kopieren da ggf borderfilter bild groesser amcht?! -// mImage = cvCloneImage(tempImg); -// // naechsten beiden zeilen entsprechen oberer: -// //mImage = cvCreateImage(cvGetSize(mTempImg), 8, 3); -// //cvCopy(mTempImg, mImage, 0); -// // We release the temporary IplImage -// cvReleaseImage(&tempImg); - - - - + addStatus(rectified); // nicht set, da rectified image kann mehrmals abgefragt werden, wobei die disp schon + // fertig gerechnet wurde + + + // IplImage* tempImg = cvLoadImage(D:/diss/personModel/ownPerson/movie/left_090.png, -1); + // // Is it created? + // if (tempImg == NULL) + // return NULL; + // // delete first old data + // //cvReleaseImage(&mImage); darf nicht freigegeben werden -> absturz, aber speicher wird + // woanders freigegeben, keine speicheranhaeufung + // // We create and copy the frame to our IplImage pointer + // cvReleaseImage(&mImage); // lieber vorher loeschen statt kopieren da ggf borderfilter bild + // groesser amcht?! mImage = cvCloneImage(tempImg); + // // naechsten beiden zeilen entsprechen oberer: + // //mImage = cvCreateImage(cvGetSize(mTempImg), 8, 3); + // //cvCopy(mTempImg, mImage, 0); + // // We release the temporary IplImage + // cvReleaseImage(&tempImg); #ifdef TMP_STEREO_SEQ // temporaere code um stereo-einzelbildfolge einzulesen: - //static IplImage* tempLeftImg = NULL; - if (tempLeftImg != NULL) + // static IplImage* tempLeftImg = NULL; + if(tempLeftImg != NULL) cvReleaseImage(&tempLeftImg); - QString fn = QString(STEREO_SEQ_FILEBASE) + QString("left_%1.png").arg(mAnimation->getCurrentFrameNum()%(STEREO_SEQ_LAST_FRAME-STEREO_SEQ_FIRST_FRAME+1) + STEREO_SEQ_FIRST_FRAME, 3, 10, QChar('0')); // [2,159] - //debout << fn << endl; - return tempLeftImg=cvLoadImage((char *) fn.toAscii().data(), CV_LOAD_IMAGE_GRAYSCALE); //-1); + QString fn = + QString(STEREO_SEQ_FILEBASE) + + QString("left_%1.png") + .arg( + mAnimation->getCurrentFrameNum() % (STEREO_SEQ_LAST_FRAME - STEREO_SEQ_FIRST_FRAME + 1) + + STEREO_SEQ_FIRST_FRAME, + 3, + 10, + QChar('0')); // [2,159] + // debout << fn << endl; + return tempLeftImg = cvLoadImage((char *) fn.toAscii().data(), CV_LOAD_IMAGE_GRAYSCALE); //-1); #endif - - - - - return &mRectLeft; } - else if (camera == cameraRight) + else if(camera == cameraRight) { triclopsError = triclopsGetImage(mTriclopsContext, TriImg_RECTIFIED, TriCam_RIGHT, &mTriRectRight); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) { debout << triclopsErrorToString(triclopsError) << endl; return NULL; @@ -400,33 +401,29 @@ IplImage *pet::StereoContext::getRectified(enum Camera camera) addStatus(rectified); - - - - - - #ifdef TMP_STEREO_SEQ - // temporaere code um stereo-einzelbildfolge einzulesen: ----------------------------------------------------------------------------------------------------- - //static IplImage* tempImg = NULL; - if (tempRightImg != NULL) + // temporaere code um stereo-einzelbildfolge einzulesen: + // ----------------------------------------------------------------------------------------------------- + // static IplImage* tempImg = NULL; + if(tempRightImg != NULL) cvReleaseImage(&tempRightImg); - QString fn = QString(STEREO_SEQ_FILEBASE) + QString("right_%1.png").arg(mAnimation->getCurrentFrameNum()%(STEREO_SEQ_LAST_FRAME-STEREO_SEQ_FIRST_FRAME+1) + STEREO_SEQ_FIRST_FRAME, 3, 10, QChar('0')); // [2,159] - //debout << fn << endl; - return tempRightImg=cvLoadImage((char *) fn.toAscii().data(), CV_LOAD_IMAGE_GRAYSCALE); //-1); + QString fn = + QString(STEREO_SEQ_FILEBASE) + + QString("right_%1.png") + .arg( + mAnimation->getCurrentFrameNum() % (STEREO_SEQ_LAST_FRAME - STEREO_SEQ_FIRST_FRAME + 1) + + STEREO_SEQ_FIRST_FRAME, + 3, + 10, + QChar('0')); // [2,159] + // debout << fn << endl; + return tempRightImg = cvLoadImage((char *) fn.toAscii().data(), CV_LOAD_IMAGE_GRAYSCALE); //-1); #endif - - - - - - - #ifdef TIME_MEASUREMENT - // "==========: " - debout << "ou rectify: " << getElapsedTime() <<endl; + // "==========: " + debout << "ou rectify: " << getElapsedTime() << endl; #endif @@ -441,12 +438,12 @@ IplImage *pet::StereoContext::getRectified(enum Camera camera) } //// A function to draw the histogram -//IplImage* DrawHistogram(CvHistogram *hist, float scaleX=1, float scaleY=1) +// IplImage* DrawHistogram(CvHistogram *hist, float scaleX=1, float scaleY=1) //{ -// // Find the maximum value of the histogram to scale -// // other values accordingly -// float histMax = 0; -// cvGetMinMaxHistValue(hist, 0, &histMax, 0, 0); +// // Find the maximum value of the histogram to scale +// // other values accordingly +// float histMax = 0; +// cvGetMinMaxHistValue(hist, 0, &histMax, 0, 0); // // Create a new blank image based on scaleX and scaleY // IplImage* imgHist = cvCreateImage(cvSize(256*scaleX, 64*scaleY), 8 ,1); @@ -482,209 +479,227 @@ IplImage *pet::StereoContext::getDisparity(bool *dispNew) { #ifdef TIME_MEASUREMENT // "==========: " - debout << "in disp: " << getElapsedTime() <<endl; + debout << "in disp: " << getElapsedTime() << endl; #endif - if (dispNew != NULL) + if(dispNew != NULL) *dispNew = false; - if ((mStatus & preprocessed) && !(mStatus & genDisparity)) + if((mStatus & preprocessed) && !(mStatus & genDisparity)) { #ifdef STEREO TriclopsError triclopsError; #endif - if (mMain->getStereoWidget()->minDisparity->value() >= mMain->getStereoWidget()->maxDisparity->value()) + if(mMain->getStereoWidget()->minDisparity->value() >= mMain->getStereoWidget()->maxDisparity->value()) { - debout << "Error: Invalid min/max settings for disparity (min>=max)!" <<endl; + debout << "Error: Invalid min/max settings for disparity (min>=max)!" << endl; return NULL; } -// opencv disp BM block matching ---------------------------------------------------------------------------------------------- - -// CvMat* BMdisparity = cvCreateMat(mRectRight.height, mRectRight.width, CV_32FC1); // CV_16S -// CvStereoBMState *BMState = cvCreateStereoBMState(CV_STEREO_BM_BASIC, 64); // 16; durch 16 teilbar -// if (BMState == NULL) -// debout << "Error: setting up the block matching state!" << endl; -//// int edgeMaskSize = mMain->getStereoWidget()->edgeMaskSize->value()*4+1; // +1 wg ungerade -//// BMState->preFilterSize = (edgeMaskSize>255?255:(edgeMaskSize<5?5:edgeMaskSize));//19; 41 -//// debout << BMState->preFilterSize << endl; -//// BMState->preFilterCap=19; 31 -// BMState->minDisparity = mMain->getStereoWidget()->minDisparity->value(); -// BMState->numberOfDisparities = 16*(1+(mMain->getStereoWidget()->maxDisparity->value()-mMain->getStereoWidget()->minDisparity->value())/16); // muss durch 16 teilbar sein -// BMState->SADWindowSize = mMain->getStereoWidget()->stereoMaskSize->value()>=5?mMain->getStereoWidget()->stereoMaskSize->value():5; // minimum 5 erlaubt -//// BMState->textureThreshold=d; 10 -//// BMState->uniquenessRatio=e; 15 -// debout << BMState->numberOfDisparities<<endl; - -// //Computes the disparity map using block matching algorithm. -// // * disparity � The output single-channel 16-bit signed, or 32-bit floating-point disparity map of the same size as input images. -// // In the first case the computed disparities are represented as fixed-point numbers with 4 fractional bits -// // (i.e. the computed disparity values are multiplied by 16 and rounded to integers). -// //The function cvFindStereoCorrespondenceBM computes disparity map for the input rectified stereo pair. -// //Invalid pixels (for which disparity can not be computed) are set to state->minDisparity - 1 (or to (state->minDisparity-1)*16 -// //in the case of 16-bit fixed-point disparity map) - -// cvFindStereoCorrespondenceBM(getRectified(cameraLeft), getRectified(cameraRight), BMdisparity, BMState); // &mRectLeft, &mRectRight - - // opencv disp GC graph cut matching ---------------------------------------------------------------------------------------------- - // folgende fkt soll genauer sein, dauert aber sehr lange und hat keine subpixelgenauigkeit - -// CvMat* GCdisparityLeft = cvCreateMat(mRectRight.height, mRectRight.width, CV_16S); // CV_32FC1 -// CvMat* GCdisparityRight = cvCreateMat(mRectRight.height, mRectRight.width, CV_16S); // CV_32FC1 -// CvStereoGCState* GCState = cvCreateStereoGCState(0, 2); // min 0, Iterationen 2 - -// GCState->minDisparity = mMain->getStereoWidget()->minDisparity->value(); -// GCState->numberOfDisparities = mMain->getStereoWidget()->maxDisparity->value()-mMain->getStereoWidget()->minDisparity->value(); //16*(1+(mMain->getStereoWidget()->maxDisparity->value()-mMain->getStereoWidget()->minDisparity->value())/16); // muss durch 16 teilbar sein - -// cvFindStereoCorrespondenceGC(getRectified(cameraLeft), getRectified(cameraRight), GCdisparityLeft, GCdisparityRight, GCState); // &mRectLeft, &mRectRight - -// cvReleaseStereoGCState(&state); - -// CvMat* GCdisparityLeft_visual = cvCreateMat(mRectRight.height, mRectRight.width, CV_8U); -// cvConvertScale(GCdisparityLeft, GCdisparityLeft_visual, -16); -// cvNamedWindow("CVdispGCleft", CV_WINDOW_AUTOSIZE); -// cvShowImage("CVdispGCleft", GCdisparityLeft_visual); - -// CvMat* GCdisparityRight_visual = cvCreateMat(mRectRight.height, mRectRight.width, CV_8U); -// cvConvertScale(GCdisparityRight, GCdisparityRight_visual, 16); -// cvNamedWindow("CVdispGCright", CV_WINDOW_AUTOSIZE); -// cvShowImage("CVdispGCright", GCdisparityRight_visual); + // opencv disp BM block matching + // ---------------------------------------------------------------------------------------------- + + // CvMat* BMdisparity = cvCreateMat(mRectRight.height, mRectRight.width, CV_32FC1); // CV_16S + // CvStereoBMState *BMState = cvCreateStereoBMState(CV_STEREO_BM_BASIC, 64); // 16; durch 16 teilbar + // if (BMState == NULL) + // debout << "Error: setting up the block matching state!" << endl; + //// int edgeMaskSize = mMain->getStereoWidget()->edgeMaskSize->value()*4+1; // +1 wg ungerade + //// BMState->preFilterSize = (edgeMaskSize>255?255:(edgeMaskSize<5?5:edgeMaskSize));//19; 41 + //// debout << BMState->preFilterSize << endl; + //// BMState->preFilterCap=19; 31 + // BMState->minDisparity = mMain->getStereoWidget()->minDisparity->value(); + // BMState->numberOfDisparities = + // 16*(1+(mMain->getStereoWidget()->maxDisparity->value()-mMain->getStereoWidget()->minDisparity->value())/16); + // // muss durch 16 teilbar sein BMState->SADWindowSize = + // mMain->getStereoWidget()->stereoMaskSize->value()>=5?mMain->getStereoWidget()->stereoMaskSize->value():5; + // // minimum 5 erlaubt + //// BMState->textureThreshold=d; 10 + //// BMState->uniquenessRatio=e; 15 + // debout << BMState->numberOfDisparities<<endl; + + // //Computes the disparity map using block matching algorithm. + // // * disparity � The output single-channel 16-bit signed, or 32-bit floating-point disparity map of + // the same size as input images. + // // In the first case the computed disparities are represented as fixed-point numbers + // with 4 fractional bits + // // (i.e. the computed disparity values are multiplied by 16 and rounded to integers). + // //The function cvFindStereoCorrespondenceBM computes disparity map for the input rectified stereo + // pair. + // //Invalid pixels (for which disparity can not be computed) are set to state->minDisparity - 1 (or to + // (state->minDisparity-1)*16 + // //in the case of 16-bit fixed-point disparity map) + + // cvFindStereoCorrespondenceBM(getRectified(cameraLeft), getRectified(cameraRight), BMdisparity, + // BMState); // &mRectLeft, &mRectRight + + // opencv disp GC graph cut matching + // ---------------------------------------------------------------------------------------------- folgende fkt + // soll genauer sein, dauert aber sehr lange und hat keine subpixelgenauigkeit + + // CvMat* GCdisparityLeft = cvCreateMat(mRectRight.height, mRectRight.width, CV_16S); // CV_32FC1 + // CvMat* GCdisparityRight = cvCreateMat(mRectRight.height, mRectRight.width, CV_16S); // CV_32FC1 + // CvStereoGCState* GCState = cvCreateStereoGCState(0, 2); // min 0, Iterationen 2 + + // GCState->minDisparity = mMain->getStereoWidget()->minDisparity->value(); + // GCState->numberOfDisparities = + // mMain->getStereoWidget()->maxDisparity->value()-mMain->getStereoWidget()->minDisparity->value(); + // //16*(1+(mMain->getStereoWidget()->maxDisparity->value()-mMain->getStereoWidget()->minDisparity->value())/16); + // // muss durch 16 teilbar sein + + // cvFindStereoCorrespondenceGC(getRectified(cameraLeft), getRectified(cameraRight), GCdisparityLeft, + // GCdisparityRight, GCState); // &mRectLeft, &mRectRight + + // cvReleaseStereoGCState(&state); + + // CvMat* GCdisparityLeft_visual = cvCreateMat(mRectRight.height, mRectRight.width, CV_8U); + // cvConvertScale(GCdisparityLeft, GCdisparityLeft_visual, -16); + // cvNamedWindow("CVdispGCleft", CV_WINDOW_AUTOSIZE); + // cvShowImage("CVdispGCleft", GCdisparityLeft_visual); + + // CvMat* GCdisparityRight_visual = cvCreateMat(mRectRight.height, mRectRight.width, CV_8U); + // cvConvertScale(GCdisparityRight, GCdisparityRight_visual, 16); + // cvNamedWindow("CVdispGCright", CV_WINDOW_AUTOSIZE); + // cvShowImage("CVdispGCright", GCdisparityRight_visual); // minmax -------------------------- -// float GCdisparityMin = FLT_MAX; -// float GCdisparityMax = 0; - -// float* GCdata = (float*) GCdisparityRight->data.fl;// .imageData; -// float* GCyData = data; -// int x,y; -// int noDispAnz=0; - -// for (y = 0; y < GCdisparityRight->height; ++y) -// { -// for (x = 0; x < GCdisparityRight->width; ++x) -// { -// if (*data != (GCState->minDisparity - 1)) -// { -// if (*data > GCdisparityMax) -// GCdisparityMax = *data; -// else if (*data < GCdisparityMin) -// GCdisparityMin = *data; -// } -// else -// ++noDispAnz; -// ++data; -// } -// data = (yData += (GCdisparityRight->step/sizeof(float))); //width); -// } - -// debout << noDispAnz << " " << GCdisparityMin << " " << GCdisparityMax <<endl; - - // bestimmung von min max --------------------------------------------------------------------------------------------------------------- - -// float BMdisparityMin = FLT_MAX; -// float BMdisparityMax = 0; - -// float* data = (float*) BMdisparity->data.fl;// .imageData; -// float* yData = data; -// int x,y; -// int noDispAnz=0; - -// for (y = 0; y < BMdisparity->height; ++y) -// { -// for (x = 0; x < BMdisparity->width; ++x) -// { -// if (*data != (BMState->minDisparity - 1)) -// { -// if (*data > BMdisparityMax) -// BMdisparityMax = *data; -// else if (*data < BMdisparityMin) -// BMdisparityMin = *data; -// } -// else -// ++noDispAnz; -// ++data; -// } -// data = (yData += (BMdisparity->step/sizeof(float))); //width); -// } - -// debout << noDispAnz << " " << BMdisparityMin << " " << BMdisparityMax <<endl; - -// double dMin, dMax; -// cvMinMaxLoc(BMdisparity, &dMin, &dMax); -// debout << (BMState->minDisparity - 1) << " " << dMin << " " << dMax <<endl; - -// BMdisparityMin = mMain->getStereoWidget()->minDisparity->value(); -// BMdisparityMax = mMain->getStereoWidget()->maxDisparity->value(); -// debout << BMdisparityMin << " " << BMdisparityMax <<endl; - -// Ausgabe der opencv disp --------------------------------------------------------------------------------------------------------------- - -// IplImage* BMdisparityImg = cvCreateImage(cvSize(mRectRight.width,mRectRight.height),IPL_DEPTH_8U,3); -// unsigned char* dataImg = ((unsigned char*) BMdisparityImg->imageData); // char* -// unsigned char* yDataImg = dataImg; -// QColor color; -// int hue; - -// yData = data = (float*) BMdisparity->data.fl; -// --dataImg; - -// for (y = 0; y < BMdisparity->height; ++y) -// { -// for (x = 0; x < BMdisparity->width; ++x) -// { -// if (*data != (BMState->minDisparity - 1)) -// { -// hue = ((*data-BMdisparityMin)*240.)/(BMdisparityMax-BMdisparityMin); -// if (hue<0 || hue>240) -// color.setHsv(0, 0, 255, 255); // white for values outside min/max -// else -// color.setHsv(hue, 255, 255, 255); // hue<0?0:(hue>240?240:hue) -// } -// else -// color.setHsv(0, 0, 0, 255); // black, if no value - -// ++data; - -// *(++dataImg) = color.red(); -// *(++dataImg) = color.green(); -// *(++dataImg) = color.blue(); -// } -// data = (yData += (BMdisparity->step/sizeof(float))); //width); -// dataImg = (yDataImg += BMdisparityImg->widthStep/sizeof(char)); //width); -// } - -// cvNamedWindow("CVdisp", CV_WINDOW_AUTOSIZE); -// cvShowImage("CVdisp", BMdisparityImg); - - - -// // histogram ---------------------------------------------------------------------------------------------------------- - - //http://opencv.willowgarage.com/documentation/c/histograms.html -// // let's quantize the hue to 30 levels -// // and the saturation to 32 levels -// int bins = 256; //, sbins = 32; -// int histSize[] = {bins}; //, sbins}; -// //float range[] = { 0, 256 }; -// //float* ranges[] = {range}; //s, sranges }; -// CvHistogram* hist = cvCreateHist(1, histSize, CV_HIST_ARRAY); // ,ranges -// cvCalcHist((IplImage**) &BMdisparity, hist); - -//// double maxVal=0; -//// minMaxLoc(hist, 0, &maxVal, 0, 0); - -// cvNamedWindow("Histogram", CV_WINDOW_AUTOSIZE); -// cvShowImage("Histogram", DrawHistogram(hist, 1, 1)); // DrawHistogram ist auskommentierte fkt von oiben - -// // freigabe --------------------------------------------------------------------------------------------------- - -// cvReleaseImage(&BMdisparityImg); -// cvReleaseMat(&BMdisparity); -// cvReleaseStereoBMState(&BMState); - -// //------------------------------------------------------------------------------------------------------------------------ - - if (mMain->getStereoWidget()->stereoDispAlgo->currentIndex() == 0) // ptGrey ------------------------------------------------------- + // float GCdisparityMin = FLT_MAX; + // float GCdisparityMax = 0; + + // float* GCdata = (float*) GCdisparityRight->data.fl;// .imageData; + // float* GCyData = data; + // int x,y; + // int noDispAnz=0; + + // for (y = 0; y < GCdisparityRight->height; ++y) + // { + // for (x = 0; x < GCdisparityRight->width; ++x) + // { + // if (*data != (GCState->minDisparity - 1)) + // { + // if (*data > GCdisparityMax) + // GCdisparityMax = *data; + // else if (*data < GCdisparityMin) + // GCdisparityMin = *data; + // } + // else + // ++noDispAnz; + // ++data; + // } + // data = (yData += (GCdisparityRight->step/sizeof(float))); //width); + // } + + // debout << noDispAnz << " " << GCdisparityMin << " " << GCdisparityMax <<endl; + + // bestimmung von min max + // --------------------------------------------------------------------------------------------------------------- + + // float BMdisparityMin = FLT_MAX; + // float BMdisparityMax = 0; + + // float* data = (float*) BMdisparity->data.fl;// .imageData; + // float* yData = data; + // int x,y; + // int noDispAnz=0; + + // for (y = 0; y < BMdisparity->height; ++y) + // { + // for (x = 0; x < BMdisparity->width; ++x) + // { + // if (*data != (BMState->minDisparity - 1)) + // { + // if (*data > BMdisparityMax) + // BMdisparityMax = *data; + // else if (*data < BMdisparityMin) + // BMdisparityMin = *data; + // } + // else + // ++noDispAnz; + // ++data; + // } + // data = (yData += (BMdisparity->step/sizeof(float))); //width); + // } + + // debout << noDispAnz << " " << BMdisparityMin << " " << BMdisparityMax <<endl; + + // double dMin, dMax; + // cvMinMaxLoc(BMdisparity, &dMin, &dMax); + // debout << (BMState->minDisparity - 1) << " " << dMin << " " << dMax <<endl; + + // BMdisparityMin = mMain->getStereoWidget()->minDisparity->value(); + // BMdisparityMax = mMain->getStereoWidget()->maxDisparity->value(); + // debout << BMdisparityMin << " " << BMdisparityMax <<endl; + + // Ausgabe der opencv disp + // --------------------------------------------------------------------------------------------------------------- + + // IplImage* BMdisparityImg = + // cvCreateImage(cvSize(mRectRight.width,mRectRight.height),IPL_DEPTH_8U,3); unsigned char* dataImg = + // ((unsigned char*) BMdisparityImg->imageData); // char* unsigned char* yDataImg = dataImg; QColor + // color; int hue; + + // yData = data = (float*) BMdisparity->data.fl; + // --dataImg; + + // for (y = 0; y < BMdisparity->height; ++y) + // { + // for (x = 0; x < BMdisparity->width; ++x) + // { + // if (*data != (BMState->minDisparity - 1)) + // { + // hue = ((*data-BMdisparityMin)*240.)/(BMdisparityMax-BMdisparityMin); + // if (hue<0 || hue>240) + // color.setHsv(0, 0, 255, 255); // white for values outside min/max + // else + // color.setHsv(hue, 255, 255, 255); // hue<0?0:(hue>240?240:hue) + // } + // else + // color.setHsv(0, 0, 0, 255); // black, if no value + + // ++data; + + // *(++dataImg) = color.red(); + // *(++dataImg) = color.green(); + // *(++dataImg) = color.blue(); + // } + // data = (yData += (BMdisparity->step/sizeof(float))); //width); + // dataImg = (yDataImg += BMdisparityImg->widthStep/sizeof(char)); //width); + // } + + // cvNamedWindow("CVdisp", CV_WINDOW_AUTOSIZE); + // cvShowImage("CVdisp", BMdisparityImg); + + + // // histogram + // ---------------------------------------------------------------------------------------------------------- + + // http://opencv.willowgarage.com/documentation/c/histograms.html + // // let's quantize the hue to 30 levels + // // and the saturation to 32 levels + // int bins = 256; //, sbins = 32; + // int histSize[] = {bins}; //, sbins}; + // //float range[] = { 0, 256 }; + // //float* ranges[] = {range}; //s, sranges }; + // CvHistogram* hist = cvCreateHist(1, histSize, CV_HIST_ARRAY); // ,ranges + // cvCalcHist((IplImage**) &BMdisparity, hist); + + //// double maxVal=0; + //// minMaxLoc(hist, 0, &maxVal, 0, 0); + + // cvNamedWindow("Histogram", CV_WINDOW_AUTOSIZE); + // cvShowImage("Histogram", DrawHistogram(hist, 1, 1)); // DrawHistogram ist auskommentierte fkt von + // oiben + + // // freigabe + // --------------------------------------------------------------------------------------------------- + + // cvReleaseImage(&BMdisparityImg); + // cvReleaseMat(&BMdisparity); + // cvReleaseStereoBMState(&BMState); + + // //------------------------------------------------------------------------------------------------------------------------ + + if(mMain->getStereoWidget()->stereoDispAlgo->currentIndex() == + 0) // ptGrey ------------------------------------------------------- { //// Description: This structure is used for image output from the Triclops //// system for image types that require 16-bits per pixel. This is the format @@ -694,41 +709,43 @@ IplImage *pet::StereoContext::getDisparity(bool *dispNew) //// the beginning of a row and the beginning of the following row //// (NOT number of pixels). //// - //typedef struct TriclopsImage16 + // typedef struct TriclopsImage16 //{ - // // The number of rows in the image. - // int nrows; - // // The number of columns in the image. - // int ncols; - // // The number row increment of the image. - // int rowinc; - // // The pixel data of the image. - // unsigned short* data; + // // The number of rows in the image. + // int nrows; + // // The number of columns in the image. + // int ncols; + // // The number row increment of the image. + // int rowinc; + // // The pixel data of the image. + // unsigned short* data; // - //} TriclopsImage16; + // } TriclopsImage16; #ifdef STEREO // set values for stereo processing - triclopsError = triclopsSetDisparity(mTriclopsContext, - mMain->getStereoWidget()->minDisparity->value(), - mMain->getStereoWidget()->maxDisparity->value()); // ,100// 22, 66); // set disparity range 14..36 bei mu oder mo untere kamera - if (triclopsError != TriclopsErrorOk) - debout << triclopsErrorToString(triclopsError) << " for the disparity range!" << endl; + triclopsError = triclopsSetDisparity( + mTriclopsContext, + mMain->getStereoWidget()->minDisparity->value(), + mMain->getStereoWidget()->maxDisparity->value()); // ,100// 22, 66); // set disparity range 14..36 bei + // mu oder mo untere kamera + if(triclopsError != TriclopsErrorOk) + debout << triclopsErrorToString(triclopsError) << " for the disparity range!" << endl; triclopsError = triclopsSetStereoMask(mTriclopsContext, mMain->getStereoWidget()->stereoMaskSize->value()); - if (triclopsError != TriclopsErrorOk) - debout << triclopsErrorToString(triclopsError) << " for the stereo mask size!" << endl; + if(triclopsError != TriclopsErrorOk) + debout << triclopsErrorToString(triclopsError) << " for the stereo mask size!" << endl; // Do stereo processing triclopsError = triclopsStereo(mTriclopsContext); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) { debout << triclopsErrorToString(triclopsError) << endl; return NULL; } triclopsError = triclopsGetImage16(mTriclopsContext, TriImg16_DISPARITY, TriCam_REFERENCE, &mTriDisparity); - if (triclopsError != TriclopsErrorOk) + if(triclopsError != TriclopsErrorOk) { debout << triclopsErrorToString(triclopsError) << endl; return NULL; @@ -737,51 +754,73 @@ IplImage *pet::StereoContext::getDisparity(bool *dispNew) mDisparity.imageData = (char *) mTriDisparity.data; #endif } - else if (mMain->getStereoWidget()->stereoDispAlgo->currentIndex() == 1) // openCV Block Matching ---------------------------------------------------------------------------------------------------------------------------- + else if( + mMain->getStereoWidget()->stereoDispAlgo->currentIndex() == + 1) // openCV Block Matching + // ---------------------------------------------------------------------------------------------------------------------------- { // Bestimmung CV_16S und Ausgabe der opencv disp - if (!mBMState) // noch =NULL + if(!mBMState) // noch =NULL { mBMState = cvCreateStereoBMState(CV_STEREO_BM_BASIC, 64); // 16; durch 16 teilbar - if (mBMState == NULL) - debout << "Error: setting up the block matching state!" << endl; + if(mBMState == NULL) + debout << "Error: setting up the block matching state!" << endl; } // int edgeMaskSize = mMain->getStereoWidget()->edgeMaskSize->value()*4+1; // +1 wg ungerade // mBMState->preFilterSize = (edgeMaskSize>255?255:(edgeMaskSize<5?5:edgeMaskSize));//19; 41 // debout << mBMState->preFilterSize << endl; // mBMState->preFilterCap=19; 31 - mBMState->SADWindowSize = myClip(mMain->getStereoWidget()->stereoMaskSize->value(), 5, 21); //>=5?mMain->getStereoWidget()->stereoMaskSize->value():5; // minimum 5 erlaubt, ab 21 wird zuviel als mindens und maxdens angezeigt! + mBMState->SADWindowSize = myClip( + mMain->getStereoWidget()->stereoMaskSize->value(), + 5, + 21); //>=5?mMain->getStereoWidget()->stereoMaskSize->value():5; // minimum 5 erlaubt, ab 21 wird zuviel + // als mindens und maxdens angezeigt! // mBMState->textureThreshold=d; 10 // mBMState->uniquenessRatio=e; 15 - // umkehrung der disparity, da links und rechts vertauscht werden musste, damit disp fuer rechtes bild berechnet wird - mBMState->minDisparity = -(mMain->getStereoWidget()->maxDisparity->value())+1; // +1, weil es dann mit ptgrey fuer min besser passt - mBMState->numberOfDisparities = 16*((mMain->getStereoWidget()->maxDisparity->value()-mMain->getStereoWidget()->minDisparity->value())/16); // muss durch 16 teilbar sein - if (mBMState->numberOfDisparities < 16) // mind 16 ist vorgeschrieben + // umkehrung der disparity, da links und rechts vertauscht werden musste, damit disp fuer rechtes bild + // berechnet wird + mBMState->minDisparity = -(mMain->getStereoWidget()->maxDisparity->value()) + + 1; // +1, weil es dann mit ptgrey fuer min besser passt + mBMState->numberOfDisparities = + 16 * + ((mMain->getStereoWidget()->maxDisparity->value() - mMain->getStereoWidget()->minDisparity->value()) / + 16); // muss durch 16 teilbar sein + if(mBMState->numberOfDisparities < 16) // mind 16 ist vorgeschrieben mBMState->numberOfDisparities = 16; - if (!mBMdisparity16) + if(!mBMdisparity16) { - mBMdisparity16 = cvCreateMat(mDisparity.height, mDisparity.width, CV_16S); // mRectRight.height, mRectRight.width gehtz nicht da ggf noch nicht vorliegend - if (mBMdisparity16 == NULL) - debout << "Error: create matrix for block matching disparity map!" << endl; + mBMdisparity16 = cvCreateMat( + mDisparity.height, + mDisparity.width, + CV_16S); // mRectRight.height, mRectRight.width gehtz nicht da ggf noch nicht vorliegend + if(mBMdisparity16 == NULL) + debout << "Error: create matrix for block matching disparity map!" << endl; } - // folgendes kann nicht genutzt werden um rechenzeiut zu sparen, da rectified nach erstem durchlauf dieser fkt auch mit ptgrey gesetzt wird, dabei aber nicht mrectleft gesetzt wird -// if (mStatus & rectified) -// cvFindStereoCorrespondenceBM(&mRectRight, &mRectLeft, mBMdisparity16, mBMState); -// else -// -// cv::StereoBM::compute(getRectified(cameraRight),getRectified(cameraLeft),mBMdisparity16); + // folgendes kann nicht genutzt werden um rechenzeiut zu sparen, da rectified nach erstem durchlauf dieser + // fkt auch mit ptgrey gesetzt wird, dabei aber nicht mrectleft gesetzt wird + // if (mStatus & rectified) + // cvFindStereoCorrespondenceBM(&mRectRight, &mRectLeft, mBMdisparity16, mBMState); + // else + // + // cv::StereoBM::compute(getRectified(cameraRight),getRectified(cameraLeft),mBMdisparity16); - cvFindStereoCorrespondenceBM(getRectified(cameraRight), getRectified(cameraLeft), mBMdisparity16, mBMState); // &mRectRight, &mRectLeft geht nicht, da noch nicht + cvFindStereoCorrespondenceBM( + getRectified(cameraRight), + getRectified(cameraLeft), + mBMdisparity16, + mBMState); // &mRectRight, &mRectLeft geht nicht, da noch nicht -// cvMinMaxLoc(mBMdisparity16, &dMin, &dMax); -// debout << (mBMState->minDisparity-1)*16 << " " << dMin << " " << dMax <<endl; + // cvMinMaxLoc(mBMdisparity16, &dMin, &dMax); + // debout << (mBMState->minDisparity-1)*16 << " " << dMin << " " << dMax <<endl; // CvMat* BMdisparity_visual = cvCreateMat(mRectRight.height, mRectRight.width, CV_8U); - // cvConvertScale(mBMdisparity16, BMdisparity_visual, 255/dMax);//, 255/((mBMState->minDisparity+mBMState->numberOfDisparities)*16));//, 255/dMax); //255/(dMax-mBMState->minDisparity*16), -mBMState->minDisparity); // scale, shift + // cvConvertScale(mBMdisparity16, BMdisparity_visual, 255/dMax);//, + // 255/((mBMState->minDisparity+mBMState->numberOfDisparities)*16));//, 255/dMax); + // //255/(dMax-mBMState->minDisparity*16), -mBMState->minDisparity); // scale, shift // // weiss sind ausreisser nach oben // // mittlerer Grauwert zeigt an, dass nichts gefunden wurde // // schwarz ist 0 und liegt untzer minDisparity @@ -791,54 +830,63 @@ IplImage *pet::StereoContext::getDisparity(bool *dispNew) // cvShowImage("CVdispBM16", BMdisparity_visual); // exchange/replace value in mBMdisparity16 so that the error value is the same like in pointgrey - short* data16 = (short*) mBMdisparity16->data.s; - short* yData16 = data16; + short *data16 = (short *) mBMdisparity16->data.s; + short *yData16 = data16; -// int noDispAnz1 = 0, noDispAnz2 = 0, noDispAnz3 = 0; -// double dMin, dMax; -// cvMinMaxLoc(mBMdisparity16, &dMin, &dMax); -// debout << endl << mBMState->minDisparity << " " << mBMState->minDisparity+mBMState->numberOfDisparities <<endl; -// debout << dMin << " " << dMax <<endl; + // int noDispAnz1 = 0, noDispAnz2 = 0, noDispAnz3 = 0; + // double dMin, dMax; + // cvMinMaxLoc(mBMdisparity16, &dMin, &dMax); + // debout << endl << mBMState->minDisparity << " " << + // mBMState->minDisparity+mBMState->numberOfDisparities <<endl; debout << dMin << " " << dMax + // <<endl; - for (int y = 0; y < mBMdisparity16->height; ++y) + for(int y = 0; y < mBMdisparity16->height; ++y) { - for (int x = 0; x < mBMdisparity16->width; ++x) + for(int x = 0; x < mBMdisparity16->width; ++x) { - //if ((*data16 < (mBMState->minDisparity)*16) || (*data16 > (mBMState->minDisparity+mBMState->numberOfDisparities)*16)) // zeigt genau den Bereich, der auch algo uebergeben wurde - if ((-*data16 < (mMain->getStereoWidget()->minDisparity->value())*16) || - (-*data16 > (mMain->getStereoWidget()->maxDisparity->value())*16) || // laesst nur den Teil ueber, der in gui eingestellt wurde - (*data16 <= (mBMState->minDisparity)*16))// enthaelt auch: (*data16 == (mBMState->minDisparity-1)*16)) // marker fuer nicht berechneten wert + // if ((*data16 < (mBMState->minDisparity)*16) || (*data16 > + // (mBMState->minDisparity+mBMState->numberOfDisparities)*16)) // zeigt genau den Bereich, der auch + // algo uebergeben wurde + if((-*data16 < (mMain->getStereoWidget()->minDisparity->value()) * 16) || + (-*data16 > (mMain->getStereoWidget()->maxDisparity->value()) * + 16) || // laesst nur den Teil ueber, der in gui eingestellt wurde + (*data16 <= + (mBMState->minDisparity) * 16)) // enthaelt auch: (*data16 == (mBMState->minDisparity-1)*16)) // + // marker fuer nicht berechneten wert { -// if (*data16 == (mBMState->minDisparity-1)*16) -// ++noDispAnz1; -// else -// ++noDispAnz2; + // if (*data16 == (mBMState->minDisparity-1)*16) + // ++noDispAnz1; + // else + // ++noDispAnz2; *data16 = 0xFF00; // fehlercode gemaess ptgrey } -// if (*data16 == (mBMState->minDisparity-1)*16) // eigentlicher fehler-wert, wenn nichts erkannt wird; wird durch vorherige abfrage mit geloescht -// { -//// ++noDispAnz; -// *data16 = 0xFF00; -// } -// else if (*data16 > 0) // passiert nicht mehr -// { -// *data16 = 0; //*data16+0x8000; // da signed <-> unsigned: zB bei char: -127 und 255 gleiche bitrepraesentation -//// ++noDispAnz3; -// } + // if (*data16 == (mBMState->minDisparity-1)*16) // eigentlicher fehler-wert, + // wenn nichts erkannt wird; wird durch vorherige abfrage mit geloescht + // { + //// ++noDispAnz; + // *data16 = 0xFF00; + // } + // else if (*data16 > 0) // passiert nicht mehr + // { + // *data16 = 0; //*data16+0x8000; // da signed <-> unsigned: zB bei char: + // -127 und 255 gleiche bitrepraesentation + //// ++noDispAnz3; + // } else // vorzeichen umkehren und // disparityFloat = (float) disparity16 / 256.0; //16-bit in triclops umrechung - *data16 = -*data16*16; // *16, da cv disp nur faktor 16 fuer subpixelgenauigkeit hat und triclops *256 + *data16 = -*data16 * + 16; // *16, da cv disp nur faktor 16 fuer subpixelgenauigkeit hat und triclops *256 // else // *data16 = (unsigned int) *data16; ++data16; } - data16 = (yData16 += (mBMdisparity16->step/sizeof(short))); //width); + data16 = (yData16 += (mBMdisparity16->step / sizeof(short))); // width); } -// debout << noDispAnz1 << " " << noDispAnz2 << " " << noDispAnz3 << " " <<endl; -// cvMinMaxLoc(mBMdisparity16, &dMin, &dMax); -// debout << dMin << " " << dMax <<endl; + // debout << noDispAnz1 << " " << noDispAnz2 << " " << noDispAnz3 << " " <<endl; + // cvMinMaxLoc(mBMdisparity16, &dMin, &dMax); + // debout << dMin << " " << dMax <<endl; // unsigned short int uu; short int ss; // uu = 0x8000; ss = 0x8000; @@ -846,69 +894,80 @@ IplImage *pet::StereoContext::getDisparity(bool *dispNew) mDisparity.imageData = (char *) mBMdisparity16->data.ptr; } - else if (mMain->getStereoWidget()->stereoDispAlgo->currentIndex() == 2) // openCV semi-global block matching http://opencv.willowgarage.com/documentation/cpp/camera_calibration_and_3d_reconstruction.html#stereosgbm ---------------------------------------------------------------------------------------------------------------------------- + else if( + mMain->getStereoWidget()->stereoDispAlgo->currentIndex() == + 2) // openCV semi-global block matching + // http://opencv.willowgarage.com/documentation/cpp/camera_calibration_and_3d_reconstruction.html#stereosgbm + // ---------------------------------------------------------------------------------------------------------------------------- { -// int cn = img1.channels(); -// sgbm.preFilterCap = 63; -// sgbm.SADWindowSize = 11; -// sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize; -// sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize; -// sgbm.minDisparity = 16; -// sgbm.numberOfDisparities = 64; -// sgbm.uniquenessRatio = 15; -// sgbm.speckleWindowSize = 3; -// sgbm.speckleRange = 3; -// sgbm.disp12MaxDiff = 1; -// sgbm.fullDP = false; -// Mat disp, disp8; -// sgbm(img1, img2, disp); + // int cn = img1.channels(); + // sgbm.preFilterCap = 63; + // sgbm.SADWindowSize = 11; + // sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize; + // sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize; + // sgbm.minDisparity = 16; + // sgbm.numberOfDisparities = 64; + // sgbm.uniquenessRatio = 15; + // sgbm.speckleWindowSize = 3; + // sgbm.speckleRange = 3; + // sgbm.disp12MaxDiff = 1; + // sgbm.fullDP = false; + // Mat disp, disp8; + // sgbm(img1, img2, disp); #if CV_MAJOR_VERSION == 2 - if (!mSgbm) // noch =NULL + if(!mSgbm) // noch =NULL { + mSgbm = new cv::StereoSGBM; // cvCreateStereoBMState(CV_STEREO_BM_BASIC, 64); // 16; durch 16 teilbar - mSgbm = new cv::StereoSGBM; //cvCreateStereoBMState(CV_STEREO_BM_BASIC, 64); // 16; durch 16 teilbar - - if (mSgbm == NULL) - debout << "Error: setting up the semi-global block matching state!" << endl; + if(mSgbm == NULL) + debout << "Error: setting up the semi-global block matching state!" << endl; } mSgbm->SADWindowSize = myClip(mMain->getStereoWidget()->stereoMaskSize->value(), 1, 11); - // umkehrung der disparity, da links und rechts vertauscht werden musste, damit disp fuer rechtes bild berechnet wird - mSgbm->minDisparity = -(mMain->getStereoWidget()->maxDisparity->value())+1; // +1, weil es dann mit ptgrey fuer min besser passt - mSgbm->numberOfDisparities = 16*((mMain->getStereoWidget()->maxDisparity->value()-mMain->getStereoWidget()->minDisparity->value())/16); // muss durch 16 teilbar sein - if (mSgbm->numberOfDisparities < 16) // mind 16 ist vorgeschrieben + // umkehrung der disparity, da links und rechts vertauscht werden musste, damit disp fuer rechtes bild + // berechnet wird + mSgbm->minDisparity = -(mMain->getStereoWidget()->maxDisparity->value()) + + 1; // +1, weil es dann mit ptgrey fuer min besser passt + mSgbm->numberOfDisparities = + 16 * + ((mMain->getStereoWidget()->maxDisparity->value() - mMain->getStereoWidget()->minDisparity->value()) / + 16); // muss durch 16 teilbar sein + if(mSgbm->numberOfDisparities < 16) // mind 16 ist vorgeschrieben mSgbm->numberOfDisparities = 16; - mSgbm->preFilterCap = 63; - mSgbm->P1 = 8 * mSgbm->SADWindowSize * mSgbm->SADWindowSize; - mSgbm->P2 = 4*mSgbm->P1; - mSgbm->uniquenessRatio = 15; + mSgbm->preFilterCap = 63; + mSgbm->P1 = 8 * mSgbm->SADWindowSize * mSgbm->SADWindowSize; + mSgbm->P2 = 4 * mSgbm->P1; + mSgbm->uniquenessRatio = 15; mSgbm->speckleWindowSize = 3; - mSgbm->speckleRange = 3; - mSgbm->disp12MaxDiff = 1; + mSgbm->speckleRange = 3; + mSgbm->disp12MaxDiff = 1; #elif CV_MAJOR_VERSION == 3 || CV_MAJOR_VERSION == 4 int SADWindowSize = 11; - int nDisparities = ( mMain->getStereoWidget()->maxDisparity->value() - mMain->getStereoWidget()->minDisparity->value() ) / 16; - //mSgbm = StereoSGBM::create(nDisparities, SADWindowSize); - mSgbm = StereoSGBM::create(-(mMain->getStereoWidget()->maxDisparity->value())+1, // minDisparity - 16 * nDisparities, //numDisparities - 11, // blockSize - 8 * SADWindowSize * SADWindowSize, // P1 - 4 * (8 * SADWindowSize * SADWindowSize), // P2 - 1, // disp12MaxDiff - 63, // preFilterCap - 15, // uniquenessRatio - 3, // speckleWindowSize - 3, // speckleRange - StereoSGBM::MODE_SGBM // mode - ); + int nDisparities = + (mMain->getStereoWidget()->maxDisparity->value() - mMain->getStereoWidget()->minDisparity->value()) / + 16; + // mSgbm = StereoSGBM::create(nDisparities, SADWindowSize); + mSgbm = StereoSGBM::create( + -(mMain->getStereoWidget()->maxDisparity->value()) + 1, // minDisparity + 16 * nDisparities, // numDisparities + 11, // blockSize + 8 * SADWindowSize * SADWindowSize, // P1 + 4 * (8 * SADWindowSize * SADWindowSize), // P2 + 1, // disp12MaxDiff + 63, // preFilterCap + 15, // uniquenessRatio + 3, // speckleWindowSize + 3, // speckleRange + StereoSGBM::MODE_SGBM // mode + ); #endif - if (!mBMdisparity16) + if(!mBMdisparity16) { mBMdisparity16 = cvCreateMat(mDisparity.height, mDisparity.width, CV_16S); - if (mBMdisparity16 == NULL) - debout << "Error: create matrix for block matching disparity map!" << endl; + if(mBMdisparity16 == NULL) + debout << "Error: create matrix for block matching disparity map!" << endl; } #if CV_MAJOR_VERSION == 2 @@ -921,51 +980,56 @@ IplImage *pet::StereoContext::getDisparity(bool *dispNew) cv::Mat MR(cvarrToMat(getRectified(cameraRight))); cv::Mat ML(cvarrToMat(getRectified(cameraLeft))); cv::Mat MD(cvarrToMat(mBMdisparity16)); - mSgbm->compute(ML,MR,MD); + mSgbm->compute(ML, MR, MD); #endif -// debout << mSgbm->preFilterCap <<endl; // default: 0 -// debout << mSgbm->SADWindowSize <<endl; -// debout << mSgbm->P1 <<endl; // default: 0 -// debout << mSgbm->P2 <<endl; // default: 0 -// debout << mSgbm->minDisparity <<endl; -// debout << mSgbm->numberOfDisparities <<endl; -// debout << mSgbm->uniquenessRatio <<endl; // default: 0 -// debout << mSgbm->speckleWindowSize <<endl; // default: 0 -// debout << mSgbm->speckleRange <<endl; // default: 0 -// debout << mSgbm->disp12MaxDiff <<endl; // default: 0 -// debout << mSgbm->fullDP <<endl; // default: 0 + // debout << mSgbm->preFilterCap <<endl; // default: 0 + // debout << mSgbm->SADWindowSize <<endl; + // debout << mSgbm->P1 <<endl; // default: 0 + // debout << mSgbm->P2 <<endl; // default: 0 + // debout << mSgbm->minDisparity <<endl; + // debout << mSgbm->numberOfDisparities <<endl; + // debout << mSgbm->uniquenessRatio <<endl; // default: 0 + // debout << mSgbm->speckleWindowSize <<endl; // default: 0 + // debout << mSgbm->speckleRange <<endl; // default: 0 + // debout << mSgbm->disp12MaxDiff <<endl; // default: 0 + // debout << mSgbm->fullDP <<endl; // default: 0 // exchange/replace value in mBMdisparity16 so that the error value is the same like in pointgrey - short* data16 = (short*) mBMdisparity16->data.s; - short* yData16 = data16; + short *data16 = (short *) mBMdisparity16->data.s; + short *yData16 = data16; - for (int y = 0; y < mBMdisparity16->height; ++y) + for(int y = 0; y < mBMdisparity16->height; ++y) { - for (int x = 0; x < mBMdisparity16->width; ++x) + for(int x = 0; x < mBMdisparity16->width; ++x) { - if ((-*data16 < (mMain->getStereoWidget()->minDisparity->value())*16) || - (-*data16 > (mMain->getStereoWidget()->maxDisparity->value())*16) || // laesst nur den Teil ueber, der in gui eingestellt wurde + if((-*data16 < (mMain->getStereoWidget()->minDisparity->value()) * 16) || + (-*data16 > (mMain->getStereoWidget()->maxDisparity->value()) * + 16) || // laesst nur den Teil ueber, der in gui eingestellt wurde #if CV_MAJOR_VERSION == 2 - (*data16 <= (mSgbm->minDisparity)*16))// enthaelt auch: (*data16 == (mBMState->minDisparity-1)*16)) // marker fuer nicht berechneten wert + (*data16 <= + (mSgbm->minDisparity) * 16)) // enthaelt auch: (*data16 == (mBMState->minDisparity-1)*16)) // + // marker fuer nicht berechneten wert #elif CV_MAJOR_VERSION == 3 || CV_MAJOR_VERSION == 4 - (*data16 <= (-(mMain->getStereoWidget()->maxDisparity->value())+1)*16)) + (*data16 <= (-(mMain->getStereoWidget()->maxDisparity->value()) + 1) * 16)) #endif { *data16 = 0xFF00; // fehlercode gemaess ptgrey } else // vorzeichen umkehren und { - if (-*data16*16 > SHRT_MAX) + if(-*data16 * 16 > SHRT_MAX) { *data16 = SHRT_MAX; debout << "Warning: Disparity set to SHRT_MAX for Pixel " << x << "/" << y << endl; } else - *data16 = -*data16*16; // *16, da cv disp nur faktor 16 fuer subpixelgenauigkeit hat und triclops *256 + *data16 = + -*data16 * + 16; // *16, da cv disp nur faktor 16 fuer subpixelgenauigkeit hat und triclops *256 } ++data16; } - data16 = (yData16 += (mBMdisparity16->step/sizeof(short))); + data16 = (yData16 += (mBMdisparity16->step / sizeof(short))); } mDisparity.imageData = (char *) mBMdisparity16->data.ptr; @@ -973,87 +1037,79 @@ IplImage *pet::StereoContext::getDisparity(bool *dispNew) setStatus(genDisparity); - if (mMin == USHRT_MAX) // das allererste Mal + if(mMin == USHRT_MAX) // das allererste Mal calcMinMax(); - if (dispNew != NULL) + if(dispNew != NULL) *dispNew = true; mMain->getStereoItem()->setDispNew(true); // das zu zeichnende Bild neu berechnen - - - - - - - - - - #ifdef TMP_STEREO_SEQ_DISP - // temporaere code um hoehe [0..ca.176] stereo-einzelbildfolge einzulesen: ----------------------------------------------------------------------------------------------------- - // hier nur um farbbild als disp in petrack anzeigen zu koennen, ist nicht passendes disp bild - QString fn = QString(STEREO_SEQ_FILEBASE) + QString("pointCloud_%1.hgt").arg(mAnimation->getCurrentFrameNum()%(STEREO_SEQ_LAST_FRAME-STEREO_SEQ_FIRST_FRAME+1) + STEREO_SEQ_FIRST_FRAME, 3, 10, QChar('0')); // [2,159] + // temporaere code um hoehe [0..ca.176] stereo-einzelbildfolge einzulesen: + // ----------------------------------------------------------------------------------------------------- hier + // nur um farbbild als disp in petrack anzeigen zu koennen, ist nicht passendes disp bild + QString fn = QString(STEREO_SEQ_FILEBASE) + + QString("pointCloud_%1.hgt") + .arg( + mAnimation->getCurrentFrameNum() % (STEREO_SEQ_LAST_FRAME - STEREO_SEQ_FIRST_FRAME + 1) + + STEREO_SEQ_FIRST_FRAME, + 3, + 10, + QChar('0')); // [2,159] debout << "Read height field for disparity image" << fn << endl; QFile file(fn); - if (!file.open(QIODevice::ReadOnly)) + if(!file.open(QIODevice::ReadOnly)) { - PInformation(NULL,"show","Failed to read"); + PInformation(NULL, "show", "Failed to read"); } - QByteArray buffer = file.readAll(); //reinterpret_cast<double *> mDisparity.height*mDisparity.width*8 - //debout << "Number of bytes in height field from virtual scene: " << buffer.size() <<endl; - double * dBuffer = (double *) buffer.data(); + QByteArray buffer = file.readAll(); // reinterpret_cast<double *> mDisparity.height*mDisparity.width*8 + // debout << "Number of bytes in height field from virtual scene: " << buffer.size() <<endl; + double *dBuffer = (double *) buffer.data(); file.close(); - if (!mBMdisparity16) + if(!mBMdisparity16) { mBMdisparity16 = cvCreateMat(mDisparity.height, mDisparity.width, CV_16S); - if (mBMdisparity16 == NULL) - debout << "Error: create matrix for libelas disparity map!" << endl; + if(mBMdisparity16 == NULL) + debout << "Error: create matrix for libelas disparity map!" << endl; } - short* data16 = (short*) mBMdisparity16->data.s; - short* yData16 = data16; - int i, j; + short *data16 = (short *) mBMdisparity16->data.s; + short *yData16 = data16; + int i, j; double disp; - for (i = mDisparity.height-1; i >= 0; --i) // 960 // dateiinhalt liegt in y gespiegelt vor - //for (i = 0; i < mDisparity.height; ++i) // 960 + for(i = mDisparity.height - 1; i >= 0; --i) // 960 // dateiinhalt liegt in y gespiegelt vor + // for (i = 0; i < mDisparity.height; ++i) // 960 { - for (j = 0; j < mDisparity.width; ++j) // 1280 + for(j = 0; j < mDisparity.width; ++j) // 1280 { - disp = dBuffer[3*(j+i*mDisparity.width)+2]; - if (disp > -0.9) - *data16 = SHRT_MAX*disp/STEREO_SEQ_MAX_PERS_HEIGHT; // von maximal STEREO_SEQ_MAX_PERS_HEIGHT cm personengroesse wird ausgegangen // dateiinhalt liegt in y gespiegelt vor + disp = dBuffer[3 * (j + i * mDisparity.width) + 2]; + if(disp > -0.9) + *data16 = SHRT_MAX * disp / + STEREO_SEQ_MAX_PERS_HEIGHT; // von maximal STEREO_SEQ_MAX_PERS_HEIGHT cm personengroesse + // wird ausgegangen // dateiinhalt liegt in y gespiegelt vor else - *data16 = 0xFFFF; //erlaubte werte: disp < 0xFF00 xxx + *data16 = 0xFFFF; // erlaubte werte: disp < 0xFF00 xxx ++data16; } - data16 = (yData16 += (mBMdisparity16->step/sizeof(short))); + data16 = (yData16 += (mBMdisparity16->step / sizeof(short))); } mDisparity.imageData = (char *) mBMdisparity16->data.ptr; - mMin = 0; - mMax = SHRT_MAX; + mMin = 0; + mMax = SHRT_MAX; #endif - - - - - - - #ifdef TIME_MEASUREMENT - // "==========: " - debout << "out disp: " << getElapsedTime() <<endl; + // "==========: " + debout << "out disp: " << getElapsedTime() << endl; #endif - return &mDisparity; } - else if (mStatus & genDisparity) + else if(mStatus & genDisparity) { return &mDisparity; } @@ -1074,29 +1130,29 @@ double pet::StereoContext::getCmPerPixel(float z) triclopsXYZToRCD(mTriclopsContext, 1., 1., z, &row1, &col, &disp); triclopsXYZToRCD(mTriclopsContext, 1., 2., z, &row2, &col, &disp); #endif - return 100./(row2-row1); + return 100. / (row2 - row1); } void pet::StereoContext::calcMinMax() { - if (mStatus & genDisparity) + if(mStatus & genDisparity) { mMin = USHRT_MAX; mMax = 0; - unsigned short* data = (unsigned short*) mDisparity.imageData; - unsigned short* yData = data; - int x,y; + unsigned short *data = (unsigned short *) mDisparity.imageData; + unsigned short *yData = data; + int x, y; - for (y = 0; y < mDisparity.height; ++y) + for(y = 0; y < mDisparity.height; ++y) { - for (x = 0; x < mDisparity.width; ++x) + for(x = 0; x < mDisparity.width; ++x) { - if (dispValueValid(*data)) + if(dispValueValid(*data)) { - if (*data > mMax) + if(*data > mMax) mMax = *data; - else if (*data < mMin) + else if(*data < mMin) mMin = *data; } ++data; @@ -1104,7 +1160,7 @@ void pet::StereoContext::calcMinMax() data = (yData += mDisparity.width); } } - //debout << "Set disparity color code min: " << mMin << ", max: " << mMax << endl; + // debout << "Set disparity color code min: " << mMin << ", max: " << mMax << endl; } void pet::StereoContext::indicateNewValues() @@ -1116,18 +1172,20 @@ void pet::StereoContext::indicateNewValues() // col, row beginnt bei 0, 0 // x, y, z in cm -bool pet::StereoContext::getXYZ(int col, int row, float* x, float* y, float* z) +bool pet::StereoContext::getXYZ(int col, int row, float *x, float *y, float *z) { - if (mStatus & genDisparity) + if(mStatus & genDisparity) { - unsigned short int disp = *(((unsigned short*) mDisparity.imageData)+mDisparity.width*row+col); + unsigned short int disp = *(((unsigned short *) mDisparity.imageData) + mDisparity.width * row + col); - if (dispValueValid(disp)) + if(dispValueValid(disp)) { #ifdef STEREO triclopsRCD16ToXYZ(mTriclopsContext, row, col, disp, x, y, z); #endif - *x *= 100.; *y *= 100.; *z *= 100.; + *x *= 100.; + *y *= 100.; + *z *= 100.; return true; } else @@ -1157,28 +1215,30 @@ float pet::StereoContext::getZfromDisp(unsigned short int disp) // x, y, z in cm (median der aus disp-werten berechneten cm in 5x5 pixelumfeld) // return false, if no disparity information is found around col/row (x,y,z not set) // Achtung: COL ROW getauscht zu triclopsRCD16ToXYZ -bool pet::StereoContext::getMedianXYZaround(int col, int row, float* x, float* y, float* z) +bool pet::StereoContext::getMedianXYZaround(int col, int row, float *x, float *y, float *z) { - if (mStatus & genDisparity) + if(mStatus & genDisparity) { - static int size = 5; // region scanned for median - static QVector<unsigned short> values(size*size); + static int size = 5; // region scanned for median + static QVector<unsigned short> values(size * size); values.fill(65280); // 65280 == 0xff00 ab wo angezeigt wird, dass es fehler sind // umstellung von row und col von mitte des 5x5x auf ecke oben links und ueberpruefung auf rand - row = ((row < 2) ? 0 : ((row > mDisparity.height-3) ? mDisparity.height-5 : row-2)); - col = ((col < 2) ? 0 : ((col > mDisparity.width -3) ? mDisparity.width -5 : col-2)); + row = ((row < 2) ? 0 : ((row > mDisparity.height - 3) ? mDisparity.height - 5 : row - 2)); + col = ((col < 2) ? 0 : ((col > mDisparity.width - 3) ? mDisparity.width - 5 : col - 2)); - unsigned short* data = (unsigned short*) (((unsigned short*) mDisparity.imageData)+mDisparity.width*row+col); //mDisparity.imageData; - unsigned short* yData = data; - int i, j, nr = 0; // nr zeigt anzahl der gefundenen disp an + unsigned short *data = + (unsigned short + *) (((unsigned short *) mDisparity.imageData) + mDisparity.width * row + col); // mDisparity.imageData; + unsigned short *yData = data; + int i, j, nr = 0; // nr zeigt anzahl der gefundenen disp an - for (j = 0; j < size; ++j) + for(j = 0; j < size; ++j) { - for (i = 0; i < size; ++i) + for(i = 0; i < size; ++i) { - if (dispValueValid(*data)) + if(dispValueValid(*data)) { values[nr++] = *data; } @@ -1187,15 +1247,17 @@ bool pet::StereoContext::getMedianXYZaround(int col, int row, float* x, float* y data = (yData += mDisparity.width); } - if (nr != 0) + if(nr != 0) { - qSort(values.begin(), values.begin()+nr); // sort first nr elements in values + qSort(values.begin(), values.begin() + nr); // sort first nr elements in values - //debout << row+2 << " " << col+2 << " " << nr << " "<< values[nr/2] << endl; + // debout << row+2 << " " << col+2 << " " << nr << " "<< values[nr/2] << endl; #ifdef STEREO - triclopsRCD16ToXYZ(mTriclopsContext, row+2, col+2, values[nr/2], x, y, z); + triclopsRCD16ToXYZ(mTriclopsContext, row + 2, col + 2, values[nr / 2], x, y, z); #endif - *x *= 100.; *y *= 100.; *z *= 100.; + *x *= 100.; + *y *= 100.; + *z *= 100.; return true; } else @@ -1207,129 +1269,134 @@ bool pet::StereoContext::getMedianXYZaround(int col, int row, float* x, float* y bool pet::StereoContext::dispValueValid(unsigned short int disp) { - if (disp < 0xFF00) - //if ((disp != mSurfaceValue+65280) && (disp != mBackForthValue+65280))// 65280 == 0xff00 + if(disp < 0xFF00) + // if ((disp != mSurfaceValue+65280) && (disp != mBackForthValue+65280))// 65280 == 0xff00 return true; else return false; } -CvMat* pet::StereoContext::getPointCloud() +CvMat *pet::StereoContext::getPointCloud() { - if (!(mStatus & genDisparity)) // falls disparity noch nicht berechnet wurde + if(!(mStatus & genDisparity)) // falls disparity noch nicht berechnet wurde getDisparity(); - if (mStatus & genDisparity) + if(mStatus & genDisparity) { - if (mPointCloud == NULL) // Speicherplatz anlegen + if(mPointCloud == NULL) // Speicherplatz anlegen { mPointCloud = cvCreateMat(mDisparity.height, mDisparity.width, CV_32FC3); // CvMat* - if (mPointCloud == NULL) + if(mPointCloud == NULL) { debout << "Error: not enaugh memory for pointCloud" << endl; return NULL; } } - unsigned short* data = (unsigned short*) mDisparity.imageData; - unsigned short* yData = data; - float* pcData = (float*) mPointCloud->data.fl; - float* pcyData = pcData; - //float x, y, z; + unsigned short *data = (unsigned short *) mDisparity.imageData; + unsigned short *yData = data; + float * pcData = (float *) mPointCloud->data.fl; + float * pcyData = pcData; + // float x, y, z; int i, j; - for (i = 0; i < mDisparity.height; ++i) + for(i = 0; i < mDisparity.height; ++i) { - for (j = 0; j < mDisparity.width; ++j) + for(j = 0; j < mDisparity.width; ++j) { - if (dispValueValid(*data)) + if(dispValueValid(*data)) { // convert the 16 bit disparity value to floating point x,y,z #ifdef STEREO - triclopsRCD16ToXYZ(mTriclopsContext, i, j, *data, pcData, pcData+1, pcData+2) ; + triclopsRCD16ToXYZ(mTriclopsContext, i, j, *data, pcData, pcData + 1, pcData + 2); #endif } else { pcData[0] = pcData[1] = pcData[2] = -1; } -// if (i ==100 || i == 101) -// cout << pcData << " # " << pcData+2 << " "; + // if (i ==100 || i == 101) + // cout << pcData << " # " << pcData+2 << " "; ++data; - pcData+=3; + pcData += 3; } - data = (yData += mDisparity.width); - pcData = (pcyData += mPointCloud->step/sizeof(float));// ->step); + data = (yData += mDisparity.width); + pcData = (pcyData += mPointCloud->step / sizeof(float)); // ->step); } -// debout << mDisparity.width << " " << mDisparity.widthStep << endl; -// debout << mPointCloud->width << " " << mPointCloud->step << endl; - - - + // debout << mDisparity.width << " " << mDisparity.widthStep << endl; + // debout << mPointCloud->width << " " << mPointCloud->step << endl; #ifdef TMP_STEREO_SEQ_DISP - // temporaere code um hoehe [0..ca.176] stereo-einzelbildfolge einzulesen: ----------------------------------------------------------------------------------------------------- - QString fn = QString(STEREO_SEQ_FILEBASE) + QString("pointCloud_%1.hgt").arg(mAnimation->getCurrentFrameNum()%(STEREO_SEQ_LAST_FRAME-STEREO_SEQ_FIRST_FRAME+1) + STEREO_SEQ_FIRST_FRAME, 3, 10, QChar('0')); // [2,159] + // temporaere code um hoehe [0..ca.176] stereo-einzelbildfolge einzulesen: + // ----------------------------------------------------------------------------------------------------- + QString fn = QString(STEREO_SEQ_FILEBASE) + + QString("pointCloud_%1.hgt") + .arg( + mAnimation->getCurrentFrameNum() % (STEREO_SEQ_LAST_FRAME - STEREO_SEQ_FIRST_FRAME + 1) + + STEREO_SEQ_FIRST_FRAME, + 3, + 10, + QChar('0')); // [2,159] debout << "Import for pointcloud: " << fn << endl; QFile file(fn); - if (!file.open(QIODevice::ReadOnly)) + if(!file.open(QIODevice::ReadOnly)) { - PInformation(NULL,"show","Failed to read"); + PInformation(NULL, "show", "Failed to read"); } - QByteArray buffer = file.readAll(); //reinterpret_cast<double *> mDisparity.height*mDisparity.width*8 - //debout << "Number of bytes in height field from virtual scene: " << buffer.size() <<endl; - double * dBuffer = (double *) buffer.data(); + QByteArray buffer = file.readAll(); // reinterpret_cast<double *> mDisparity.height*mDisparity.width*8 + // debout << "Number of bytes in height field from virtual scene: " << buffer.size() <<endl; + double *dBuffer = (double *) buffer.data(); file.close(); - data = (unsigned short*) mDisparity.imageData; - yData = data; - pcData = (float*) mPointCloud->data.fl; + data = (unsigned short *) mDisparity.imageData; + yData = data; + pcData = (float *) mPointCloud->data.fl; pcyData = pcData; - for (i = mDisparity.height-1; i >= 0; --i) // 960 // dateiinhalt liegt in y gespiegelt vor + for(i = mDisparity.height - 1; i >= 0; --i) // 960 // dateiinhalt liegt in y gespiegelt vor { - for (j = 0; j < mDisparity.width; ++j) // 1280 + for(j = 0; j < mDisparity.width; ++j) // 1280 { - if (*data != -1) + if(*data != -1) { - pcData[0] = .01*dBuffer[3*(j+i*mDisparity.width)]; - pcData[1] = .01*dBuffer[3*(j+i*mDisparity.width)+1]; - pcData[2] = .01*(784-dBuffer[3*(j+i*mDisparity.width)+2]); // entfernung von kamera ueber hoehenfeld der person + pcData[0] = .01 * dBuffer[3 * (j + i * mDisparity.width)]; + pcData[1] = .01 * dBuffer[3 * (j + i * mDisparity.width) + 1]; + pcData[2] = + .01 * (784 - dBuffer[3 * (j + i * mDisparity.width) + 2]); // entfernung von kamera ueber + // hoehenfeld der person } else pcData[0] = pcData[1] = pcData[2] = -1; ++data; - pcData+=3; - //if (dBuffer[j+i*mDisparity.width] > 0) + pcData += 3; + // if (dBuffer[j+i*mDisparity.width] > 0) } - data = (yData += mDisparity.width); - pcData = (pcyData += mPointCloud->step/sizeof(float)); + data = (yData += mDisparity.width); + pcData = (pcyData += mPointCloud->step / sizeof(float)); } #endif - - - return mPointCloud; } else return NULL; -// else // kann nun nicht mehr passieren, da disp berechnet wird, wenn nichjt schon geschehen -// { -// debout << "Warning: generate disparity before pointCloud!" << endl; -// return NULL; -// } + // else // kann nun nicht mehr passieren, da disp berechnet wird, wenn nichjt schon geschehen + // { + // debout << "Warning: generate disparity before pointCloud!" << endl; + // return NULL; + // } } //// erzeugt ein aequidistantes xy-gitter //// von min bis max (dadurch koennten ausreisser das netz unnoetig auseinanderziehen und viele pkte fallen zusammen) -//CvMat* StereoContext::getRectifiedPointCloud(float *xMin, float *xMax, float *yMin, float *yMax, float *zMin, float *zMax) +// CvMat* StereoContext::getRectifiedPointCloud(float *xMin, float *xMax, float *yMin, float *yMax, float *zMin, float +// *zMax) //{ -// if (!(mStatus & genDisparity) || (mPointCloud == NULL)) -// getPointCloud(); +// if (!(mStatus & genDisparity) || (mPointCloud == NULL)) +// getPointCloud(); // if (mPointCloud != NULL) // { @@ -1374,59 +1441,66 @@ CvMat* pet::StereoContext::getPointCloud() // return shows, if export was sucessfull -bool pet::StereoContext::exportPointCloud(QString dest) //default = "" +bool pet::StereoContext::exportPointCloud(QString dest) // default = "" { static QString lastFile = ""; - if (mStatus & genDisparity) + if(mStatus & genDisparity) { // if no destination file or folder is given - if (dest.isEmpty()) + if(dest.isEmpty()) { - if (lastFile.isEmpty() && !mMain->getProFileName().isEmpty()) - lastFile = QFileInfo(mMain->getProFileName()).path()+QDir::separator()+QFileInfo(mMain->getProFileName()).baseName()+".pts"; - - dest = QFileDialog::getSaveFileName(mMain, QObject::tr("Select file for exporting point cloud"), lastFile, + if(lastFile.isEmpty() && !mMain->getProFileName().isEmpty()) + lastFile = QFileInfo(mMain->getProFileName()).path() + QDir::separator() + + QFileInfo(mMain->getProFileName()).baseName() + ".pts"; + + dest = QFileDialog::getSaveFileName( + mMain, + QObject::tr("Select file for exporting point cloud"), + lastFile, QObject::tr("Triclops points (*.pts);;All supported types (*.pts *.xxx);;All files (*.*)")); } - if (!dest.isEmpty()) + if(!dest.isEmpty()) { - if (dest.right(4) == ".pts") + if(dest.right(4) == ".pts") { QFile file(dest); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - PCritical(mMain, QObject::tr("Petrack"), QObject::tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString())); + PCritical( + mMain, + QObject::tr("Petrack"), + QObject::tr("Cannot open %1:\n%2.").arg(dest).arg(file.errorString())); return false; } debout << "export point cloud to " << dest << "..." << endl; QTextStream out(&file); - unsigned short* data = (unsigned short*) mDisparity.imageData; - unsigned short* yData = data; - float x, y, z; - int i, j, k = 0; - int nPoints = 0; - unsigned char c; - unsigned char *iD = (unsigned char *) getRectified(cameraRight)->imageData; + unsigned short *data = (unsigned short *) mDisparity.imageData; + unsigned short *yData = data; + float x, y, z; + int i, j, k = 0; + int nPoints = 0; + unsigned char c; + unsigned char * iD = (unsigned char *) getRectified(cameraRight)->imageData; - for (i = 0; i < mDisparity.height; ++i) + for(i = 0; i < mDisparity.height; ++i) { - for (j = 0; j < mDisparity.width; ++j) + for(j = 0; j < mDisparity.width; ++j) { - if (dispValueValid(*data) && - ((mMain->getBackgroundFilter()->getEnabled() && mMain->getBackgroundFilter()->isForeground(j, i)) || - !mMain->getBackgroundFilter()->getEnabled())) + if(dispValueValid(*data) && ((mMain->getBackgroundFilter()->getEnabled() && + mMain->getBackgroundFilter()->isForeground(j, i)) || + !mMain->getBackgroundFilter()->getEnabled())) { // convert the 16 bit disparity value to floating point x,y,z #ifdef STEREO - triclopsRCD16ToXYZ(mTriclopsContext, i, j, *data, &x, &y, &z) ; + triclopsRCD16ToXYZ(mTriclopsContext, i, j, *data, &x, &y, &z); #endif // look at points within a range - //if ( z < 5.0 ) + // if ( z < 5.0 ) c = iD[k]; out << x << " " << y << " " << z << " " << c << " " << c << " " << c << endl; ++nPoints; @@ -1438,37 +1512,41 @@ bool pet::StereoContext::exportPointCloud(QString dest) //default = "" } -// int i, j, k, pixelinc = mTriDisparity.rowinc/2; -// unsigned short *row; -// unsigned short disp; -// float x, y, z; -// int nPoints = 0; - -// for (i = 0, k = 0; i < mTriDisparity.nrows; ++i) -// { -// row = mTriDisparity.data + i * pixelinc; -// for (j = 0; j < mTriDisparity.ncols; ++j, ++k) -// { -// disp = row[j]; -// // filter invalid points -// if (dispValueValid(disp)) -// { -// // convert the 16 bit disparity value to floating point x,y,z -// triclopsRCD16ToXYZ(mTriclopsContext, i, j, disp, &x, &y, &z) ; -// // look at points within a range -// //if ( z < 5.0 ) -// out << x << " " << y << " " << z << " " << mTriRectRight.data[k] << " " << mTriRectRight.data[k] << " " << mTriRectRight.data[k] << endl; -// ++nPoints; -// } -// } -// } + // int i, j, k, pixelinc = mTriDisparity.rowinc/2; + // unsigned short *row; + // unsigned short disp; + // float x, y, z; + // int nPoints = 0; + + // for (i = 0, k = 0; i < mTriDisparity.nrows; ++i) + // { + // row = mTriDisparity.data + i * pixelinc; + // for (j = 0; j < mTriDisparity.ncols; ++j, ++k) + // { + // disp = row[j]; + // // filter invalid points + // if (dispValueValid(disp)) + // { + // // convert the 16 bit disparity value to floating point x,y,z + // triclopsRCD16ToXYZ(mTriclopsContext, i, j, disp, &x, &y, &z) ; + // // look at points within a range + // //if ( z < 5.0 ) + // out << x << " " << y << " " << z << " " << mTriRectRight.data[k] << " " << + // mTriRectRight.data[k] << " " << mTriRectRight.data[k] << endl; + // ++nPoints; + // } + // } + // } file.close(); cout << " with " << nPoints << " points finished " << endl; } else { - PCritical(mMain, QObject::tr("Petrack"), QObject::tr("Cannot save %1 maybe because of wrong file extension.").arg(dest)); + PCritical( + mMain, + QObject::tr("Petrack"), + QObject::tr("Cannot save %1 maybe because of wrong file extension.").arg(dest)); return false; } lastFile = dest; @@ -1477,7 +1555,10 @@ bool pet::StereoContext::exportPointCloud(QString dest) //default = "" } else { - PCritical(mMain, QObject::tr("Petrack"), QObject::tr("Cannot export point cloud, because disparity has not been generated.")); + PCritical( + mMain, + QObject::tr("Petrack"), + QObject::tr("Cannot export point cloud, because disparity has not been generated.")); return false; } } diff --git a/src/stereoItem.cpp b/src/stereoItem.cpp index e398e3751b697cf1e1a4b936b23bb2bdd5f1567e..fdacf020272481752978e4042214e7a655be0b7c 100644 --- a/src/stereoItem.cpp +++ b/src/stereoItem.cpp @@ -18,24 +18,24 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> +#include "stereoItem.h" +#include "animation.h" #include "petrack.h" -#include "view.h" -#include "stereoItem.h" #include "stereoWidget.h" #include "tracker.h" -#include "animation.h" +#include "view.h" + +#include <QtWidgets> // in x und y gleichermassen skaliertes koordinatensystem, // da von einer vorherigen intrinsischen kamerakalibrierung ausgegenagen wird, -// so dass pixel quadratisch -StereoItem::StereoItem(QWidget *wParent, QGraphicsItem * parent) - : QGraphicsItem(parent) +// so dass pixel quadratisch +StereoItem::StereoItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsItem(parent) { - mMainWindow = (class Petrack*) wParent; - mImage = nullptr; - mDispNew = true; + mMainWindow = (class Petrack *) wParent; + mImage = nullptr; + mDispNew = true; setAcceptHoverEvents(true); } @@ -50,34 +50,36 @@ StereoItem::StereoItem(QWidget *wParent, QGraphicsItem * parent) */ QRectF StereoItem::boundingRect() const { - if (mMainWindow->getImage()) - return QRectF(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), mMainWindow->getImage()->width(), mMainWindow->getImage()->height()); + if(mMainWindow->getImage()) + return QRectF( + -mMainWindow->getImageBorderSize(), + -mMainWindow->getImageBorderSize(), + mMainWindow->getImage()->width(), + mMainWindow->getImage()->height()); else return QRectF(0, 0, 0, 0); } // event, of moving mouse while button is pressed -void StereoItem::mouseMoveEvent(QGraphicsSceneMouseEvent */*event*/) -{ -} +void StereoItem::mouseMoveEvent(QGraphicsSceneMouseEvent * /*event*/) {} // event, of moving mouse void StereoItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { - - if (mMainWindow->getStereoContext()) + if(mMainWindow->getStereoContext()) { - #ifndef STEREO_DISABLED +#ifndef STEREO_DISABLED static int lastX = -1, lastY = -1; - QPointF pos = event->scenePos(); + QPointF pos = event->scenePos(); pos.setX(pos.x() + mMainWindow->getImageBorderSize()); pos.setY(pos.y() + mMainWindow->getImageBorderSize()); - if ((lastX != (int) pos.x()) || (lastY != (int) pos.y())) + if((lastX != (int) pos.x()) || (lastY != (int) pos.y())) { float x, y, z; lastX = (int) pos.x(); lastY = (int) pos.y(); - if (mMainWindow->getStereoContext()->getXYZ(lastX, lastY, &x, &y, &z)) // nicht runden: myround, dan 0.5 zuviel + if(mMainWindow->getStereoContext()->getXYZ( + lastX, lastY, &x, &y, &z)) // nicht runden: myround, dan 0.5 zuviel { mMainWindow->setStatusStereo(x, y, z); } @@ -86,7 +88,7 @@ void StereoItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) mMainWindow->setStatusStereo(-1, -1, -1); } - //debout <<lastX<<" "<< lastY<<" "<< x << " " << y << " " << z << endl; + // debout <<lastX<<" "<< lastY<<" "<< x << " " << y << " " << z << endl; } #endif } @@ -98,90 +100,101 @@ void StereoItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) #ifndef STEREO_DISABLED void StereoItem::updateData(IplImage *disp) { - - if (disp != NULL) + if(disp != NULL) { - if ((mImage != NULL) && ((mImage->width() != disp->width) || (mImage->height() != disp->height))) + if((mImage != NULL) && ((mImage->width() != disp->width) || (mImage->height() != disp->height))) delete mImage; - if (mImage == NULL) // zu Beginn oder wenn sich die Groesse aendert + if(mImage == NULL) // zu Beginn oder wenn sich die Groesse aendert mImage = new QImage(disp->width, disp->height, QImage::Format_ARGB32); - int x,y; - unsigned short* data = (unsigned short*) disp->imageData; // char* - unsigned short* yData = data; - char *p; - QColor color; - unsigned short min = mMainWindow->getStereoContext()->getMin(); - unsigned short max = mMainWindow->getStereoContext()->getMax(); - double scale = max-min; - int hue, value; - - if (scale > 0) // nicht min=max ! + int x, y; + unsigned short *data = (unsigned short *) disp->imageData; // char* + unsigned short *yData = data; + char * p; + QColor color; + unsigned short min = mMainWindow->getStereoContext()->getMin(); + unsigned short max = mMainWindow->getStereoContext()->getMax(); + double scale = max - min; + int hue, value; + + if(scale > 0) // nicht min=max ! { - if (mMainWindow->getStereoWidget()->stereoColor->currentIndex() == 0) // rainbow - scale=240./scale; - else // greyscale - scale=255./scale; + if(mMainWindow->getStereoWidget()->stereoColor->currentIndex() == 0) // rainbow + scale = 240. / scale; + else // greyscale + scale = 255. / scale; } - for (y = 0; y < disp->height; y++) + for(y = 0; y < disp->height; y++) { // Pointer to the data information in the QImage for just one column // set pointer to value before, because ++p is faster than p++ - p = ((char*)mImage->scanLine(y))-1; - for (x = 0; x < disp->width; x++) + p = ((char *) mImage->scanLine(y)) - 1; + for(x = 0; x < disp->width; x++) { - if (mMainWindow->getStereoContext()->dispValueValid(*data)) //(*data != mMainWindow->getStereoContext()->getSurfaceValue()+65280) && (*data != mMainWindow->getStereoContext()->getBackForthValue()+65280)) // 65280 == 0xff00 + if(mMainWindow->getStereoContext()->dispValueValid( + *data)) //(*data != mMainWindow->getStereoContext()->getSurfaceValue()+65280) && (*data != + // mMainWindow->getStereoContext()->getBackForthValue()+65280)) // 65280 == 0xff00 { - if (mMainWindow->getStereoWidget()->stereoColor->currentIndex() == 0) // rainbow + if(mMainWindow->getStereoWidget()->stereoColor->currentIndex() == 0) // rainbow { - hue = scale*(*data-min); - color.setHsv(hue<0?0:(hue>240?240:hue), 255, 255, 255); // 0=rot, 240=blau, nicht 359, da sich Farbkreis wieder schliesst + hue = scale * (*data - min); + color.setHsv( + hue < 0 ? 0 : (hue > 240 ? 240 : hue), + 255, + 255, + 255); // 0=rot, 240=blau, nicht 359, da sich Farbkreis wieder schliesst } else // greyscale { - value = scale*(*data-min); // for greyscale - color.setHsv(0, 0, value<0?0:(value>255?255:value), 255); // 0=rot, 240=blau, nicht 359, da sich Farbkreis wieder schliesst + value = scale * (*data - min); // for greyscale + color.setHsv( + 0, + 0, + value < 0 ? 0 : (value > 255 ? 255 : value), + 255); // 0=rot, 240=blau, nicht 359, da sich Farbkreis wieder schliesst } - //c = (char) (((*data-min)*255)/(max-min)); // 255 nur 1x (nicht gleichverteilt!) + // c = (char) (((*data-min)*255)/(max-min)); // 255 nur 1x (nicht gleichverteilt!) } else { - color.setRgb(0, 0, 0, (!mMainWindow->getStereoWidget()->hideWrong->isChecked())*255); //.setAlpha(0); + color.setRgb( + 0, 0, 0, (!mMainWindow->getStereoWidget()->hideWrong->isChecked()) * 255); //.setAlpha(0); } *(++p) = color.red(); *(++p) = color.green(); *(++p) = color.blue(); *(++p) = color.alpha(); // 255; - //printf("%d ", (int)*(data)); + // printf("%d ", (int)*(data)); ++data; } - data = (yData += disp->width); // falsch, da nicht mehr char sondern short: (yData += disp->widthStep); // because sometimes widthStep != width - //printf("\n"); + data = (yData += disp->width); // falsch, da nicht mehr char sondern short: (yData += disp->widthStep); // + // because sometimes widthStep != width + // printf("\n"); } } } #endif - -void StereoItem::paint(QPainter */*painter*/, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) + +void StereoItem::paint(QPainter * /*painter*/, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { #ifndef STEREO_DISABLED IplImage *disp = NULL; - bool mDispNewWhilePainting; + bool mDispNewWhilePainting; - if (mMainWindow->getStereoContext()) + if(mMainWindow->getStereoContext()) disp = mMainWindow->getStereoContext()->getDisparity(&mDispNewWhilePainting); else return; - if (mDispNew || // disparity ist nach zeichnen neu berechnet worden - mDispNewWhilePainting) // disp ist wegen des zeichnens neu berechnet worden + if(mDispNew || // disparity ist nach zeichnen neu berechnet worden + mDispNewWhilePainting) // disp ist wegen des zeichnens neu berechnet worden updateData(disp); - if (mImage != NULL) + if(mImage != NULL) { - painter->setOpacity(mMainWindow->getStereoWidget()->opacity->value()/100.); - painter->drawImage(-mMainWindow->getImageBorderSize(),-mMainWindow->getImageBorderSize(), *mImage); + painter->setOpacity(mMainWindow->getStereoWidget()->opacity->value() / 100.); + painter->drawImage(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), *mImage); mDispNew = false; } @@ -192,4 +205,3 @@ void StereoItem::setDispNew(bool d) // default: d = true { mDispNew = d; } - diff --git a/src/stereoWidget.cpp b/src/stereoWidget.cpp index bdeb019d95ed70644d5bb425523a1b0479f21fb2..c93ec5af3367e82640389da2b034aee8d6a1b9f5 100644 --- a/src/stereoWidget.cpp +++ b/src/stereoWidget.cpp @@ -20,10 +20,9 @@ #include "stereoWidget.h" -StereoWidget::StereoWidget(QWidget *parent) - : QWidget(parent) +StereoWidget::StereoWidget(QWidget *parent) : QWidget(parent) { - mMainWindow = (class Petrack*) parent; + mMainWindow = (class Petrack *) parent; setupUi(this); @@ -85,49 +84,55 @@ void StereoWidget::getXml(QDomElement &elem) for(subElem = elem.firstChildElement(); !subElem.isNull(); subElem = subElem.nextSiblingElement()) { - if (subElem.tagName() == "DISPARITY") + if(subElem.tagName() == "DISPARITY") { - if (subElem.hasAttribute("OPACITY")) + if(subElem.hasAttribute("OPACITY")) opacity->setValue(subElem.attribute("OPACITY").toInt()); - if (subElem.hasAttribute("SHOW")) + if(subElem.hasAttribute("SHOW")) stereoShowDisparity->setCheckState(subElem.attribute("SHOW").toInt() ? Qt::Checked : Qt::Unchecked); - if (subElem.hasAttribute("COLOR")) + if(subElem.hasAttribute("COLOR")) stereoColor->setCurrentIndex(subElem.attribute("COLOR").toInt()); - if (subElem.hasAttribute("ALGO")) + if(subElem.hasAttribute("ALGO")) stereoDispAlgo->setCurrentIndex(subElem.attribute("ALGO").toInt()); - if (subElem.hasAttribute("HIDE_INVALID")) + if(subElem.hasAttribute("HIDE_INVALID")) hideWrong->setCheckState(subElem.attribute("HIDE_INVALID").toInt() ? Qt::Checked : Qt::Unchecked); - for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); subSubElem = subSubElem.nextSiblingElement()) + for(subSubElem = subElem.firstChildElement(); !subSubElem.isNull(); + subSubElem = subSubElem.nextSiblingElement()) { - if (subSubElem.tagName() == "VALUES") + if(subSubElem.tagName() == "VALUES") { - if (subSubElem.hasAttribute("MIN")) + if(subSubElem.hasAttribute("MIN")) minDisparity->setValue(subSubElem.attribute("MIN").toInt()); - if (subSubElem.hasAttribute("MAX")) + if(subSubElem.hasAttribute("MAX")) maxDisparity->setValue(subSubElem.attribute("MAX").toInt()); } - else if (subSubElem.tagName() == "MASK") + else if(subSubElem.tagName() == "MASK") { - if (subSubElem.hasAttribute("SIZE")) + if(subSubElem.hasAttribute("SIZE")) stereoMaskSize->setValue(subSubElem.attribute("SIZE").toInt()); - if (subSubElem.hasAttribute("EDGE_SIZE")) + if(subSubElem.hasAttribute("EDGE_SIZE")) edgeMaskSize->setValue(subSubElem.attribute("EDGE_SIZE").toInt()); - if (subSubElem.hasAttribute("USE_EDGE")) + if(subSubElem.hasAttribute("USE_EDGE")) useEdge->setCheckState(subSubElem.attribute("USE_EDGE").toInt() ? Qt::Checked : Qt::Unchecked); } - else if (subSubElem.tagName() == "USE") + else if(subSubElem.tagName() == "USE") { - if (subSubElem.hasAttribute("RECO")) - stereoUseForReco->setCheckState(subSubElem.attribute("RECO").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("HEIGHT")) - stereoUseForHeight->setCheckState(subSubElem.attribute("HEIGHT").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("HEIGHT_EVER")) - stereoUseForHeightEver->setCheckState(subSubElem.attribute("HEIGHT_EVER").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("EXPORT")) - stereoUseForExport->setCheckState(subSubElem.attribute("EXPORT").toInt() ? Qt::Checked : Qt::Unchecked); - if (subSubElem.hasAttribute("CALIB_CENTER")) - stereoUseCalibrationCenter->setCheckState(subSubElem.attribute("CALIB_CENTER").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("RECO")) + stereoUseForReco->setCheckState( + subSubElem.attribute("RECO").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("HEIGHT")) + stereoUseForHeight->setCheckState( + subSubElem.attribute("HEIGHT").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("HEIGHT_EVER")) + stereoUseForHeightEver->setCheckState( + subSubElem.attribute("HEIGHT_EVER").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("EXPORT")) + stereoUseForExport->setCheckState( + subSubElem.attribute("EXPORT").toInt() ? Qt::Checked : Qt::Unchecked); + if(subSubElem.hasAttribute("CALIB_CENTER")) + stereoUseCalibrationCenter->setCheckState( + subSubElem.attribute("CALIB_CENTER").toInt() ? Qt::Checked : Qt::Unchecked); } else debout << "Unknown STEREO tag " << subSubElem.tagName() << std::endl; diff --git a/src/swapFilter.cpp b/src/swapFilter.cpp index 31987087a20abfe27e750b56898320c137e3c8a7..4e54d52235fb0f0c28efc938ad53fe5cc83fea0b 100644 --- a/src/swapFilter.cpp +++ b/src/swapFilter.cpp @@ -19,10 +19,10 @@ */ #include "swapFilter.h" + #include "helper.h" -SwapFilter::SwapFilter() - :Filter() +SwapFilter::SwapFilter() : Filter() { mSwapVertically.setMinimum(0.); mSwapVertically.setMaximum(1.); @@ -42,24 +42,24 @@ cv::Mat SwapFilter::act(cv::Mat &img, cv::Mat &res) bool sV = (bool) mSwapVertically.getValue(); bool sH = (bool) mSwapHorizontally.getValue(); - if (sV && sH) - cv::flip(img, res, -1); // both - else if (sV) - cv::flip(img, res, 0); // vertical - else if (sH) - cv::flip(img, res, 1); // horizontal - else - res = img; // nothing to do + if(sV && sH) + cv::flip(img, res, -1); // both + else if(sV) + cv::flip(img, res, 0); // vertical + else if(sH) + cv::flip(img, res, 1); // horizontal + else + res = img; // nothing to do return res; } -Parameter* SwapFilter::getSwapHorizontally() +Parameter *SwapFilter::getSwapHorizontally() { return &mSwapHorizontally; } -Parameter* SwapFilter::getSwapVertically() +Parameter *SwapFilter::getSwapVertically() { return &mSwapVertically; } diff --git a/src/tracker.cpp b/src/tracker.cpp index 4ff07dd1924bfc102079cd1112802b189d31ff00..7a7c8fa226c642cde2f0475374cf496ce9b556c0 100644 --- a/src/tracker.cpp +++ b/src/tracker.cpp @@ -18,20 +18,20 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <opencv2/opencv.hpp> - -#include <ctime> -#include <iomanip> - -#include "helper.h" #include "tracker.h" -#include "petrack.h" + #include "animation.h" #include "control.h" -#include "stereoWidget.h" +#include "helper.h" #include "multiColorMarkerWidget.h" #include "pMessageBox.h" +#include "petrack.h" #include "recognitionRoiItem.h" +#include "stereoWidget.h" + +#include <ctime> +#include <iomanip> +#include <opencv2/opencv.hpp> #define MIN_WIN_SIZE 3. @@ -42,113 +42,84 @@ */ inline float errorToQual(float error) { - return 80.F - error/20.F; + return 80.F - error / 20.F; } -TrackPoint::TrackPoint() - : mQual(0), - mMarkerID(-1), - mSp(-1., -1., -1.) -{ -} -TrackPoint::TrackPoint(const Vec2F &p) - : Vec2F(p), - mQual(0), - mMarkerID(-1), - mSp(-1., -1., -1.) +TrackPoint::TrackPoint() : mQual(0), mMarkerID(-1), mSp(-1., -1., -1.) {} +TrackPoint::TrackPoint(const Vec2F &p) : Vec2F(p), mQual(0), mMarkerID(-1), mSp(-1., -1., -1.) {} +TrackPoint::TrackPoint(const Vec2F &p, int qual) : Vec2F(p), mQual(qual), mMarkerID(-1), mSp(-1., -1., -1.) {} +TrackPoint::TrackPoint(const Vec2F &p, int qual, int markerID) : + Vec2F(p), mQual(qual), mMarkerID(markerID), mSp(-1., -1., -1.) { } -TrackPoint::TrackPoint(const Vec2F &p, int qual) - : Vec2F(p), - mQual(qual), - mMarkerID(-1), - mSp(-1., -1., -1.) -{ -} -TrackPoint::TrackPoint(const Vec2F &p, int qual, int markerID) - : Vec2F(p), - mQual(qual), - mMarkerID(markerID), - mSp(-1.,-1.,-1.) -{ -} -TrackPoint::TrackPoint(const Vec2F &p, int qual, const QColor &col) - : Vec2F(p), - mCol(col), - mQual(qual), - mMarkerID(-1), - mSp(-1., -1., -1.) +TrackPoint::TrackPoint(const Vec2F &p, int qual, const QColor &col) : + Vec2F(p), mCol(col), mQual(qual), mMarkerID(-1), mSp(-1., -1., -1.) { } -TrackPoint::TrackPoint(const Vec2F &p, int qual, const Vec2F &colPoint, const QColor &col) - : Vec2F(p), - mColPoint(colPoint), - mCol(col), - mQual(qual), - mMarkerID(-1), - mSp(-1., -1., -1.) +TrackPoint::TrackPoint(const Vec2F &p, int qual, const Vec2F &colPoint, const QColor &col) : + Vec2F(p), mColPoint(colPoint), mCol(col), mQual(qual), mMarkerID(-1), mSp(-1., -1., -1.) { } -const TrackPoint& TrackPoint::operator=(const Vec2F& v) +const TrackPoint &TrackPoint::operator=(const Vec2F &v) { Vec2F::operator=(v); return *this; } -const TrackPoint& TrackPoint::operator+=(const Vec2F& v) +const TrackPoint &TrackPoint::operator+=(const Vec2F &v) { Vec2F::operator+=(v); return *this; } -const TrackPoint TrackPoint::operator+(const Vec2F& v) const +const TrackPoint TrackPoint::operator+(const Vec2F &v) const { - return TrackPoint(*this) += v; //Vec2F(mX + v.mX, mY + v.mY); + return TrackPoint(*this) += v; // Vec2F(mX + v.mX, mY + v.mY); } //-------------------------------------------------------------------------- // the list index is the frame number plus mFirstFrame 0..mLastFrame-mFirstFrame // no frame is left blank -TrackPerson::TrackPerson() - : mNr(0), - mHeight(MIN_HEIGHT), - mHeightCount(0), - mFirstFrame(-1), - mLastFrame(0), - mNewReco(false), - mComment(), - mNrInBg(0), - mColCount(0) +TrackPerson::TrackPerson() : + mNr(0), + mHeight(MIN_HEIGHT), + mHeightCount(0), + mFirstFrame(-1), + mLastFrame(0), + mNewReco(false), + mComment(), + mNrInBg(0), + mColCount(0) { } -TrackPerson::TrackPerson(int nr, int frame, const TrackPoint &p) - : mNr(nr), - mMarkerID(-1), - mHeight(MIN_HEIGHT), - mHeightCount(0), - mFirstFrame(frame), - mLastFrame(frame), - mNewReco(true), - mCol(p.color()), - mComment(), - mColCount(1) +TrackPerson::TrackPerson(int nr, int frame, const TrackPoint &p) : + mNr(nr), + mMarkerID(-1), + mHeight(MIN_HEIGHT), + mHeightCount(0), + mFirstFrame(frame), + mLastFrame(frame), + mNewReco(true), + mCol(p.color()), + mComment(), + mColCount(1) { append(p); } -TrackPerson::TrackPerson(int nr, int frame, const TrackPoint &p, int markerID) - : mNr(nr), - mMarkerID(markerID), - mHeight(MIN_HEIGHT), - mHeightCount(0), - mFirstFrame(frame), - mLastFrame(frame), - mNewReco(true), - mCol(p.color()), - mComment(), - mColCount(1) +TrackPerson::TrackPerson(int nr, int frame, const TrackPoint &p, int markerID) : + mNr(nr), + mMarkerID(markerID), + mHeight(MIN_HEIGHT), + mHeightCount(0), + mFirstFrame(frame), + mLastFrame(frame), + mNewReco(true), + mCol(p.color()), + mComment(), + mColCount(1) { append(p); } @@ -156,9 +127,9 @@ TrackPerson::TrackPerson(int nr, int frame, const TrackPoint &p, int markerID) // mittelt alle erkannten farben der trackpoints zu einer farbe der trackperson void TrackPerson::addColor(const QColor &col) { - mCol.setRed( (mColCount * mCol.red() + col.red()) / (mColCount+1)); - mCol.setBlue( (mColCount * mCol.blue() + col.blue()) / (mColCount+1)); - mCol.setGreen((mColCount * mCol.green() + col.green()) / (mColCount+1)); + mCol.setRed((mColCount * mCol.red() + col.red()) / (mColCount + 1)); + mCol.setBlue((mColCount * mCol.blue() + col.blue()) / (mColCount + 1)); + mCol.setGreen((mColCount * mCol.green() + col.green()) / (mColCount + 1)); ++mColCount; } @@ -167,32 +138,32 @@ void TrackPerson::addColor(const QColor &col) void TrackPerson::optimizeColor() { // ausreisser herausnehmen ueber die koordinate der farbe - int i, j; + int i, j; Vec2F v, vBefore; - int anz1 = 0, anz2 = 0; - bool swap = false; + int anz1 = 0, anz2 = 0; + bool swap = false; // den ersten farbpunkt suchen und vBefore initial setzen - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if (at(i).color().isValid()) + if(at(i).color().isValid()) { vBefore = at(i).colPoint() - at(i); break; } } - if (at(i).color().isValid()) + if(at(i).color().isValid()) ++anz1; // testen, auf welcher seit der farbmarker haeufiger gesehen wird - for (j = i+1; j < size(); ++j) + for(j = i + 1; j < size(); ++j) { - if (at(j).color().isValid()) + if(at(j).color().isValid()) { v = at(j).colPoint() - at(j); - if ((v * vBefore) < 0) + if((v * vBefore) < 0) swap = !swap; - if (swap) + if(swap) ++anz2; else ++anz1; @@ -200,28 +171,28 @@ void TrackPerson::optimizeColor() } } swap = false; - if (at(i).color().isValid()) + if(at(i).color().isValid()) vBefore = at(i).colPoint() - at(i); // farben mit geringerer anzahl loeschen QColor colInvalid; - if (anz2 > anz1) + if(anz2 > anz1) (*this)[i].setColor(colInvalid); - for (j = i+1; j < size(); ++j) + for(j = i + 1; j < size(); ++j) { - if (at(j).color().isValid()) + if(at(j).color().isValid()) { v = at(j).colPoint() - at(j); - if ((v * vBefore) < 0) + if((v * vBefore) < 0) swap = !swap; - if (swap) + if(swap) { - if (anz1 > anz2) + if(anz1 > anz2) (*this)[j].setColor(colInvalid); } else { - if (anz2 > anz1) + if(anz2 > anz1) (*this)[j].setColor(colInvalid); } vBefore = v; @@ -232,9 +203,9 @@ void TrackPerson::optimizeColor() QList<int> r; QList<int> g; QList<int> b; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if (at(i).color().isValid()) + if(at(i).color().isValid()) { r.append(at(i).color().red()); g.append(at(i).color().green()); @@ -244,8 +215,8 @@ void TrackPerson::optimizeColor() std::sort(r.begin(), r.end()); std::sort(g.begin(), g.end()); std::sort(b.begin(), b.end()); - if (r.size()>0 && g.size()>0 && b.size()>0) // kann eigentlich nicht vorkommen - setColor(QColor(r[(r.size()-1)/2],g[(g.size()-1)/2],b[(b.size()-1)/2])); + if(r.size() > 0 && g.size() > 0 && b.size() > 0) // kann eigentlich nicht vorkommen + setColor(QColor(r[(r.size() - 1) / 2], g[(g.size() - 1) / 2], b[(b.size() - 1) / 2])); } void TrackPerson::recalcHeight(float altitude) @@ -256,20 +227,20 @@ void TrackPerson::recalcHeight(float altitude) resetHeight(); - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) { z = at(i).sp().z(); - if (z >= 0) + if(z >= 0) { ++mHeightCount; - //h += z; + // h += z; zList.append(z); } } - if (mHeightCount > 0) + if(mHeightCount > 0) { std::sort(zList.begin(), zList.end()); - mHeight = zList[mHeightCount/2]; + mHeight = zList[mHeightCount / 2]; mHeight = altitude - mHeight; } } @@ -279,32 +250,35 @@ void TrackPerson::recalcHeight(float altitude) double TrackPerson::getNearestZ(int i, int *extrapolated) { *extrapolated = 0; - if ((i < 0) || (i >= size())) // indexueberpruefung + if((i < 0) || (i >= size())) // indexueberpruefung return -1.; - if (at(i).sp().z() >= 0) + if(at(i).sp().z() >= 0) return at(i).sp().z(); else // -1 an aktueller hoehe { int nrFor = 1; int nrRew = 1; - while ((i+nrFor < size()) && (at(i+nrFor).sp().z() < 0)) // nach && wird nur ausgefuehrt, wenn erstes true == size() also nicht + while((i + nrFor < size()) && + (at(i + nrFor).sp().z() < 0)) // nach && wird nur ausgefuehrt, wenn erstes true == size() also nicht nrFor++; - while ((i-nrRew >= 0) && (at(i-nrRew).sp().z() < 0)) // nach && wird nur ausgefuehrt, wenn erstes true == size() also nicht + while((i - nrRew >= 0) && + (at(i - nrRew).sp().z() < 0)) // nach && wird nur ausgefuehrt, wenn erstes true == size() also nicht nrRew++; - if ((i+nrFor == size()) && (i-nrRew < 0)) // gar keine Hoeheninfo in trj gefunden + if((i + nrFor == size()) && (i - nrRew < 0)) // gar keine Hoeheninfo in trj gefunden return -1.; - else if (i+nrFor == size()) // nur in Vergangenheit hoeheninfo gefunden + else if(i + nrFor == size()) // nur in Vergangenheit hoeheninfo gefunden { *extrapolated = 2; - return at(i-nrRew).sp().z(); + return at(i - nrRew).sp().z(); } - else if (i-nrRew < 0) // nur in der zukunft hoeheninfo gefunden + else if(i - nrRew < 0) // nur in der zukunft hoeheninfo gefunden { *extrapolated = 1; - return at(i+nrFor).sp().z(); + return at(i + nrFor).sp().z(); } else // in beiden richtungen hoeheninfo gefunden - INTERPOLATION, NICHT EXTRAPOLATION - return at(i-nrRew).sp().z()+nrRew*(at(i+nrFor).sp().z()-at(i-nrRew).sp().z())/(nrFor+nrRew); // lineare interpolation + return at(i - nrRew).sp().z() + + nrRew * (at(i + nrFor).sp().z() - at(i - nrRew).sp().z()) / (nrFor + nrRew); // lineare interpolation } } @@ -336,48 +310,56 @@ double TrackPerson::getNearestZ(int i, int *extrapolated) */ bool TrackPerson::insertAtFrame(int frame, const TrackPoint &point, int persNr, bool extrapolate) { - int i; - Vec2F tmp; // ua. zur linearen Interpolation - TrackPoint tp; // default: 0 = ist schlechteste qualitaet - double distance; + int i; + Vec2F tmp; // ua. zur linearen Interpolation + TrackPoint tp; // default: 0 = ist schlechteste qualitaet + double distance; - if (frame > mLastFrame) + if(frame > mLastFrame) { // lineare interpolation, wenn frames uebersprungen wurden - if (frame-mLastFrame-1 > 0) + if(frame - mLastFrame - 1 > 0) { - tmp.setX((point.x()-last().x())/(frame-mLastFrame)); - tmp.setY((point.y()-last().y())/(frame-mLastFrame)); + tmp.setX((point.x() - last().x()) / (frame - mLastFrame)); + tmp.setY((point.y() - last().y()) / (frame - mLastFrame)); tp = last(); tp.setQual(0); - for (i = 0; i < frame-mLastFrame-1; ++i) + for(i = 0; i < frame - mLastFrame - 1; ++i) { tp += tmp; append(tp); } append(point); } - else if (extrapolate && ((mLastFrame-mFirstFrame) > 0)) // mind. 2 trackpoints sind in liste! + else if(extrapolate && ((mLastFrame - mFirstFrame) > 0)) // mind. 2 trackpoints sind in liste! { - tmp = last()-at(size()-2); // vektor zw letztem und vorletztem pkt - // der Abstand zum extrapoliertem Ziel darf nicht groesser als 2x so gross sein, wie die entfernung vorheriger trackpoints - // eine mindestbewegung wird vorausgesetzt, da sonst bewegungen aus dem "stillstand" immer als fehler angesehen werden + tmp = last() - at(size() - 2); // vektor zw letztem und vorletztem pkt + // der Abstand zum extrapoliertem Ziel darf nicht groesser als 2x so gross sein, wie die entfernung + // vorheriger trackpoints eine mindestbewegung wird vorausgesetzt, da sonst bewegungen aus dem "stillstand" + // immer als fehler angesehen werden // am besten waere eine fehlerbetrachtung in abhaengigkeit von der geschwindigkeit - nicht gemacht! - if (((distance = ((last()+tmp).distanceToPoint(point))) > EXTRAPOLATE_FACTOR*tmp.length()) && (distance > 3)) + if(((distance = ((last() + tmp).distanceToPoint(point))) > EXTRAPOLATE_FACTOR * tmp.length()) && + (distance > 3)) { - if (!((last().qual() == 0) && (at(size()-2).qual() == 0))) // das vorherige einfuegen ist 2x nicht auch schon schlecht gewesen + if(!((last().qual() == 0) && + (at(size() - 2).qual() == 0))) // das vorherige einfuegen ist 2x nicht auch schon schlecht gewesen { tp = point; - debout << "Warning: Extrapolation instaed of tracking because of big difference from tracked point in speed and direction of person " << persNr+1 << " between frame " << mLastFrame << " and " << mLastFrame+1 << "!" << std::endl; - tp = last()+tmp; // nur vektor wird hier durch + geaendert - tp.setQual(0); - // im anschluss koennte noch dunkelster pkt in umgebung gesucht werden!!! - // keine Extrapolation der Groesse + debout << "Warning: Extrapolation instaed of tracking because of big difference from tracked point " + "in speed and direction of person " + << persNr + 1 << " between frame " << mLastFrame << " and " << mLastFrame + 1 << "!" + << std::endl; + tp = last() + tmp; // nur vektor wird hier durch + geaendert + tp.setQual(0); + // im anschluss koennte noch dunkelster pkt in umgebung gesucht werden!!! + // keine Extrapolation der Groesse append(tp); } else { - debout << "Warning: Because of three big differences from tracked point in speed and direction between last three frames the track point of person " << persNr+1 << " at " << mLastFrame+1 << " was NOT inserted!" << std::endl; + debout << "Warning: Because of three big differences from tracked point in speed and direction " + "between last three frames the track point of person " + << persNr + 1 << " at " << mLastFrame + 1 << " was NOT inserted!" << std::endl; return false; } } @@ -388,40 +370,48 @@ bool TrackPerson::insertAtFrame(int frame, const TrackPoint &point, int persNr, append(point); mLastFrame = frame; } - else if (frame < mFirstFrame) + else if(frame < mFirstFrame) { - if (mFirstFrame-frame-1 > 0) + if(mFirstFrame - frame - 1 > 0) { - tmp.setX((point.x()-first().x())/(mFirstFrame-frame)); - tmp.setY((point.y()-first().y())/(mFirstFrame-frame)); + tmp.setX((point.x() - first().x()) / (mFirstFrame - frame)); + tmp.setY((point.y() - first().y()) / (mFirstFrame - frame)); tp = first(); tp.setQual(0); - for (i = 0; i < mFirstFrame-frame-1; ++i) + for(i = 0; i < mFirstFrame - frame - 1; ++i) { tp += tmp; prepend(tp); } prepend(point); } - else if (extrapolate && ((mLastFrame-mFirstFrame) > 0)) // mind. 2 trackpoints sind in liste! + else if(extrapolate && ((mLastFrame - mFirstFrame) > 0)) // mind. 2 trackpoints sind in liste! { - tmp = at(0)-at(1); // vektor zw letztem und vorletztem pkt - // der Abstand zum extrapoliertem Ziel darf nicht groesser als 2x so gross sein, wie die entfernung vorheriger trackpoints - // eine mindestbewegung wird vorausgesetzt, da sonst bewegungen aus dem "stillstand" immer als fehler angesehen werden + tmp = at(0) - at(1); // vektor zw letztem und vorletztem pkt + // der Abstand zum extrapoliertem Ziel darf nicht groesser als 2x so gross sein, wie die entfernung + // vorheriger trackpoints eine mindestbewegung wird vorausgesetzt, da sonst bewegungen aus dem "stillstand" + // immer als fehler angesehen werden // am besten waere eine fehlerbetrachtung in abhaengigkeit von der geschwindigkeit - nicht gemacht! - if (((distance = (at(0)+tmp).distanceToPoint(point)) > EXTRAPOLATE_FACTOR*tmp.length()) && (distance > 3)) + if(((distance = (at(0) + tmp).distanceToPoint(point)) > EXTRAPOLATE_FACTOR * tmp.length()) && + (distance > 3)) { - if (!((at(0).qual() == 0) && (at(1).qual() == 0))) // das vorherige einfuegen ist 2x nicht auch schon schlecht gewesen + if(!((at(0).qual() == 0) && + (at(1).qual() == 0))) // das vorherige einfuegen ist 2x nicht auch schon schlecht gewesen { tp = point; - debout << "Warning: Extrapolation instaed of tracking because of big difference from tracked point in speed and direction of person " << persNr+1 << " between frame " << mFirstFrame << " and " << mFirstFrame-1 << "!" << std::endl; - tp = at(0)+tmp; // nur vektor wird hier durch + geaendert + debout << "Warning: Extrapolation instaed of tracking because of big difference from tracked point " + "in speed and direction of person " + << persNr + 1 << " between frame " << mFirstFrame << " and " << mFirstFrame - 1 << "!" + << std::endl; + tp = at(0) + tmp; // nur vektor wird hier durch + geaendert tp.setQual(0); prepend(tp); } else { - debout << "Warning: Because of three big differences from tracked point in speed and direction between last three frames the track point of person " << persNr+1 << " at " << mLastFrame-1 << " was NOT inserted!" << std::endl; + debout << "Warning: Because of three big differences from tracked point in speed and direction " + "between last three frames the track point of person " + << persNr + 1 << " at " << mLastFrame - 1 << " was NOT inserted!" << std::endl; return false; } } @@ -434,59 +424,69 @@ bool TrackPerson::insertAtFrame(int frame, const TrackPoint &point, int persNr, } else { - // dieser Zweig wird insbesondere von reco durchlaufen, da vorher immer auch noch getrackt wird und reco draufgesetzt wird!!! + // dieser Zweig wird insbesondere von reco durchlaufen, da vorher immer auch noch getrackt wird und reco + // draufgesetzt wird!!! tp = point; - if (point.qual()<100 && point.qual()>80) // erkannte Person aber ohne strukturmarker + if(point.qual() < 100 && point.qual() > 80) // erkannte Person aber ohne strukturmarker { - // wenn in angrenzenden Frames qual groesse 90 (100 oder durch vorheriges verschieben entstanden), dann verschieben - if (trackPointExist(frame-1) && trackPointAt(frame-1).qual()>90) + // wenn in angrenzenden Frames qual groesse 90 (100 oder durch vorheriges verschieben entstanden), dann + // verschieben + if(trackPointExist(frame - 1) && trackPointAt(frame - 1).qual() > 90) { tp.setQual(95); - tmp = point+(trackPointAt(frame-1)-trackPointAt(frame-1).colPoint()); - tp.set(tmp.x(),tmp.y()); - debout << "Warning: move trackpoint according to last distance of structur marker and color marker of person "<< persNr+1 << ":"<< std::endl; - debout << " "<< point <<" -> "<< tp << std::endl; + tmp = point + (trackPointAt(frame - 1) - trackPointAt(frame - 1).colPoint()); + tp.set(tmp.x(), tmp.y()); + debout << "Warning: move trackpoint according to last distance of structur marker and color marker of " + "person " + << persNr + 1 << ":" << std::endl; + debout << " " << point << " -> " << tp << std::endl; } - else if (trackPointExist(frame+1) && trackPointAt(frame+1).qual()>90) + else if(trackPointExist(frame + 1) && trackPointAt(frame + 1).qual() > 90) { tp.setQual(95); - tmp = point+(trackPointAt(frame+1)-trackPointAt(frame+1).colPoint()); - tp.set(tmp.x(),tmp.y()); - debout << "Warning: move trackpoint according to last distance of structur marker and color marker of person "<< persNr+1 << ":"<< std::endl; - debout << " "<< point <<" -> "<< tp << std::endl; + tmp = point + (trackPointAt(frame + 1) - trackPointAt(frame + 1).colPoint()); + tp.set(tmp.x(), tmp.y()); + debout << "Warning: move trackpoint according to last distance of structur marker and color marker of " + "person " + << persNr + 1 << ":" << std::endl; + debout << " " << point << " -> " << tp << std::endl; } } // ueberprueft, welcher punkt besser - if (tp.qual() > at(frame-mFirstFrame).qual()) + if(tp.qual() > at(frame - mFirstFrame).qual()) { // warnung ausgeben, wenn replacement (fuer gewoehnlich von reco) den pfadverlauf abrupt aendert - if (trackPointExist(frame-1)) - tmp = trackPointAt(frame) - trackPointAt(frame-1); - else if (trackPointExist(frame+1)) - tmp = trackPointAt(frame+1) - trackPointAt(frame); - if ((trackPointExist(frame-1) || trackPointExist(frame+1)) && ((distance = (trackPointAt(frame).distanceToPoint(tp))) > 1.5*tmp.length()) && (distance > 3)) + if(trackPointExist(frame - 1)) + tmp = trackPointAt(frame) - trackPointAt(frame - 1); + else if(trackPointExist(frame + 1)) + tmp = trackPointAt(frame + 1) - trackPointAt(frame); + if((trackPointExist(frame - 1) || trackPointExist(frame + 1)) && + ((distance = (trackPointAt(frame).distanceToPoint(tp))) > 1.5 * tmp.length()) && (distance > 3)) { int anz; - debout << "Warning: Big difference in location between existing and replacing track point of person " << persNr+1 << " in frame " << frame << "!" << std::endl; + debout << "Warning: Big difference in location between existing and replacing track point of person " + << persNr + 1 << " in frame " << frame << "!" << std::endl; // qualitaet anpassen, da der weg zum pkt nicht der richtige gewesen sein kann // zurueck - for (anz=1; trackPointExist(frame-anz) && (trackPointAt(frame-anz).qual() < 100); ++anz) + for(anz = 1; trackPointExist(frame - anz) && (trackPointAt(frame - anz).qual() < 100); ++anz) ; - for (i=1; i<(anz-1); ++i) // anz ist einer zu viel; zudem nur boie anz-1 , da sonst eh nur mit 1 multipliziert wuerde - (*this)[frame-mFirstFrame-i].setQual((i*trackPointAt(frame-i).qual())/anz); + for(i = 1; i < (anz - 1); + ++i) // anz ist einer zu viel; zudem nur boie anz-1 , da sonst eh nur mit 1 multipliziert wuerde + (*this)[frame - mFirstFrame - i].setQual((i * trackPointAt(frame - i).qual()) / anz); // vor - for (anz=1; trackPointExist(frame+anz) && (trackPointAt(frame+anz).qual() < 100); ++anz) + for(anz = 1; trackPointExist(frame + anz) && (trackPointAt(frame + anz).qual() < 100); ++anz) ; - for (i=1; i<(anz-1); ++i) // anz ist einer zu viel; zudem nur boie anz-1 , da sonst eh nur mit 1 multipliziert wuerde - (*this)[frame-mFirstFrame+i].setQual((i*trackPointAt(frame+i).qual())/anz); + for(i = 1; i < (anz - 1); + ++i) // anz ist einer zu viel; zudem nur boie anz-1 , da sonst eh nur mit 1 multipliziert wuerde + (*this)[frame - mFirstFrame + i].setQual((i * trackPointAt(frame + i).qual()) / anz); } - replace(frame-mFirstFrame, tp); + replace(frame - mFirstFrame, tp); - if (tp.qual() > 100) // manual add // after inserting, because point ist const - (*this)[frame-mFirstFrame].setQual(100); // so moving of a point is possible + if(tp.qual() > 100) // manual add // after inserting, because point ist const + (*this)[frame - mFirstFrame].setQual(100); // so moving of a point is possible } else return false; @@ -496,14 +496,14 @@ bool TrackPerson::insertAtFrame(int frame, const TrackPoint &point, int persNr, bool TrackPerson::trackPointExist(int frame) const { - if (frame >= mFirstFrame && frame <= mLastFrame) + if(frame >= mFirstFrame && frame <= mLastFrame) return true; else return false; } -const TrackPoint& TrackPerson::trackPointAt(int frame) const // & macht bei else probleme, sonst mit [] zugreifbar +const TrackPoint &TrackPerson::trackPointAt(int frame) const // & macht bei else probleme, sonst mit [] zugreifbar { - return at(frame-mFirstFrame); + return at(frame - mFirstFrame); } /** @@ -514,8 +514,8 @@ const TrackPoint& TrackPerson::trackPointAt(int frame) const // & macht bei else */ double TrackPerson::distanceToNextFrame(int frame) const { - if (frame >= mFirstFrame && frame+1 <= mLastFrame) - return at(frame-mFirstFrame).distanceToPoint(at(frame-mFirstFrame+1)); + if(frame >= mFirstFrame && frame + 1 <= mLastFrame) + return at(frame - mFirstFrame).distanceToPoint(at(frame - mFirstFrame + 1)); else return -1; } @@ -533,8 +533,9 @@ double TrackPerson::distanceToNextFrame(int frame) const Tracker::Tracker(QWidget *wParent) { - mMainWindow = (class Petrack*) wParent; - mTermCriteria = cv::TermCriteria(cv::TermCriteria::COUNT|cv::TermCriteria::EPS, 20, 0.03); ///< maxIter=20 and epsilon=0.03 + mMainWindow = (class Petrack *) wParent; + mTermCriteria = + cv::TermCriteria(cv::TermCriteria::COUNT | cv::TermCriteria::EPS, 20, 0.03); ///< maxIter=20 and epsilon=0.03 reset(); } @@ -544,10 +545,11 @@ Tracker::Tracker(QWidget *wParent) void Tracker::init(cv::Size size) { clear(); // loescht liste aller getrackten personen - // nicht mehr noetig, da nicht mehr in track selber // jetzt start, war prevImg == NULL && prevFrame == -1 zeigt an, dass ein neuer Trackingprozess beginnt / neue Bildfolge + // nicht mehr noetig, da nicht mehr in track selber // jetzt start, war prevImg == NULL && prevFrame == -1 zeigt an, + // dass ein neuer Trackingprozess beginnt / neue Bildfolge - mGrey.create(size,CV_8UC1); - mPrevGrey.create(size,CV_8UC1); + mGrey.create(size, CV_8UC1); + mPrevGrey.create(size, CV_8UC1); reset(); } @@ -560,19 +562,19 @@ void Tracker::reset() void Tracker::resize(cv::Size size) { - if (!mGrey.empty() && ((size.width != mGrey.cols) || (size.height != mGrey.rows))) + if(!mGrey.empty() && ((size.width != mGrey.cols) || (size.height != mGrey.rows))) { - mGrey.create(size,CV_8UC1); + mGrey.create(size, CV_8UC1); // umkopieren des alten Graubildes in groesseres oder auch kleineres bild (wg border) // aus borderFilter kopiert - if (!mPrevGrey.empty()) + if(!mPrevGrey.empty()) { - int s = (size.width-mPrevGrey.cols)/2; - if( s >= 0) - cv::copyMakeBorder(mPrevGrey,mPrevGrey,s,s,s,s,cv::BORDER_CONSTANT,cv::Scalar(0)); + int s = (size.width - mPrevGrey.cols) / 2; + if(s >= 0) + cv::copyMakeBorder(mPrevGrey, mPrevGrey, s, s, s, s, cv::BORDER_CONSTANT, cv::Scalar(0)); else - mPrevGrey = mPrevGrey(cv::Rect(-s,-s,mPrevGrey.cols+2*s,mPrevGrey.rows+2*s)); + mPrevGrey = mPrevGrey(cv::Rect(-s, -s, mPrevGrey.cols + 2 * s, mPrevGrey.rows + 2 * s)); } } } @@ -582,17 +584,17 @@ void Tracker::splitPerson(int pers, int frame) { int j; - if (at(pers).firstFrame()< frame) + if(at(pers).firstFrame() < frame) { append(at(pers)); // alte trj einkuerzen und ab aktuellem frame zukunft loeschen - for (j = 0; j < at(pers).lastFrame()-frame+1; ++j) + for(j = 0; j < at(pers).lastFrame() - frame + 1; ++j) (*this)[pers].removeLast(); - (*this)[pers].setLastFrame(frame-1); + (*this)[pers].setLastFrame(frame - 1); // neu angehaengte/gedoppelte trajektorie - for (j = 0; j < frame-last().firstFrame(); ++j) + for(j = 0; j < frame - last().firstFrame(); ++j) last().removeFirst(); last().setFirstFrame(frame); } @@ -606,12 +608,14 @@ void Tracker::splitPerson(int pers, int frame) * @param onlyVisible set of people for whom to do it (empty means everyone) * @return true if a trajectory was split */ -bool Tracker::splitPersonAt(const Vec2F& point, int frame, QSet<int> onlyVisible) +bool Tracker::splitPersonAt(const Vec2F &point, int frame, QSet<int> onlyVisible) { int i; - for (i = 0; i < size(); ++i) // ueber TrackPerson - if (((onlyVisible.empty()) || (onlyVisible.contains(i))) && (at(i).trackPointExist(frame) && (at(i).trackPointAt(frame).distanceToPoint(point) < mMainWindow->getHeadSize(nullptr, i, frame)/2.))) + for(i = 0; i < size(); ++i) // ueber TrackPerson + if(((onlyVisible.empty()) || (onlyVisible.contains(i))) && + (at(i).trackPointExist(frame) && + (at(i).trackPointAt(frame).distanceToPoint(point) < mMainWindow->getHeadSize(nullptr, i, frame) / 2.))) { splitPerson(i, frame); @@ -631,17 +635,17 @@ bool Tracker::delPointOf(int pers, int direction, int frame) { int j; - if (direction == -1) + if(direction == -1) { - for (j = 0; j < frame-at(pers).firstFrame(); ++j) + for(j = 0; j < frame - at(pers).firstFrame(); ++j) (*this)[pers].removeFirst(); (*this)[pers].setFirstFrame(frame); } - else if (direction == 0) + else if(direction == 0) removeAt(pers); - else if (direction == 1) + else if(direction == 1) { - for (j = 0; j < at(pers).lastFrame()-frame; ++j) + for(j = 0; j < at(pers).lastFrame() - frame; ++j) (*this)[pers].removeLast(); (*this)[pers].setLastFrame(frame); } @@ -661,12 +665,14 @@ bool Tracker::delPointOf(int pers, int direction, int frame) * @param onlyVisible set of people whose points could be deleted; empty means everyone * @return true if deletion occured */ -bool Tracker::delPoint(const Vec2F& point, int direction, int frame, QSet<int> onlyVisible) +bool Tracker::delPoint(const Vec2F &point, int direction, int frame, QSet<int> onlyVisible) { int i; - for (i = 0; i < size(); ++i) // ueber TrackPerson - if (((onlyVisible.empty()) || (onlyVisible.contains(i))) && (at(i).trackPointExist(frame) && (at(i).trackPointAt(frame).distanceToPoint(point) < mMainWindow->getHeadSize(nullptr, i, frame)/2.))) + for(i = 0; i < size(); ++i) // ueber TrackPerson + if(((onlyVisible.empty()) || (onlyVisible.contains(i))) && + (at(i).trackPointExist(frame) && + (at(i).trackPointAt(frame).distanceToPoint(point) < mMainWindow->getHeadSize(nullptr, i, frame) / 2.))) { delPointOf(i, direction, frame); return true; @@ -683,28 +689,28 @@ void Tracker::delPointAll(int direction, int frame) { int i, j; - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { - if (at(i).trackPointExist(frame)) // + if(at(i).trackPointExist(frame)) // { - if (direction == -1) + if(direction == -1) { - for (j = 0; j < frame-at(i).firstFrame(); ++j) + for(j = 0; j < frame - at(i).firstFrame(); ++j) (*this)[i].removeFirst(); (*this)[i].setFirstFrame(frame); } - else if (direction == 0) + else if(direction == 0) removeAt(i--); // nach Loeschen wird i um 1 erniedrigt - else if (direction == 1) + else if(direction == 1) { - for (j = 0; j < at(i).lastFrame()-frame; ++j) + for(j = 0; j < at(i).lastFrame() - frame; ++j) (*this)[i].removeLast(); (*this)[i].setLastFrame(frame); } } - else if (((direction == -1) && (frame > at(i).lastFrame())) || - (direction == 0) || - ((direction == 1) && (frame < at(i).firstFrame()))) + else if( + ((direction == -1) && (frame > at(i).lastFrame())) || (direction == 0) || + ((direction == 1) && (frame < at(i).firstFrame()))) { removeAt(i); i--; @@ -718,19 +724,19 @@ void Tracker::delPointAll(int direction, int frame) // man koennte noch unterscheiden, ob trajektorie aktuell in petrack zu sehen sein soll void Tracker::delPointInsideROI() { - int i, j; + int i, j; QRectF rect = mMainWindow->getRecoRoiItem()->rect(); - bool inside; + bool inside; - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { inside = ((at(i).size() > 0) && rect.contains(at(i).at(0).x(), at(i).at(0).y())); - for (j = 1; j < at(i).size(); ++j) + for(j = 1; j < at(i).size(); ++j) { - if (inside != rect.contains(at(i).at(j).x(), at(i).at(j).y())) // aenderung von inside + if(inside != rect.contains(at(i).at(j).x(), at(i).at(j).y())) // aenderung von inside { - splitPerson(i, at(i).firstFrame()+j); - if (inside) + splitPerson(i, at(i).firstFrame() + j); + if(inside) { removeAt(i); i--; @@ -739,7 +745,8 @@ void Tracker::delPointInsideROI() break; } } - if (inside){ + if(inside) + { // rest loeschen removeAt(i); i--; @@ -751,14 +758,14 @@ void Tracker::delPointInsideROI() // man koennte noch unterscheiden, ob trajektorie aktuell in petrack zu sehen sein soll void Tracker::delPointROI() { - int i, j, anz=0; + int i, j, anz = 0; QRectF rect = mMainWindow->getRecoRoiItem()->rect(); - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { - for (j = 0; j < at(i).size(); ++j) + for(j = 0; j < at(i).size(); ++j) { - if (rect.contains(at(i).at(j).x(), at(i).at(j).y())) + if(rect.contains(at(i).at(j).x(), at(i).at(j).y())) { anz++; removeAt(i); @@ -767,7 +774,7 @@ void Tracker::delPointROI() } } } - debout << "deleted "<<anz<<" trajectories!"<< std::endl; + debout << "deleted " << anz << " trajectories!" << std::endl; } /** @@ -781,38 +788,42 @@ void Tracker::delPointROI() * @param onlyVisible list of visible persons * @return if a comment has been saved */ -bool Tracker::editTrackPersonComment(const Vec2F& point, int frame, const QSet<int>& onlyVisible) +bool Tracker::editTrackPersonComment(const Vec2F &point, int frame, const QSet<int> &onlyVisible) { - for (int i = 0; i < size(); ++i) // ueber TrackPerson + for(int i = 0; i < size(); ++i) // ueber TrackPerson { - if (((onlyVisible.empty()) || (onlyVisible.contains(i))) && (at(i).trackPointExist(frame) && - (at(i).trackPointAt(frame).distanceToPoint(point) < - mMainWindow->getHeadSize(nullptr, i, frame) / - 2.))) // war: MIN_DISTANCE)) // 30 ist abstand zwischen kopfen + if(((onlyVisible.empty()) || (onlyVisible.contains(i))) && + (at(i).trackPointExist(frame) && (at(i).trackPointAt(frame).distanceToPoint(point) < + mMainWindow->getHeadSize(nullptr, i, frame) / + 2.))) // war: MIN_DISTANCE)) // 30 ist abstand zwischen kopfen { QString displayedComment = at(i).comment(); - QString framePrefix = "Frame " + QString::number(frame, 'g', 5) + ": "; + QString framePrefix = "Frame " + QString::number(frame, 'g', 5) + ": "; - if (displayedComment.isEmpty()) + if(displayedComment.isEmpty()) { displayedComment.append(framePrefix); } - else if (!displayedComment.contains(framePrefix)) + else if(!displayedComment.contains(framePrefix)) { displayedComment.append("\n" + framePrefix); } - bool ok = false; - QString comment = QInputDialog::getMultiLineText(mMainWindow, QObject::tr("Add Comment"), - QObject::tr("Comment:"), - displayedComment, &ok); - - if (ok) { - if (comment.isEmpty()) { - int ret = PWarning(mMainWindow, QObject::tr("Empty comment"), - QObject::tr("Are you sure you want to save an empty comment?"), - PMessageBox::StandardButton::Save | PMessageBox::StandardButton::Cancel); - if (ret == PMessageBox::StandardButton::Cancel) { + bool ok = false; + QString comment = QInputDialog::getMultiLineText( + mMainWindow, QObject::tr("Add Comment"), QObject::tr("Comment:"), displayedComment, &ok); + + if(ok) + { + if(comment.isEmpty()) + { + int ret = PWarning( + mMainWindow, + QObject::tr("Empty comment"), + QObject::tr("Are you sure you want to save an empty comment?"), + PMessageBox::StandardButton::Save | PMessageBox::StandardButton::Cancel); + if(ret == PMessageBox::StandardButton::Cancel) + { return false; } } @@ -824,59 +835,76 @@ bool Tracker::editTrackPersonComment(const Vec2F& point, int frame, const QSet<i return false; } -bool Tracker::setTrackPersonHeight(const Vec2F& point, int frame, QSet<int> onlyVisible) +bool Tracker::setTrackPersonHeight(const Vec2F &point, int frame, QSet<int> onlyVisible) { int i; - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { - if (((onlyVisible.empty()) || (onlyVisible.contains(i))) && (at(i).trackPointExist(frame) && (at(i).trackPointAt(frame).distanceToPoint(point) < mMainWindow->getHeadSize(nullptr, i, frame)/2.))) // war: MIN_DISTANCE)) // 30 ist abstand zwischen kopfen + if(((onlyVisible.empty()) || (onlyVisible.contains(i))) && + (at(i).trackPointExist(frame) && (at(i).trackPointAt(frame).distanceToPoint(point) < + mMainWindow->getHeadSize(nullptr, i, frame) / + 2.))) // war: MIN_DISTANCE)) // 30 ist abstand zwischen kopfen { bool ok; double col_height; // col_height is negative, if height is determined through color and not yet set manually - if( at(i).height() < MIN_HEIGHT+1 ) - col_height = at(i).color().isValid() ? -mMainWindow->getControlWidget()->getColorPlot()->map(at(i).color()) : -mMainWindow->getControlWidget()->mapDefaultHeight->value(); + if(at(i).height() < MIN_HEIGHT + 1) + col_height = at(i).color().isValid() ? + -mMainWindow->getControlWidget()->getColorPlot()->map(at(i).color()) : + -mMainWindow->getControlWidget()->mapDefaultHeight->value(); else col_height = at(i).height(); - double height = QInputDialog::getDouble(mMainWindow,QObject::tr("Set person height"),QObject::tr("Person height[cm]:"), - fabs(col_height), -500, 500, 1, &ok); - if (ok) + double height = QInputDialog::getDouble( + mMainWindow, + QObject::tr("Set person height"), + QObject::tr("Person height[cm]:"), + fabs(col_height), + -500, + 500, + 1, + &ok); + if(ok) { if(height < 0) { - debout << "Warning: you entered a negative height!" << std::endl;// is not supported!" << endl; - //return false; + debout << "Warning: you entered a negative height!" << std::endl; // is not supported!" << endl; + // return false; } - // if previous value (col_height) is negative, height was determined thru color. If manually set value is the color-map value, we do not change anything + // if previous value (col_height) is negative, height was determined thru color. If manually set value + // is the color-map value, we do not change anything // @todo: @ar.graf: check if manually set values have side-effects (maybe do not show in statistics) - if (!(std::abs(col_height + height) < 0.01)) + if(!(std::abs(col_height + height) < 0.01)) { (*this)[i].setHeight(height); return true; - } else { - debout << std::endl << "No height change detected. Color-mapped height will remain set." << std::endl; + } + else + { + debout << std::endl + << "No height change detected. Color-mapped height will remain set." << std::endl; } } } } return false; } -bool Tracker::resetTrackPersonHeight(const Vec2F& point, int frame, QSet<int> onlyVisible) +bool Tracker::resetTrackPersonHeight(const Vec2F &point, int frame, QSet<int> onlyVisible) { int i; - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { - if (((onlyVisible.empty()) || (onlyVisible.contains(i))) && (at(i).trackPointExist(frame) && (at(i).trackPointAt(frame).distanceToPoint(point) < mMainWindow->getHeadSize(nullptr, i, frame)/2.))) // war: MIN_DISTANCE)) // 30 ist abstand zwischen kopfen + if(((onlyVisible.empty()) || (onlyVisible.contains(i))) && + (at(i).trackPointExist(frame) && (at(i).trackPointAt(frame).distanceToPoint(point) < + mMainWindow->getHeadSize(nullptr, i, frame) / + 2.))) // war: MIN_DISTANCE)) // 30 ist abstand zwischen kopfen { - (*this)[i].setHeight(MIN_HEIGHT); return true; - } } return false; @@ -885,41 +913,46 @@ bool Tracker::resetTrackPersonHeight(const Vec2F& point, int frame, QSet<int> on // used for calculation of 3D point for all points in frame // returns number of found points or -1 if no stereoContext available (also points without disp found are counted) -int Tracker::calcPosition(int /*frame*/) { +int Tracker::calcPosition(int /*frame*/) +{ #ifndef STEREO_DISABLED - int anz = 0, notFoundDisp = 0; - pet::StereoContext * sc = mMainWindow->getStereoContext(); - float x, y, z; + int anz = 0, notFoundDisp = 0; + pet::StereoContext *sc = mMainWindow->getStereoContext(); + float x, y, z; - if (sc) + if(sc) { - // for every point of a person, which has already identified at this frame - for (int i = 0; i < size(); ++i) // ueber TrackPerson + for(int i = 0; i < size(); ++i) // ueber TrackPerson { - - if (at(i).trackPointExist(frame)) + if(at(i).trackPointExist(frame)) { ++anz; - //TrackPoint *point = &(at(i).trackPointAt(frame)); - // ACHTUNG: BORDER NICHT BEACHTET bei p.x()...??? - // calculate height with disparity map - if (sc->getMedianXYZaround((int) at(i).trackPointAt(frame).x(), (int) at(i).trackPointAt(frame).y(), &x, &y, &z)) // nicht myRound, da pixel 0 von 0..0.99 in double geht + // TrackPoint *point = &(at(i).trackPointAt(frame)); + // ACHTUNG: BORDER NICHT BEACHTET bei p.x()...??? + // calculate height with disparity map + if(sc->getMedianXYZaround( + (int) at(i).trackPointAt(frame).x(), + (int) at(i).trackPointAt(frame).y(), + &x, + &y, + &z)) // nicht myRound, da pixel 0 von 0..0.99 in double geht { // hier kommt man nur hinein, wenn x, y, z Wert berechnet werden konnten // statt altitude koennte hier irgendwann die berechnete Bodenhoehe einfliessen - (*this)[i][frame-at(i).firstFrame()].setSp(x, y, z); //setZdistanceToCam(z); + (*this)[i][frame - at(i).firstFrame()].setSp(x, y, z); // setZdistanceToCam(z); (*this)[i].setHeight(z, mMainWindow->getControlWidget()->coordAltitude->value()); } else ++notFoundDisp; - //else // Meldung zu haeufig - // debout << "Warning: No disparity information for person " << i+1 << "." << endl; + // else // Meldung zu haeufig + // debout << "Warning: No disparity information for person " << i+1 << "." << endl; } } - //if (notFoundDisp>0) // Meldung zu haeufig - // debout << "Warning: No disparity information found for " << (100.*notFoundDisp)/anz << " percent of points." << endl; + // if (notFoundDisp>0) // Meldung zu haeufig + // debout << "Warning: No disparity information found for " << (100.*notFoundDisp)/anz << " percent of + // points." << endl; return anz; } else @@ -949,116 +982,137 @@ int Tracker::calcPosition(int /*frame*/) { * @param[out] pers person the point was added to; undefined when new trajectory was created * @return true if new trajectory was created; false otherwise */ -bool Tracker::addPoint(TrackPoint &point, int frame, const QSet<int>& onlyVisible, reco::RecognitionMethod method, int *pers) +bool Tracker::addPoint( + TrackPoint & point, + int frame, + const QSet<int> & onlyVisible, + reco::RecognitionMethod method, + int * pers) { - bool found = false; - int i, iNearest = 0.; + bool found = false; + int i, iNearest = 0.; float scaleHead; float dist, minDist = 1000000.; float z = -1; #ifndef STEREO_DISABLED - float x=-1, y=-1; + float x = -1, y = -1; // ACHTUNG: BORDER NICHT BEACHTET bei point.x()... // hier wird farbe nur bei reco bestimmt gegebenfalls auch beim tracken interessant // calculate height with disparity map - if (mMainWindow->getStereoContext() && mMainWindow->getStereoWidget()->stereoUseForHeight->isChecked()) + if(mMainWindow->getStereoContext() && mMainWindow->getStereoWidget()->stereoUseForHeight->isChecked()) { - if (mMainWindow->getStereoContext()->getMedianXYZaround((int) p.x(), (int)p.y(), &x, &y, &z)) // nicht myRound, da pixel 0 von 0..0.99 in double geht + if(mMainWindow->getStereoContext()->getMedianXYZaround( + (int) p.x(), (int) p.y(), &x, &y, &z)) // nicht myRound, da pixel 0 von 0..0.99 in double geht { // statt altitude koennte hier irgendwann die berechnete Bodenhoehe einfliessen - p.setSp(x, y, z); //setZdistanceToCam(z); + p.setSp(x, y, z); // setZdistanceToCam(z); } - //cout << " " << point.x()<< " " << point.y() << " " << x << " " << y << " " << z <<endl; - //if (i == 10) - // debout << i << " " << mMainWindow->getControlWidget()->coordAltitude->value() - z << " " << z << " " << (*this)[i].height() << endl; + // cout << " " << point.x()<< " " << point.y() << " " << x << " " << y << " " << z <<endl; + // if (i == 10) + // debout << i << " " << mMainWindow->getControlWidget()->coordAltitude->value() - z << " " << z << " " << + // (*this)[i].height() << endl; } #endif // skalierungsfaktor fuer kopfgroesse // fuer multicolor marker groesser, da der schwarze punkt weit am rand liegen kann bool multiColorWithDot = false; - if (method == reco::RecognitionMethod::MultiColor && // multicolor marker - mMainWindow->getMultiColorMarkerWidget()->useDot->isChecked() && // nutzung von black dot - !mMainWindow->getMultiColorMarkerWidget()->ignoreWithoutDot->isChecked()) // muetzen ohne black dot werden auch akzeptiert + if(method == reco::RecognitionMethod::MultiColor && // multicolor marker + mMainWindow->getMultiColorMarkerWidget()->useDot->isChecked() && // nutzung von black dot + !mMainWindow->getMultiColorMarkerWidget() + ->ignoreWithoutDot->isChecked()) // muetzen ohne black dot werden auch akzeptiert { multiColorWithDot = true; - scaleHead = 1.3f; + scaleHead = 1.3f; } else scaleHead = 1.0f; - for (i = 0; i < size(); ++i) // !found && // ueber TrackPerson + for(i = 0; i < size(); ++i) // !found && // ueber TrackPerson { - if (((onlyVisible.empty()) || (onlyVisible.contains(i))) && at(i).trackPointExist(frame)) + if(((onlyVisible.empty()) || (onlyVisible.contains(i))) && at(i).trackPointExist(frame)) { dist = at(i).trackPointAt(frame).distanceToPoint(point); - if ((dist < scaleHead*mMainWindow->getHeadSize(nullptr, i, frame)/2.) || - // fuer multifarbmarker mit schwarzem punkt wird nur farbmarker zur Abstandbetrachtung herangezogen - // at(i).trackPointAt(frame).colPoint() existiert nicht an dieser stelle, da bisher nur getrackt wurde!!!! - (multiColorWithDot && point.color().isValid() && (at(i).trackPointAt(frame).distanceToPoint(point.colPoint()) < mMainWindow->getHeadSize(nullptr, i, frame)/2.))) + if((dist < scaleHead * mMainWindow->getHeadSize(nullptr, i, frame) / 2.) || + // fuer multifarbmarker mit schwarzem punkt wird nur farbmarker zur Abstandbetrachtung herangezogen + // at(i).trackPointAt(frame).colPoint() existiert nicht an dieser stelle, da bisher nur getrackt + // wurde!!!! + (multiColorWithDot && point.color().isValid() && + (at(i).trackPointAt(frame).distanceToPoint(point.colPoint()) < + mMainWindow->getHeadSize(nullptr, i, frame) / 2.))) { - if (found) + if(found) { debout << "Warning: more possible trackpoints for point" << std::endl; debout << " " << point << " in frame " << frame << " with low distance:" << std::endl; - debout << " person " << i+1 << " (distance: " << dist << "), " << std::endl; - debout << " person " << iNearest+1 << " (distance: " << minDist << "), " << std::endl; - if (minDist > dist) + debout << " person " << i + 1 << " (distance: " << dist << "), " << std::endl; + debout << " person " << iNearest + 1 << " (distance: " << minDist << "), " << std::endl; + if(minDist > dist) { - minDist = dist; + minDist = dist; iNearest = i; } } else { - minDist = dist; + minDist = dist; iNearest = i; // WAR: break inner loop found = true; } - } + } } } - if (found) // den naechstgelegenen nehmen + if(found) // den naechstgelegenen nehmen { // test, if recognition point or tracked point is better is made in at(i).insertAtFrame - if ((*this)[iNearest].insertAtFrame(frame, point, iNearest, (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked))) // wenn eingefuegt wurde (bessere qualitaet) - //|| !at(i).trackPointAt(frame).color().isValid() moeglich, um auch bei schlechterer qualitaet aber aktuell nicht - // vorliegender farbe die ermittelte farbe einzutragen - kommt nicht vor! + if((*this)[iNearest].insertAtFrame( + frame, + point, + iNearest, + (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == + Qt::Checked))) // wenn eingefuegt wurde (bessere qualitaet) + //|| !at(i).trackPointAt(frame).color().isValid() moeglich, um auch bei schlechterer + // qualitaet aber aktuell nicht + // vorliegender farbe die ermittelte farbe einzutragen - kommt nicht vor! { // Synchronize TrackPerson.markerID with TrackPoint.markerID (*this)[iNearest].syncTrackPersonMarkerID(point.getMarkerID()); // set/add color - if (point.color().isValid()) // not valid for manual, than old color is used + if(point.color().isValid()) // not valid for manual, than old color is used { - //if (at(i).trackPointAt(frame).color().isValid()) man koennte alte farbe abziehen - aber nicht noetig, kommt nicht vor + // if (at(i).trackPointAt(frame).color().isValid()) man koennte alte farbe abziehen - aber nicht noetig, + // kommt nicht vor (*this)[iNearest].addColor(point.color()); } } - if (pers != nullptr) + if(pers != nullptr) *pers = iNearest; (*this)[iNearest].setNewReco(true); - } - if ((onlyVisible.empty()) && !found) + if((onlyVisible.empty()) && !found) { iNearest = size(); - if (point.qual() > 100) //manual add + if(point.qual() > 100) // manual add point.setQual(100); - append(TrackPerson(0, frame, point, point.getMarkerID())); // 0 is person number/markerID; newReco is set to true by default - + append(TrackPerson( + 0, frame, point, point.getMarkerID())); // 0 is person number/markerID; newReco is set to true by default } - if ((z > 0) && ((onlyVisible.empty()) || found)) + if((z > 0) && ((onlyVisible.empty()) || found)) (*this)[iNearest].setHeight(z, mMainWindow->getControlWidget()->coordAltitude->value()); // , frame - if ((!onlyVisible.empty()) && !found) + if((!onlyVisible.empty()) && !found) { - QMessageBox::warning(nullptr, "PeTrack", "Adding a manual TrackPoint is only possible, when \"show only people\" and \"show only people list\" are disabled!\n" - "You would not see the newly created TrackPoint otherwise."); + QMessageBox::warning( + nullptr, + "PeTrack", + "Adding a manual TrackPoint is only possible, when \"show only people\" and \"show only people list\" are " + "disabled!\n" + "You would not see the newly created TrackPoint otherwise."); debout << "Warning: No manual insertion, because not all trajectories are visible!" << std::endl; return false; } @@ -1072,11 +1126,11 @@ void Tracker::addPoints(QList<TrackPoint> &pL, int frame, reco::RecognitionMetho int i; // reset newReco - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson (*this)[i].setNewReco(false); // ueberprufen ob identisch mit einem Punkt in liste - for (i = 0; i < pL.size(); ++i) // ueber PointList + for(i = 0; i < pL.size(); ++i) // ueber PointList { addPoint(pL[i], frame, QSet<int>(), method); } @@ -1085,9 +1139,9 @@ void Tracker::addPoints(QList<TrackPoint> &pL, int frame, reco::RecognitionMetho int Tracker::visible(int frameNum) { int i, anz = 0; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if (at(i).trackPointExist(frameNum)) + if(at(i).trackPointExist(frameNum)) anz++; } return anz; @@ -1096,9 +1150,9 @@ int Tracker::visible(int frameNum) int Tracker::largestFirstFrame() { int max = -1, i; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if (at(i).firstFrame() > max) + if(at(i).firstFrame() > max) max = at(i).firstFrame(); } return max; @@ -1106,29 +1160,29 @@ int Tracker::largestFirstFrame() int Tracker::largestLastFrame() { int max = -1, i; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if (at(i).lastFrame() > max) + if(at(i).lastFrame() > max) max = at(i).lastFrame(); } return max; } int Tracker::smallestFirstFrame() { - int i, min = ((size()>0) ? at(0).firstFrame() : -1); - for (i = 1; i < size(); ++i) + int i, min = ((size() > 0) ? at(0).firstFrame() : -1); + for(i = 1; i < size(); ++i) { - if (at(i).firstFrame() < min) + if(at(i).firstFrame() < min) min = at(i).firstFrame(); } return min; } int Tracker::smallestLastFrame() { - int i, min = ((size()>0) ? at(0).lastFrame() : -1); - for (i = 1; i < size(); ++i) + int i, min = ((size() > 0) ? at(0).lastFrame() : -1); + for(i = 1; i < size(); ++i) { - if (at(i).lastFrame() < min) + if(at(i).lastFrame() < min) min = at(i).lastFrame(); } return min; @@ -1146,21 +1200,30 @@ int Tracker::smallestLastFrame() * @param onlyVisible * @return number of feature points */ -size_t Tracker::calcPrevFeaturePoints(int prevFrame, cv::Rect &rect, int frame, bool reTrack, int reQual, int borderSize, QSet<int> onlyVisible) +size_t Tracker::calcPrevFeaturePoints( + int prevFrame, + cv::Rect &rect, + int frame, + bool reTrack, + int reQual, + int borderSize, + QSet<int> onlyVisible) { int j = -1; mPrevFeaturePoints.clear(); mPrevFeaturePointsIdx.clear(); - if (prevFrame != -1) + if(prevFrame != -1) { - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) { - if(!((onlyVisible.empty()) || (onlyVisible.contains(i)))){ + if(!((onlyVisible.empty()) || (onlyVisible.contains(i)))) + { continue; } - if(!at(i).trackPointExist(prevFrame)){ + if(!at(i).trackPointExist(prevFrame)) + { continue; } @@ -1175,23 +1238,26 @@ size_t Tracker::calcPrevFeaturePoints(int prevFrame, cv::Rect &rect, int frame, if(reTrack) { int dir = (frame - prevFrame); // direction of tracking - forward/backwards - dir /= std::abs(dir); // theoretically possible to omit MAX_STEP_TRACK frames + dir /= std::abs(dir); // theoretically possible to omit MAX_STEP_TRACK frames constexpr int minQualReco = 90; for(int j = 0; - at(i).trackPointExist(frame + j*dir) && at(i).trackPointAt(frame + j*dir).qual() < minQualReco; - ++j){ - if(at(i).trackPointAt(frame + j*dir).qual() < reQual){ + at(i).trackPointExist(frame + j * dir) && at(i).trackPointAt(frame + j * dir).qual() < minQualReco; + ++j) + { + if(at(i).trackPointAt(frame + j * dir).qual() < reQual) + { applyReTrack = false; break; } } } - if( at(i).trackPointExist(frame) && !applyReTrack ){ + if(at(i).trackPointExist(frame) && !applyReTrack) + { continue; } - Vec2F prevPoint = at(i).at(prevFrame-at(i).firstFrame()); + Vec2F prevPoint = at(i).at(prevFrame - at(i).firstFrame()); prevPoint += Vec2F(borderSize, borderSize); cv::Point2f p2f = prevPoint.toPoint2f(); if(rect.contains(p2f)) @@ -1200,7 +1266,7 @@ size_t Tracker::calcPrevFeaturePoints(int prevFrame, cv::Rect &rect, int frame, ++j; mPrevFeaturePointsIdx.push_back(i); - if (j > MAX_COUNT-2) + if(j > MAX_COUNT - 2) { debout << "Warning: reached maximal number of tracking point: " << MAX_COUNT << std::endl; break; // for loop @@ -1235,45 +1301,49 @@ size_t Tracker::calcPrevFeaturePoints(int prevFrame, cv::Rect &rect, int frame, */ int Tracker::insertFeaturePoints(int frame, size_t count, cv::Mat &img, int borderSize, float errorScale) { - int inserted = 0; + int inserted = 0; TrackPoint v; - int qual; - bool found; - Vec2F borderSize2F(-borderSize, -borderSize); - int dist = (borderSize > 9) ? borderSize : 10; // abstand zum bildrand, ab wann warnung ueber trj verlust herausgeschrieben wird - float z=-1; -// int borderColorGray = qGray(mMainWindow->getBorderFilter()->getBorderColR()->getValue(), -// mMainWindow->getBorderFilter()->getBorderColG()->getValue(), -// mMainWindow->getBorderFilter()->getBorderColB()->getValue()); - - for (size_t i = 0; i < count; ++i) - { - if (mStatus[i]) + int qual; + bool found; + Vec2F borderSize2F(-borderSize, -borderSize); + int dist = (borderSize > 9) ? borderSize : + 10; // abstand zum bildrand, ab wann warnung ueber trj verlust herausgeschrieben wird + float z = -1; + // int borderColorGray = qGray(mMainWindow->getBorderFilter()->getBorderColR()->getValue(), + // mMainWindow->getBorderFilter()->getBorderColG()->getValue(), + // mMainWindow->getBorderFilter()->getBorderColB()->getValue()); + + for(size_t i = 0; i < count; ++i) + { + if(mStatus[i]) { - v = Vec2F(mFeaturePoints.at(i).x,mFeaturePoints.at(i).y); // umwandlung nach TrackPoint bei "=" + v = Vec2F(mFeaturePoints.at(i).x, mFeaturePoints.at(i).y); // umwandlung nach TrackPoint bei "=" // ausserhalb der groesse des originalbildes - if ((v.x() >= borderSize && v.y() >= borderSize && v.x() <= img.cols-1-borderSize && v.y() <= img.rows-1-borderSize) || - (mTrackError[i] < errorScale*MAX_TRACK_ERROR)) // nur bei kleinem Fehler darf auch im Randbereich getrackt werden + if((v.x() >= borderSize && v.y() >= borderSize && v.x() <= img.cols - 1 - borderSize && + v.y() <= img.rows - 1 - borderSize) || + (mTrackError[i] < + errorScale * MAX_TRACK_ERROR)) // nur bei kleinem Fehler darf auch im Randbereich getrackt werden { // das Beschraenken auf die Bildgroesse ist reine sicherheitsmassnahme, // oft sind tracking paths auch ausserhalb des bildes noch gut, // aber beim tracken in die andere richtung kann es bei petrack probleme machen - if (v.x() >= 0 && v.y() >= 0 && v.x() <= img.cols-1 && v.y() <= img.rows-1) + if(v.x() >= 0 && v.y() >= 0 && v.x() <= img.cols - 1 && v.y() <= img.rows - 1) { // borderSize abziehen, da Trackerdaten am Rand des Originalbildes 0/0 ist // set position relative to original image size v += borderSize2F; #ifndef STEREO_DISABLED - float x=-1, y=-1; + float x = -1, y = -1; // ACHTUNG: BORDER NICHT BEACHTET bei point.x()... // calculate height with disparity map - if (mMainWindow->getStereoContext() && mMainWindow->getStereoWidget()->stereoUseForHeight->isChecked()) + if(mMainWindow->getStereoContext() && + mMainWindow->getStereoWidget()->stereoUseForHeight->isChecked()) { - mMainWindow->getStereoContext()->getMedianXYZaround((int) v.x(), (int)v.y(), &x, &y, &z); + mMainWindow->getStereoContext()->getMedianXYZaround((int) v.x(), (int) v.y(), &x, &y, &z); { - v.setSp(x, y, z); //v.setZdistanceToCam(z); + v.setSp(x, y, z); // v.setZdistanceToCam(z); } //(*this)[i].setHeight(z, mMainWindow->getControlWidget()->coordAltitude->value(), frame); } @@ -1288,23 +1358,31 @@ int Tracker::insertFeaturePoints(int frame, size_t count, cv::Mat &img, int bord // TODO Wird gerade eben nicht gemacht. Sollten wir??? - // ueberpruefen, ob tracking ziel auf anderem tracking path landet, dann beide trackpaths verschmelzen lassen + // ueberpruefen, ob tracking ziel auf anderem tracking path landet, dann beide trackpaths + // verschmelzen lassen found = false; - if (mMainWindow->getControlWidget()->trackMerge->checkState() == Qt::Checked) // wenn zusammengefuehrt=merge=verschmolzen werden soll + if(mMainWindow->getControlWidget()->trackMerge->checkState() == + Qt::Checked) // wenn zusammengefuehrt=merge=verschmolzen werden soll { found = tryMergeTrajectories(v, i, frame); } // wenn keine verschmelzung erfolgte, versuchen trackpoint einzufuegen - if (!found) + if(!found) { qual = static_cast<int>(errorToQual(mTrackError[i])); - if (qual < 20) + if(qual < 20) qual = 20; v.setQual(qual); // qual um 50, damit nur reco-kopf-ellipsen points nicht herauskegeln // bei insertAtFrame wird qual beruecksichtigt, ob vorheiger besser - if ((*this)[mPrevFeaturePointsIdx[i]].insertAtFrame(frame, v, mPrevFeaturePointsIdx[i], (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked)) && (z > 0)) - (*this)[mPrevFeaturePointsIdx[i]].setHeight(z, mMainWindow->getControlWidget()->coordAltitude->value()); // , frame + if((*this)[mPrevFeaturePointsIdx[i]].insertAtFrame( + frame, + v, + mPrevFeaturePointsIdx[i], + (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked)) && + (z > 0)) + (*this)[mPrevFeaturePointsIdx[i]].setHeight( + z, mMainWindow->getControlWidget()->coordAltitude->value()); // , frame } ++inserted; @@ -1313,8 +1391,9 @@ int Tracker::insertFeaturePoints(int frame, size_t count, cv::Mat &img, int bord } else { - if (v.x() >= dist && v.y() >= dist && v.x() <= img.cols-1-dist && v.y() <= img.rows-1-dist) - debout << "Warning: Lost trajectory inside picture of person " << mPrevFeaturePointsIdx[i]+1 << " at frame " << frame << "!" << std::endl; + if(v.x() >= dist && v.y() >= dist && v.x() <= img.cols - 1 - dist && v.y() <= img.rows - 1 - dist) + debout << "Warning: Lost trajectory inside picture of person " << mPrevFeaturePointsIdx[i] + 1 + << " at frame " << frame << "!" << std::endl; } } @@ -1329,56 +1408,71 @@ int Tracker::insertFeaturePoints(int frame, size_t count, cv::Mat &img, int bord * @param frame frame in which the point v was tracked * @return true if a suitable trajectory to merge with was found */ -bool Tracker::tryMergeTrajectories(const TrackPoint& v, size_t i, int frame) +bool Tracker::tryMergeTrajectories(const TrackPoint &v, size_t i, int frame) { - int deleteIndex; + int deleteIndex; bool found = false; - int j; + int j; // nach trajektorie suchen, mit der eine verschmelzung erfolgen koennte - for (j = 0; !found && j < size(); ++j) // ueber TrackPerson + for(j = 0; !found && j < size(); ++j) // ueber TrackPerson { - if (j != mPrevFeaturePointsIdx[i] && at(j).trackPointExist(frame) && (at(j).trackPointAt(frame).distanceToPoint(v) < mMainWindow->getHeadSize(nullptr, j, frame)/2.)) + if(j != mPrevFeaturePointsIdx[i] && at(j).trackPointExist(frame) && + (at(j).trackPointAt(frame).distanceToPoint(v) < mMainWindow->getHeadSize(nullptr, j, frame) / 2.)) { // um ein fehltracking hin zu einer anderen Trajektorie nicht zum Verschmelzen dieser fuehren zu lassen // (die fehlerbehandlung durch interpolation wird in insertAtFrame durchgefuehrt) - if (!((at(mPrevFeaturePointsIdx[i]).trackPointExist(frame-1) && - (at(mPrevFeaturePointsIdx[i]).trackPointAt(frame-1).distanceToPoint(v) > mMainWindow->getHeadSize(nullptr, mPrevFeaturePointsIdx[i], frame-1)/2.)) || - (at(mPrevFeaturePointsIdx[i]).trackPointExist(frame+1) && - (at(mPrevFeaturePointsIdx[i]).trackPointAt(frame+1).distanceToPoint(v) > mMainWindow->getHeadSize(nullptr, mPrevFeaturePointsIdx[i], frame+1)/2.)))) + if(!((at(mPrevFeaturePointsIdx[i]).trackPointExist(frame - 1) && + (at(mPrevFeaturePointsIdx[i]).trackPointAt(frame - 1).distanceToPoint(v) > + mMainWindow->getHeadSize(nullptr, mPrevFeaturePointsIdx[i], frame - 1) / 2.)) || + (at(mPrevFeaturePointsIdx[i]).trackPointExist(frame + 1) && + (at(mPrevFeaturePointsIdx[i]).trackPointAt(frame + 1).distanceToPoint(v) > + mMainWindow->getHeadSize(nullptr, mPrevFeaturePointsIdx[i], frame + 1) / 2.)))) { - if (at(j).firstFrame() < (*this)[mPrevFeaturePointsIdx[i]].firstFrame() && - at(j).lastFrame() > (*this)[mPrevFeaturePointsIdx[i]].lastFrame()) + if(at(j).firstFrame() < (*this)[mPrevFeaturePointsIdx[i]].firstFrame() && + at(j).lastFrame() > (*this)[mPrevFeaturePointsIdx[i]].lastFrame()) { - for (int k = 0; k < at(mPrevFeaturePointsIdx[i]).size(); ++k) + for(int k = 0; k < at(mPrevFeaturePointsIdx[i]).size(); ++k) { // bei insertAtFrame wird qual beruecksichtigt, ob vorheriger besser - (*this)[j].insertAtFrame(at(mPrevFeaturePointsIdx[i]).firstFrame()+k, at(mPrevFeaturePointsIdx[i]).at(k), j, (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked)); + (*this)[j].insertAtFrame( + at(mPrevFeaturePointsIdx[i]).firstFrame() + k, + at(mPrevFeaturePointsIdx[i]).at(k), + j, + (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked)); } - deleteIndex=mPrevFeaturePointsIdx[i]; + deleteIndex = mPrevFeaturePointsIdx[i]; } - else if (at(j).firstFrame() < (*this)[mPrevFeaturePointsIdx[i]].firstFrame()) + else if(at(j).firstFrame() < (*this)[mPrevFeaturePointsIdx[i]].firstFrame()) { - for (int k = at(j).size()-1; k > -1; --k) + for(int k = at(j).size() - 1; k > -1; --k) { // bei insertAtFrame wird qual beruecksichtigt, ob vorheriger besser - (*this)[mPrevFeaturePointsIdx[i]].insertAtFrame(at(j).firstFrame()+k, at(j).at(k), mPrevFeaturePointsIdx[i], (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked)); + (*this)[mPrevFeaturePointsIdx[i]].insertAtFrame( + at(j).firstFrame() + k, + at(j).at(k), + mPrevFeaturePointsIdx[i], + (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked)); } - deleteIndex=j; + deleteIndex = j; } else { - for (int k = 0; k < at(j).size(); ++k) + for(int k = 0; k < at(j).size(); ++k) { // bei insertAtFrame wird qual beruecksichtigt, ob vorheriger besser - (*this)[mPrevFeaturePointsIdx[i]].insertAtFrame(at(j).firstFrame()+k, at(j).at(k), mPrevFeaturePointsIdx[i], (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked)); + (*this)[mPrevFeaturePointsIdx[i]].insertAtFrame( + at(j).firstFrame() + k, + at(j).at(k), + mPrevFeaturePointsIdx[i], + (mMainWindow->getControlWidget()->trackExtrapolation->checkState() == Qt::Checked)); } - deleteIndex=j; + deleteIndex = j; } removeAt(deleteIndex); // shift index of feature points - for (size_t k = 0; k < mPrevFeaturePointsIdx.size(); ++k) - if (mPrevFeaturePointsIdx[k] > deleteIndex) + for(size_t k = 0; k < mPrevFeaturePointsIdx.size(); ++k) + if(mPrevFeaturePointsIdx[k] > deleteIndex) --mPrevFeaturePointsIdx[k]; found = true; } @@ -1390,8 +1484,8 @@ bool Tracker::tryMergeTrajectories(const TrackPoint& v, size_t i, int frame) // default: int winSize=10, int level=3 // winSize=3 ist genauer, aber kann auch leichter abgelenkt werden; winSize=30 ist robuster aber ungenauer -// level kann groesser gewaehlt werden, wenn winSize klein, macht aber keinen grossen unterschied; (0) waere ohne pyramide -// war , int winSize=10 +// level kann groesser gewaehlt werden, wenn winSize klein, macht aber keinen grossen unterschied; (0) waere ohne +// pyramide war , int winSize=10 /** * @brief Tracks points from the last frame in this (current) frame * @@ -1406,55 +1500,71 @@ bool Tracker::tryMergeTrajectories(const TrackPoint& v, size_t i, int frame) * @param errorScaleExponent errorScale is 1.5^errorScaleExponent * @return Number of tracked points */ -int Tracker::track(cv::Mat &img, cv::Rect &rect, int frame, bool reTrack, int reQual, int borderSize, reco::RecognitionMethod recoMethod, int level, QSet<int> onlyVisible, int errorScaleExponent) +int Tracker::track( + cv::Mat & img, + cv::Rect & rect, + int frame, + bool reTrack, + int reQual, + int borderSize, + reco::RecognitionMethod recoMethod, + int level, + QSet<int> onlyVisible, + int errorScaleExponent) { QList<int> trjToDel; - float errorScale = pow(1.5,errorScaleExponent); // 0 waere neutral + float errorScale = pow(1.5, errorScaleExponent); // 0 waere neutral - if (mGrey.empty()) + if(mGrey.empty()) { debout << "ERROR: you have to initialize tracking before using tracker!" << std::endl; return -1; } - if (img.empty()) + if(img.empty()) { debout << "ERROR: no NULL image allowed for tracking!" << std::endl; return -1; } - if ((mPrevFrame != -1) && (abs(frame - mPrevFrame) > MAX_STEP_TRACK)) + if((mPrevFrame != -1) && (abs(frame - mPrevFrame) > MAX_STEP_TRACK)) reset(); - if (abs(frame - mPrevFrame) == 0) + if(abs(frame - mPrevFrame) == 0) { debout << "ERROR: Frame has not changed. There is nothing to track!" << std::endl; return -1; } - if (img.channels() == 3) + if(img.channels() == 3) { - cv::cvtColor(img,mGrey,cv::COLOR_BGR2GRAY); + cv::cvtColor(img, mGrey, cv::COLOR_BGR2GRAY); } - else if (img.channels() == 1){ + else if(img.channels() == 1) + { img.copyTo(mGrey); - }else{ + } + else + { debout << "Error: Wrong number of channels: " << img.channels() << std::endl; return -1; } - size_t numOfPeopleToTrack = calcPrevFeaturePoints(mPrevFrame, rect, frame, reTrack, reQual, borderSize, onlyVisible); + size_t numOfPeopleToTrack = + calcPrevFeaturePoints(mPrevFrame, rect, frame, reTrack, reQual, borderSize, onlyVisible); - if (numOfPeopleToTrack > 0) + if(numOfPeopleToTrack > 0) { preCalculateImagePyramids(level); - if (mPrevFrame != -1) + if(mPrevFrame != -1) { - if (abs(frame - mPrevFrame) > MAX_STEP_TRACK) - debout << "Warning: no tracking because of too many skipped frames (" << mPrevFrame << " to " << frame << ")!" << std::endl; - else if (abs(frame - mPrevFrame) > 1) - debout << "Warning: linear interpolation of skipped frames which are not already tracked (" << mPrevFrame << " to " << frame << ")." << std::endl; // will be done in insertFeaturePoints + if(abs(frame - mPrevFrame) > MAX_STEP_TRACK) + debout << "Warning: no tracking because of too many skipped frames (" << mPrevFrame << " to " << frame + << ")!" << std::endl; + else if(abs(frame - mPrevFrame) > 1) + debout << "Warning: linear interpolation of skipped frames which are not already tracked (" + << mPrevFrame << " to " << frame << ")." << std::endl; // will be done in insertFeaturePoints } trackFeaturePointsLK(level, mMainWindow->getControlWidget()->getAdaptiveLevel()); @@ -1463,15 +1573,21 @@ int Tracker::track(cv::Mat &img, cv::Rect &rect, int frame, bool reTrack, int re refineViaColorPointLK(level, errorScale); BackgroundFilter *bgFilter = mMainWindow->getBackgroundFilter(); - // testen, ob Punkt im Vordergrund liegt, ansonsten, wenn nicht gerade zuvor detektiert, ganze trajektorie loeschen (maximnale laenge ausserhalb ist somit 2 frames) - if (bgFilter && bgFilter->getEnabled() && (mPrevFrame != -1)) // nur fuer den fall von bgSubtraction durchfuehren + // testen, ob Punkt im Vordergrund liegt, ansonsten, wenn nicht gerade zuvor detektiert, ganze trajektorie + // loeschen (maximnale laenge ausserhalb ist somit 2 frames) + if(bgFilter && bgFilter->getEnabled() && (mPrevFrame != -1)) // nur fuer den fall von bgSubtraction durchfuehren { useBackgroundFilter(trjToDel, bgFilter); } // (bei schlechten, aber noch ertraeglichem fehler in der naehe dunkelsten punkt suchen) - // dieser ansatz kann dazu fuehren, dass bei starken helligkeitsunterschieden auf pappe zum schatten gewandert wird!!! - if (!mMainWindow->getStereoWidget()->stereoUseForReco->isChecked() && ((recoMethod == reco::RecognitionMethod::Casern)|| (recoMethod == reco::RecognitionMethod::Hermes))) // nicht benutzen, wenn ueber disparity der kopf gesucht wird und somit kein marker vorhanden oder zumindest nicht am punkt lewigen muss + // dieser ansatz kann dazu fuehren, dass bei starken helligkeitsunterschieden auf pappe zum schatten gewandert + // wird!!! + if(!mMainWindow->getStereoWidget()->stereoUseForReco->isChecked() && + ((recoMethod == reco::RecognitionMethod::Casern) || + (recoMethod == + reco::RecognitionMethod::Hermes))) // nicht benutzen, wenn ueber disparity der kopf gesucht wird und somit + // kein marker vorhanden oder zumindest nicht am punkt lewigen muss { refineViaNearDarkPoint(); } @@ -1486,7 +1602,7 @@ int Tracker::track(cv::Mat &img, cv::Rect &rect, int frame, bool reTrack, int re // delete vorher ausgewaehlte trj // ACHTUNG: einzige stelle in tracker, wo eine trj geloescht wird // trackNumberAll, trackShowOnlyNr werden nicht angepasst, dies wird aber am ende von petrack::updateimage gemacht - for (int i = 0; i < trjToDel.size(); ++i) // ueber TrackPerson + for(int i = 0; i < trjToDel.size(); ++i) // ueber TrackPerson { removeAt(trjToDel[i]); } @@ -1510,15 +1626,17 @@ int Tracker::track(cv::Mat &img, cv::Rect &rect, int frame, bool reTrack, int re void Tracker::preCalculateImagePyramids(int level) { int maxWinSize = 3; - for(size_t i = 0; i < mPrevFeaturePointsIdx.size(); ++i){ + for(size_t i = 0; i < mPrevFeaturePointsIdx.size(); ++i) + { int winSize = mMainWindow->winSize(nullptr, mPrevFeaturePointsIdx[i], mPrevFrame, 0); - if(winSize > maxWinSize){ + if(winSize > maxWinSize) + { maxWinSize = winSize; } } cv::buildOpticalFlowPyramid(mPrevGrey, mPrevPyr, cv::Size(maxWinSize, maxWinSize), level); - cv::buildOpticalFlowPyramid(mGrey, mCurrentPyr, cv::Size(maxWinSize,maxWinSize), level); + cv::buildOpticalFlowPyramid(mGrey, mCurrentPyr, cv::Size(maxWinSize, maxWinSize), level); } @@ -1598,35 +1716,51 @@ void Tracker::trackFeaturePointsLK(int level, bool adaptive) */ void Tracker::refineViaColorPointLK(int level, float errorScale) { - int winSize; - bool useColor = mMainWindow->getMultiColorMarkerWidget()->useColor->isChecked(); + int winSize; + bool useColor = mMainWindow->getMultiColorMarkerWidget()->useColor->isChecked(); std::vector<cv::Point2f> prevColorFeaturePoint, colorFeaturePoint; - std::vector<uchar> colorStatus; - std::vector<float> colorTrackError; + std::vector<uchar> colorStatus; + std::vector<float> colorTrackError; - for (size_t i = 0; i < mPrevFeaturePointsIdx.size(); ++i) + for(size_t i = 0; i < mPrevFeaturePointsIdx.size(); ++i) { - // wenn fehler zu gross, dann Farbmarkerelement nehmen // fuer multicolor marker / farbiger hut mit schwarzem punkt - if ( useColor && mTrackError[i]>errorScale*150.F && at(mPrevFeaturePointsIdx[i]).at(mPrevFrame-at(mPrevFeaturePointsIdx[i]).firstFrame()).color().isValid()) + // wenn fehler zu gross, dann Farbmarkerelement nehmen // fuer multicolor marker / farbiger hut mit schwarzem + // punkt + if(useColor && mTrackError[i] > errorScale * 150.F && + at(mPrevFeaturePointsIdx[i]).at(mPrevFrame - at(mPrevFeaturePointsIdx[i]).firstFrame()).color().isValid()) { - float prevPointX = static_cast<float>(at(mPrevFeaturePointsIdx[i]).at(mPrevFrame-at(mPrevFeaturePointsIdx[i]).firstFrame()).colPoint().x()); - float prevPointY = static_cast<float>(at(mPrevFeaturePointsIdx[i]).at(mPrevFrame-at(mPrevFeaturePointsIdx[i]).firstFrame()).colPoint().y()); + float prevPointX = static_cast<float>( + at(mPrevFeaturePointsIdx[i]).at(mPrevFrame - at(mPrevFeaturePointsIdx[i]).firstFrame()).colPoint().x()); + float prevPointY = static_cast<float>( + at(mPrevFeaturePointsIdx[i]).at(mPrevFrame - at(mPrevFeaturePointsIdx[i]).firstFrame()).colPoint().y()); prevColorFeaturePoint.push_back(cv::Point2f(prevPointX, prevPointY)); winSize = mMainWindow->winSize(nullptr, mPrevFeaturePointsIdx[i], mPrevFrame, level); - cv::calcOpticalFlowPyrLK(mPrevPyr,mCurrentPyr,prevColorFeaturePoint,colorFeaturePoint,colorStatus,colorTrackError,cv::Size(winSize,winSize),level,mTermCriteria); + cv::calcOpticalFlowPyrLK( + mPrevPyr, + mCurrentPyr, + prevColorFeaturePoint, + colorFeaturePoint, + colorStatus, + colorTrackError, + cv::Size(winSize, winSize), + level, + mTermCriteria); - colorTrackError[i] = colorTrackError[i]*10.F/winSize; + colorTrackError[i] = colorTrackError[i] * 10.F / winSize; - if ((colorStatus[i] == 1) && (colorTrackError[i] < errorScale*50.F)) + if((colorStatus[i] == 1) && (colorTrackError[i] < errorScale * 50.F)) { - debout << "Warning: tracking color marker instead of structural marker of person "<< mPrevFeaturePointsIdx[i]+1 <<" at " << mFeaturePoints[i].x << " x " << mFeaturePoints[i].y - << " / error: " << mTrackError[i] << " / color error: " << colorTrackError[i] << std::endl; + debout << "Warning: tracking color marker instead of structural marker of person " + << mPrevFeaturePointsIdx[i] + 1 << " at " << mFeaturePoints[i].x << " x " << mFeaturePoints[i].y + << " / error: " << mTrackError[i] << " / color error: " << colorTrackError[i] << std::endl; - mFeaturePoints[i] = cv::Point2f(mPrevFeaturePoints[i].x+(colorFeaturePoint[i].x-prevColorFeaturePoint[i].x), - mPrevFeaturePoints[i].x+(colorFeaturePoint[i].x-prevColorFeaturePoint[i].x)); - debout << " resulting point: " << mFeaturePoints[i].x << " x " << mFeaturePoints[i].y << std::endl; + mFeaturePoints[i] = cv::Point2f( + mPrevFeaturePoints[i].x + (colorFeaturePoint[i].x - prevColorFeaturePoint[i].x), + mPrevFeaturePoints[i].x + (colorFeaturePoint[i].x - prevColorFeaturePoint[i].x)); + debout << " resulting point: " << mFeaturePoints[i].x << " x " << mFeaturePoints[i].y + << std::endl; mTrackError[i] = colorTrackError[i]; } } @@ -1644,34 +1778,39 @@ void Tracker::refineViaColorPointLK(int level, float errorScale) * @param trjToDel[out] trajectories marked for deletion * @param bgFilter[in] backgroundFilter, which determines if a point is in the bg */ -void Tracker::useBackgroundFilter(QList<int>& trjToDel, BackgroundFilter *bgFilter){ - int x, y; - static int margin=10; // rand am bild, ab dem trajectorie in den hintergrund laufen darf - int bS = mMainWindow->getImageBorderSize(); - QRectF rect = mMainWindow->getRecoRoiItem()->rect(); - for (size_t i = 0; i < mPrevFeaturePointsIdx.size(); ++i) +void Tracker::useBackgroundFilter(QList<int> &trjToDel, BackgroundFilter *bgFilter) +{ + int x, y; + static int margin = 10; // rand am bild, ab dem trajectorie in den hintergrund laufen darf + int bS = mMainWindow->getImageBorderSize(); + QRectF rect = mMainWindow->getRecoRoiItem()->rect(); + for(size_t i = 0; i < mPrevFeaturePointsIdx.size(); ++i) { - x = myRound(mFeaturePoints[i].x-.5); - y = myRound(mFeaturePoints[i].y-.5); - - // Rahmen, in dem nicht vordergrund pflicht, insbesondere am rechten rand!!!! es wird gruenes von hand angelegtes bounding rect roi genutzt - if ((mStatus[i] == 1) && - x >= MAX(margin, rect.x()) && x <= MIN(mGrey.cols-1-2*bS-margin-50, rect.x()+rect.width()) && - y >= MAX(margin, rect.y()) && y <= MIN(mGrey.rows-1-2*bS-margin, rect.y()+rect.height())) + x = myRound(mFeaturePoints[i].x - .5); + y = myRound(mFeaturePoints[i].y - .5); + + // Rahmen, in dem nicht vordergrund pflicht, insbesondere am rechten rand!!!! es wird gruenes von hand + // angelegtes bounding rect roi genutzt + if((mStatus[i] == 1) && x >= MAX(margin, rect.x()) && + x <= MIN(mGrey.cols - 1 - 2 * bS - margin - 50, rect.x() + rect.width()) && y >= MAX(margin, rect.y()) && + y <= MIN(mGrey.rows - 1 - 2 * bS - margin, rect.y() + rect.height())) { - if (!bgFilter->isForeground(x, y) && at(mPrevFeaturePointsIdx[i]).trackPointAt(mPrevFrame).qual() < 100) + if(!bgFilter->isForeground(x, y) && at(mPrevFeaturePointsIdx[i]).trackPointAt(mPrevFrame).qual() < 100) { - if ((mMainWindow->getControlWidget()->filterBgDeleteTrj->checkState() == Qt::Checked) && - (at(mPrevFeaturePointsIdx[i]).nrInBg() >= mMainWindow->getControlWidget()->filterBgDeleteNumber->value())) + if((mMainWindow->getControlWidget()->filterBgDeleteTrj->checkState() == Qt::Checked) && + (at(mPrevFeaturePointsIdx[i]).nrInBg() >= + mMainWindow->getControlWidget()->filterBgDeleteNumber->value())) { // nur zum loeschen vormerken und am ende der fkt loeschen, da sonst Seiteneffekte komplex - trjToDel+= mPrevFeaturePointsIdx[i]; - debout << "Warning: Delete trajectory " << mPrevFeaturePointsIdx[i]+1 << " inside region of interest, because it laid outside foreground for " << - mMainWindow->getControlWidget()->filterBgDeleteNumber->value() << " successive frames!" << std::endl; + trjToDel += mPrevFeaturePointsIdx[i]; + debout << "Warning: Delete trajectory " << mPrevFeaturePointsIdx[i] + 1 + << " inside region of interest, because it laid outside foreground for " + << mMainWindow->getControlWidget()->filterBgDeleteNumber->value() << " successive frames!" + << std::endl; } else { - (*this)[mPrevFeaturePointsIdx[i]].setNrInBg(at(mPrevFeaturePointsIdx[i]).nrInBg()+1); + (*this)[mPrevFeaturePointsIdx[i]].setNrInBg(at(mPrevFeaturePointsIdx[i]).nrInBg() + 1); } } else // zaehler zuruecksetzen, der anzahl von getrackten Punkten im hintergrund zaehlt @@ -1694,46 +1833,48 @@ void Tracker::useBackgroundFilter(QList<int>& trjToDel, BackgroundFilter *bgFilt void Tracker::refineViaNearDarkPoint() { int x, y; - for (size_t i = 0; i < mPrevFeaturePointsIdx.size(); ++i) + for(size_t i = 0; i < mPrevFeaturePointsIdx.size(); ++i) { - x = myRound(mFeaturePoints[i].x-.5); - y = myRound(mFeaturePoints[i].y-.5); + x = myRound(mFeaturePoints[i].x - .5); + y = myRound(mFeaturePoints[i].y - .5); // der reine fehler ist leider kein alleinig gutes mass, // da in kontrastarmen regionen der angegebene fehler gering, aber das resultat haeufiger fehlerhaft ist // es waere daher schoen, wenn der fehler in abhaengigkeit von kontrast in umgebung skaliert wuerde // zb (max 0..255): normal 10..150 -> *1; klein 15..50 -> *3; gross 0..255 -> *.5 - if ((mTrackError[i] > MAX_TRACK_ERROR) && (mStatus[i] == 1) && - x >= 0 && x < mGrey.cols && y >= 0 && y < mGrey.rows) + if((mTrackError[i] > MAX_TRACK_ERROR) && (mStatus[i] == 1) && x >= 0 && x < mGrey.cols && y >= 0 && + y < mGrey.rows) { - int regionSize = myRound(mMainWindow->getHeadSize(nullptr, mPrevFeaturePointsIdx[i], mPrevFrame)/10.); ///< size of searched region around point: -regionSize to regionSize - int xMin, xMax, yMin, yMax, xMin2, xMax2, yMin2, yMax2, darkest; + int regionSize = myRound( + mMainWindow->getHeadSize(nullptr, mPrevFeaturePointsIdx[i], mPrevFrame) / + 10.); ///< size of searched region around point: -regionSize to regionSize + int xMin, xMax, yMin, yMax, xMin2, xMax2, yMin2, yMax2, darkest; bool markerInsideWhite = true; - int xDark = x, yDark = y; + int xDark = x, yDark = y; // trotz grau (img)->nChannels=3 - xMin = ((0 > (x-regionSize)) ? 0 : (x-regionSize)); - yMin = ((0 > (y-regionSize)) ? 0 : (y-regionSize)); - xMax = ((mGrey.cols < (x+regionSize+1)) ? mGrey.cols : (x+regionSize+1)); - yMax = ((mGrey.rows < (y+regionSize+1)) ? mGrey.rows : (y+regionSize+1)); + xMin = ((0 > (x - regionSize)) ? 0 : (x - regionSize)); + yMin = ((0 > (y - regionSize)) ? 0 : (y - regionSize)); + xMax = ((mGrey.cols < (x + regionSize + 1)) ? mGrey.cols : (x + regionSize + 1)); + yMax = ((mGrey.rows < (y + regionSize + 1)) ? mGrey.rows : (y + regionSize + 1)); darkest = 255; - for (int k = yMin; k < yMax; ++k) + for(int k = yMin; k < yMax; ++k) { - for (int j = xMin; j < xMax; ++j) + for(int j = xMin; j < xMax; ++j) { - if (getValue(mGrey, j, k).value() < darkest) + if(getValue(mGrey, j, k).value() < darkest) { darkest = getValue(mGrey, j, k).value(); - xDark = j; - yDark = k; + xDark = j; + yDark = k; } } } - xMin2 = ((0 > (xDark-regionSize)) ? 0 : (xDark-regionSize)); - yMin2 = ((0 > (yDark-regionSize)) ? 0 : (yDark-regionSize)); - xMax2 = ((mGrey.cols < (xDark+regionSize+1)) ? mGrey.cols : (xDark+regionSize+1)); - yMax2 = ((mGrey.rows < (yDark+regionSize+1)) ? mGrey.rows : (yDark+regionSize+1)); + xMin2 = ((0 > (xDark - regionSize)) ? 0 : (xDark - regionSize)); + yMin2 = ((0 > (yDark - regionSize)) ? 0 : (yDark - regionSize)); + xMax2 = ((mGrey.cols < (xDark + regionSize + 1)) ? mGrey.cols : (xDark + regionSize + 1)); + yMax2 = ((mGrey.rows < (yDark + regionSize + 1)) ? mGrey.rows : (yDark + regionSize + 1)); // suchbereich: // ### @@ -1741,38 +1882,43 @@ void Tracker::refineViaNearDarkPoint() // # # // # # // ### - for (int k = yMin2+1; k < yMax2-1; ++k) + for(int k = yMin2 + 1; k < yMax2 - 1; ++k) { - if ((getValue(mGrey, xMin2, k).value() <= darkest) || (getValue(mGrey, xMax2-1, k).value() <= darkest)) + if((getValue(mGrey, xMin2, k).value() <= darkest) || (getValue(mGrey, xMax2 - 1, k).value() <= darkest)) { markerInsideWhite = false; break; } } - if (markerInsideWhite) - for (int j = xMin2+1; j < xMax2-1; ++j) + if(markerInsideWhite) + for(int j = xMin2 + 1; j < xMax2 - 1; ++j) { - if ((getValue(mGrey, j, yMin2).value() <= darkest) || (getValue(mGrey, j, yMax2-1).value() <= darkest)) + if((getValue(mGrey, j, yMin2).value() <= darkest) || + (getValue(mGrey, j, yMax2 - 1).value() <= darkest)) { markerInsideWhite = false; break; } } - if (markerInsideWhite) + if(markerInsideWhite) { mFeaturePoints[i].x = xDark; mFeaturePoints[i].y = yDark; - debout << "Move trackpoint to darker pixel for" << i+1 << "!" << std::endl; + debout << "Move trackpoint to darker pixel for" << i + 1 << "!" << std::endl; } // interpolation wg nachbargrauwerten: x = myRound(mFeaturePoints[i].x); y = myRound(mFeaturePoints[i].y); - if ((x>0) && (x<(mGrey.cols-1)) && (y>0) && (y<(mGrey.rows-1)) && (darkest<255)) + if((x > 0) && (x < (mGrey.cols - 1)) && (y > 0) && (y < (mGrey.rows - 1)) && (darkest < 255)) { - mFeaturePoints[i].x += .5*((double)(getValue(mGrey, x+1, y).value()-getValue(mGrey, x-1, y).value()))/((double)(255-darkest)); - mFeaturePoints[i].y += .5*((double)(getValue(mGrey, x, y+1).value()-getValue(mGrey, x, y-1).value()))/((double)(255-darkest)); + mFeaturePoints[i].x += + .5 * ((double) (getValue(mGrey, x + 1, y).value() - getValue(mGrey, x - 1, y).value())) / + ((double) (255 - darkest)); + mFeaturePoints[i].y += + .5 * ((double) (getValue(mGrey, x, y + 1).value() - getValue(mGrey, x, y - 1).value())) / + ((double) (255 - darkest)); } mFeaturePoints[i].x += .5F; @@ -1784,7 +1930,7 @@ void Tracker::refineViaNearDarkPoint() void Tracker::recalcHeight(float altitude) { // in TrackPerson: resetHeight(); - for (int i = 0; i < size(); ++i) // ueber TrackPerson + for(int i = 0; i < size(); ++i) // ueber TrackPerson { (*this)[i].recalcHeight(altitude); } @@ -1807,158 +1953,176 @@ void Tracker::recalcHeight(float altitude) * @param testInside[in] true if warning for start and endpoint in reco ROI is wished * @param testLength[in] true if warning for very short trajectories is wished */ -void Tracker::checkPlausibility(QList<int> &pers, QList<int> &frame, - bool testEqual, bool testVelocity, bool testInside, bool testLength) - { - QProgressDialog progress("Check Plausibility",nullptr,0,400,mMainWindow->window()); +void Tracker::checkPlausibility( + QList<int> &pers, + QList<int> &frame, + bool testEqual, + bool testVelocity, + bool testInside, + bool testLength) +{ + QProgressDialog progress("Check Plausibility", nullptr, 0, 400, mMainWindow->window()); progress.setWindowTitle("Check plausibility"); progress.setWindowModality(Qt::WindowModal); progress.setVisible(true); progress.setValue(0); progress.setLabelText("Check Plausibility..."); - static int margin=30; // rand am bild, ab dem trajectorie verloren sein darf - int i, j; - double x, y; - int bS = mMainWindow->getImageBorderSize(); - QRectF rect = mMainWindow->getRecoRoiItem()->rect(); - int lastFrame = mMainWindow->getAnimation()->getNumFrames()-1; + static int margin = 30; // rand am bild, ab dem trajectorie verloren sein darf + int i, j; + double x, y; + int bS = mMainWindow->getImageBorderSize(); + QRectF rect = mMainWindow->getRecoRoiItem()->rect(); + int lastFrame = mMainWindow->getAnimation()->getNumFrames() - 1; #ifdef TIME_MEASUREMENT double time1, tstart; #endif // test, if the trajectory is very short (less than 10 Trackpoints) - if (testLength) + if(testLength) { progress.setValue(0); progress.setLabelText("Check trajectories lengths..."); qApp->processEvents(); #ifdef TIME_MEASUREMENT - time1 = 0.0; + time1 = 0.0; tstart = clock(); #endif - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { - progress.setValue(i*100./size()); + progress.setValue(i * 100. / size()); qApp->processEvents(); - if (at(i).size() < 10) + if(at(i).size() < 10) { - debout << "Warning: Trajectory of person " << i+1 << " has less than 10 trackpoints!" << std::endl; - pers.append(i+1); + debout << "Warning: Trajectory of person " << i + 1 << " has less than 10 trackpoints!" << std::endl; + pers.append(i + 1); frame.append((*this)[i].firstFrame()); } } #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(testLength) = " << time1 << " sec." << endl; #endif } // check, if trajectory starts and ends outside the recognition area - if (testInside) + if(testInside) { progress.setValue(100); progress.setLabelText("Check if trajectories are inside image..."); qApp->processEvents(); #ifdef TIME_MEASUREMENT - time1 = 0.0; + time1 = 0.0; tstart = clock(); #endif - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { qApp->processEvents(); - progress.setValue(100+i*100./size()); + progress.setValue(100 + i * 100. / size()); x = (*this)[i].first().x(); y = (*this)[i].first().y(); // mGrey hat gleiche groesse wie zuletzt getracktes bild - if ((*this)[i].firstFrame() != 0 && x >= MAX(margin, rect.x()) && y >= MAX(margin, rect.y()) && x <= MIN(mGrey.cols-1-2*bS-margin, rect.x()+rect.width()) && y <= MIN(mGrey.rows-1-2*bS-margin, rect.y()+rect.height())) + if((*this)[i].firstFrame() != 0 && x >= MAX(margin, rect.x()) && y >= MAX(margin, rect.y()) && + x <= MIN(mGrey.cols - 1 - 2 * bS - margin, rect.x() + rect.width()) && + y <= MIN(mGrey.rows - 1 - 2 * bS - margin, rect.y() + rect.height())) { - debout << "Warning: Start of trajectory inside picture and recognition area of person " << i+1 << "!" << std::endl; - pers.append(i+1); + debout << "Warning: Start of trajectory inside picture and recognition area of person " << i + 1 << "!" + << std::endl; + pers.append(i + 1); frame.append((*this)[i].firstFrame()); } x = (*this)[i].last().x(); y = (*this)[i].last().y(); // mGrey hat gleiche groesse wie zuletzt getracktes bild - if ((*this)[i].lastFrame() != lastFrame && x >= MAX(margin, rect.x()) && y >= MAX(margin, rect.y()) && x <= MIN(mGrey.cols-1-2*bS-margin, rect.x()+rect.width()) && y <= MIN(mGrey.rows-1-2*bS-margin, rect.y()+rect.height())) + if((*this)[i].lastFrame() != lastFrame && x >= MAX(margin, rect.x()) && y >= MAX(margin, rect.y()) && + x <= MIN(mGrey.cols - 1 - 2 * bS - margin, rect.x() + rect.width()) && + y <= MIN(mGrey.rows - 1 - 2 * bS - margin, rect.y() + rect.height())) { - debout << "Warning: End of trajectory inside picture and recognition area of person " << i+1 << "!" << std::endl; - pers.append(i+1); + debout << "Warning: End of trajectory inside picture and recognition area of person " << i + 1 << "!" + << std::endl; + pers.append(i + 1); frame.append((*this)[i].lastFrame()); } } #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(testInside) = " << time1 << " sec." << endl; #endif } // testen, ob grosse Geschwindigkeitsaenderungen // statt distanz koennte man auch noch vektoren vergleichen, was genauere analyse waer!!!! - if (testVelocity) + if(testVelocity) { qApp->processEvents(); progress.setValue(200); progress.setLabelText("Check velocity..."); #ifdef TIME_MEASUREMENT - time1 = 0.0; + time1 = 0.0; tstart = clock(); #endif double d01, d12, d23; - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { qApp->processEvents(); - progress.setValue(200+i*100./size()); - for (j = 1; j < at(i).size()-2; ++j) // ueber TrackPoint (ohne ersten und letzten beiden) + progress.setValue(200 + i * 100. / size()); + for(j = 1; j < at(i).size() - 2; ++j) // ueber TrackPoint (ohne ersten und letzten beiden) { - d01 = at(i).at(j ).distanceToPoint(at(i).at(j-1)); - d12 = at(i).at(j+1).distanceToPoint(at(i).at(j )); - d23 = at(i).at(j+2).distanceToPoint(at(i).at(j+1)); - if (((1.8*(d01+d23)/2.) < d12) && ((d12 > 6.) || ((d01+d23)/2. > 3.))) // geschwindigkeit 1,8-fach && mindestpixelbewegung im schnitt von 3 + d01 = at(i).at(j).distanceToPoint(at(i).at(j - 1)); + d12 = at(i).at(j + 1).distanceToPoint(at(i).at(j)); + d23 = at(i).at(j + 2).distanceToPoint(at(i).at(j + 1)); + if(((1.8 * (d01 + d23) / 2.) < d12) && + ((d12 > 6.) || + ((d01 + d23) / 2. > 3.))) // geschwindigkeit 1,8-fach && mindestpixelbewegung im schnitt von 3 { - debout << "Warning: Fast variation of velocity of person " << i+1 << " between frame " << j+at(i).firstFrame() << " and " << j+1+at(i).firstFrame() << "!" << std::endl; - pers.append(i+1); - frame.append(j+at(i).firstFrame()); + debout << "Warning: Fast variation of velocity of person " << i + 1 << " between frame " + << j + at(i).firstFrame() << " and " << j + 1 + at(i).firstFrame() << "!" << std::endl; + pers.append(i + 1); + frame.append(j + at(i).firstFrame()); } } } #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(testVelocity) = " << time1 << " sec." << endl; #endif } - // testen, ob zwei trackpoint sehr nah beieinanderliegen (es gibt trajektorien, die uebereinander liegen, wenn nicht genmergt wird) - if (testEqual) + // testen, ob zwei trackpoint sehr nah beieinanderliegen (es gibt trajektorien, die uebereinander liegen, wenn nicht + // genmergt wird) + if(testEqual) { progress.setValue(300); progress.setLabelText("Check if trajectories are equal..."); qApp->processEvents(); #ifdef TIME_MEASUREMENT - time1 = 0.0; + time1 = 0.0; tstart = clock(); #endif int lLF = largestLastFrame(); int f; - for (f = smallestFirstFrame(); f <= lLF; ++f) + for(f = smallestFirstFrame(); f <= lLF; ++f) { - progress.setValue(300+f*100./lLF); + progress.setValue(300 + f * 100. / lLF); qApp->processEvents(); - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - // if (!pers.contains(i+1)) man koennte nur einmal eine Person aufnehmen, da aufeinanderfolgende frames oft betroffen - for (j = i+1; j < size(); ++j) + // if (!pers.contains(i+1)) man koennte nur einmal eine Person aufnehmen, da aufeinanderfolgende frames + // oft betroffen + for(j = i + 1; j < size(); ++j) { - if (at(i).trackPointExist(f) && at(j).trackPointExist(f)) + if(at(i).trackPointExist(f) && at(j).trackPointExist(f)) { - if (at(i).trackPointAt(f).distanceToPoint(at(j).trackPointAt(f)) < mMainWindow->getHeadSize(nullptr, i, f)/2.) + if(at(i).trackPointAt(f).distanceToPoint(at(j).trackPointAt(f)) < + mMainWindow->getHeadSize(nullptr, i, f) / 2.) { - debout << "Warning: Person " << i+1 << " and " << j+1 << " are very close to each other at frame " << f << "!" << std::endl; - pers.append(i+1); + debout << "Warning: Person " << i + 1 << " and " << j + 1 + << " are very close to each other at frame " << f << "!" << std::endl; + pers.append(i + 1); frame.append(f); } } @@ -1967,7 +2131,7 @@ void Tracker::checkPlausibility(QList<int> &pers, QList<int> &frame, } #ifdef TIME_MEASUREMENT time1 += clock() - tstart; - time1 = time1/CLOCKS_PER_SEC; + time1 = time1 / CLOCKS_PER_SEC; cout << " time(testEqual) = " << time1 << " sec." << endl; #endif } @@ -1977,9 +2141,9 @@ void Tracker::checkPlausibility(QList<int> &pers, QList<int> &frame, void Tracker::optimizeColor() { int i; - for (i = 0; i < size(); ++i) // ueber TrackPerson + for(i = 0; i < size(); ++i) // ueber TrackPerson { - if ((*this)[i].color().isValid()) + if((*this)[i].color().isValid()) (*this)[i].optimizeColor(); } } @@ -1987,7 +2151,7 @@ void Tracker::optimizeColor() // reset the height of all persons, but not the pos of the trackpoints void Tracker::resetHeight() { - for (int i = 0; i < size(); ++i) // ueber TrackPerson + for(int i = 0; i < size(); ++i) // ueber TrackPerson { (*this)[i].resetHeight(); } @@ -1996,9 +2160,9 @@ void Tracker::resetHeight() // reset the pos of the tzrackpoints, but not the heights void Tracker::resetPos() { - for (int i = 0; i < size(); ++i) // ueber TrackPerson + for(int i = 0; i < size(); ++i) // ueber TrackPerson { - for (int j = 0; j < (*this)[i].size(); ++j) // ueber TrackPoints + for(int j = 0; j < (*this)[i].size(); ++j) // ueber TrackPoints { (*this)[i][j].setSp(-1., -1., -1.); } @@ -2013,71 +2177,81 @@ void Tracker::resetPos() bool Tracker::printHeightDistribution() { debout << std::endl; - QMap<double, int> dict; + QMap<double, int> dict; QMap<double, int>::const_iterator j; - int i, anz = 0; - int heightStep = 5; - double average = 0., avg = 0.; - int noHeight = 0; + int i, anz = 0; + int heightStep = 5; + double average = 0., avg = 0.; + int noHeight = 0; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if ((*this)[i].height() > MIN_HEIGHT) // !=-1// insbesondere von hand eingefuegte trackpoint/persons haben keine farbe + if((*this)[i].height() > + MIN_HEIGHT) // !=-1// insbesondere von hand eingefuegte trackpoint/persons haben keine farbe { - ++dict[(((int) (*this)[i].height())/heightStep)*heightStep]; + ++dict[(((int) (*this)[i].height()) / heightStep) * heightStep]; avg += (*this)[i].height(); } else ++noHeight; } j = dict.constBegin(); - while (j != dict.constEnd()) { + while(j != dict.constEnd()) + { anz += j.value(); ++j; } debout << "number of persons with measured height : " << anz << std::endl; - debout << "person without measured height (not included in calculated values): " << noHeight << " (using default height for export)" << std::endl; - if (anz == 0) + debout << "person without measured height (not included in calculated values): " << noHeight + << " (using default height for export)" << std::endl; + if(anz == 0) return false; j = dict.constBegin(); - while (j != dict.constEnd()) { - debout << "height " << std::fixed << std::setprecision(1) << std::setw(5) << j.key() << " - " << j.key()+heightStep << " : number " << std::setw(3) << j.value() << " (" << std::setw(4) << (100.*j.value())/anz << "%)" << std::endl; - average+=(j.key()+heightStep/2.)*j.value(); + while(j != dict.constEnd()) + { + debout << "height " << std::fixed << std::setprecision(1) << std::setw(5) << j.key() << " - " + << j.key() + heightStep << " : number " << std::setw(3) << j.value() << " (" << std::setw(4) + << (100. * j.value()) / anz << "%)" << std::endl; + average += (j.key() + heightStep / 2.) * j.value(); ++j; } - debout << "average height (bucket): " << std::fixed << std::setprecision(1) << std::setw(5) << average/anz << std::endl; - debout << "average height : " << std::fixed << std::setprecision(1) << std::setw(5) << avg/anz << std::endl; + debout << "average height (bucket): " << std::fixed << std::setprecision(1) << std::setw(5) << average / anz + << std::endl; + debout << "average height : " << std::fixed << std::setprecision(1) << std::setw(5) << avg / anz + << std::endl; return true; } - /** - * Sets the heights based on the values contained in \p heights. - * @param heights Map between marker ID and corresponding height - */ +/** + * Sets the heights based on the values contained in \p heights. + * @param heights Map between marker ID and corresponding height + */ void Tracker::setMarkerHeights(const std::unordered_map<int, float> &heights) { - for (int i = 0; i < size(); ++i) // over TrackPerson + for(int i = 0; i < size(); ++i) // over TrackPerson { - for (int j = 0; j < (*this)[i].size(); ++j) // over TrackPoints + for(int j = 0; j < (*this)[i].size(); ++j) // over TrackPoints { // markerID of current person at current TrackPoint: int markerID = (*this)[i][j].getMarkerID(); - if (markerID != -1) // when a real markerID is found (not -1) + if(markerID != -1) // when a real markerID is found (not -1) { // find index of mID within List of MarkerIDs that were read from txt-file: - if (heights.find(markerID) != std::end(heights)) + if(heights.find(markerID) != std::end(heights)) { (*this)[i].setHeight(heights.at(markerID)); - } else + } + else { - debout << "Warning, the following markerID was not part of the height-file: " << markerID << std::endl; + debout << "Warning, the following markerID was not part of the height-file: " << markerID + << std::endl; debout << "No height set for personNR: " << (*this)[i].nr() << std::endl; } } } - } + } } /** @@ -2086,21 +2260,22 @@ void Tracker::setMarkerHeights(const std::unordered_map<int, float> &heights) */ void Tracker::setMarkerIDs(const std::unordered_map<int, int> &markerIDs) { - for (int i = 0; i < size(); ++i) // over TrackPerson + for(int i = 0; i < size(); ++i) // over TrackPerson { // personID of current person int personID = i + 1; - if (markerIDs.find(personID) != std::end(markerIDs)) + if(markerIDs.find(personID) != std::end(markerIDs)) { int markerID = markerIDs.at(personID); (*this)[i].setMarkerID(markerID); - for (int j = 0; j < (*this)[i].size(); ++j) // over TrackPoints + for(int j = 0; j < (*this)[i].size(); ++j) // over TrackPoints { (*this)[i][j].setMarkerID(markerID); } - }else + } + else { - debout << "Warning, the following personID was not part of the markerID-file: " << personID << std::endl; + debout << "Warning, the following personID was not part of the markerID-file: " << personID << std::endl; } } } @@ -2118,21 +2293,21 @@ void Tracker::setMarkerIDs(const std::unordered_map<int, int> &markerIDs) */ void Tracker::purge(int frame) { - int i, j; + int i, j; float count; ///< number of trackpoints without recognition - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if (at(i).size() > 10 && at(i).firstFrame() <= frame && at(i).lastFrame() >= frame) + if(at(i).size() > 10 && at(i).firstFrame() <= frame && at(i).lastFrame() >= frame) { count = 0; - for (j = 0; j < at(i).size(); ++j) + for(j = 0; j < at(i).size(); ++j) { - if (at(i).at(j).qual() < 100.) + if(at(i).at(j).qual() < 100.) ++count; } - if (count/at(i).size() > 0.8) // Achtung, wenn roi klein, dann viele tp nur getrackt - removeAt(i); // delete trj + if(count / at(i).size() > 0.8) // Achtung, wenn roi klein, dann viele tp nur getrackt + removeAt(i); // delete trj } } } @@ -2147,27 +2322,17 @@ void Tracker::purge(int frame) */ void TrackPerson::syncTrackPersonMarkerID(int markerID) { - int tpMarkerID = markerID; //MarkerID of currently handled trackpoint + int tpMarkerID = markerID; // MarkerID of currently handled trackpoint - if (tpMarkerID != -1) // CodeMarker was recognized + if(tpMarkerID != -1) // CodeMarker was recognized { - if (mMarkerID == -1) // first time a Person is found TrackPerson.mMarkerID is -1 by initialisation + if(mMarkerID == -1) // first time a Person is found TrackPerson.mMarkerID is -1 by initialisation { setMarkerID(tpMarkerID); // set TrackPerson MarkerID equal to TrackPoint MarkerID } - if (mMarkerID != tpMarkerID) + if(mMarkerID != tpMarkerID) { std::cout << "ERROR: Two MarkerIDs were found for one trajectory." << std::endl; } } } - - - - - - - - - - diff --git a/src/trackerItem.cpp b/src/trackerItem.cpp index 661ab79acc92fa5adc4a190112dca9e073e12ed4..70bc9397825924d2adef48e910427c943a371d46 100644 --- a/src/trackerItem.cpp +++ b/src/trackerItem.cpp @@ -18,27 +18,27 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> -#include <QInputDialog> +#include "trackerItem.h" #include "animation.h" -#include "petrack.h" #include "control.h" -#include "view.h" -#include "trackerItem.h" -#include "tracker.h" +#include "petrack.h" #include "recognitionRoiItem.h" +#include "tracker.h" #include "trackingRoiItem.h" +#include "view.h" + +#include <QInputDialog> +#include <QtWidgets> // in x und y gleichermassen skaliertes koordinatensystem, // da von einer vorherigen intrinsischen kamerakalibrierung ausgegenagen wird, -// so dass pixel quadratisch -TrackerItem::TrackerItem(QWidget *wParent, Tracker *tracker, QGraphicsItem * parent) - : QGraphicsItem(parent) +// so dass pixel quadratisch +TrackerItem::TrackerItem(QWidget *wParent, Tracker *tracker, QGraphicsItem *parent) : QGraphicsItem(parent) { - mMainWindow = (class Petrack*) wParent; + mMainWindow = (class Petrack *) wParent; mControlWidget = mMainWindow->getControlWidget(); - mTracker = tracker; + mTracker = tracker; } /** @@ -51,46 +51,54 @@ TrackerItem::TrackerItem(QWidget *wParent, Tracker *tracker, QGraphicsItem * par */ QRectF TrackerItem::boundingRect() const { - if (mMainWindow->getImage()) - return QRectF(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), mMainWindow->getImage()->width(), mMainWindow->getImage()->height()); + if(mMainWindow->getImage()) + return QRectF( + -mMainWindow->getImageBorderSize(), + -mMainWindow->getImageBorderSize(), + mMainWindow->getImage()->width(), + mMainWindow->getImage()->height()); else return QRectF(0, 0, 0, 0); } void TrackerItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { - if( !(event->modifiers() & Qt::ShiftModifier || event->modifiers() & Qt::ControlModifier || event->modifiers() & Qt::AltModifier) ) + if(!(event->modifiers() & Qt::ShiftModifier || event->modifiers() & Qt::ControlModifier || + event->modifiers() & Qt::AltModifier)) { - TrackPoint p((Vec2F) event->pos(), 110); // 110 ist ueber 100 (hoechste Qualitaetsstufe) und wird nach einfuegen auf 100 gesetzt - bool found = false; - int i, iNearest = -1; + TrackPoint p( + (Vec2F) event->pos(), + 110); // 110 ist ueber 100 (hoechste Qualitaetsstufe) und wird nach einfuegen auf 100 gesetzt + bool found = false; + int i, iNearest = -1; float dist, minDist = 1000000.; QSet<int> onlyVisible = mMainWindow->getPedestrianUserSelection(); - int frame = mMainWindow->getAnimation()->getCurrentFrameNum(); + int frame = mMainWindow->getAnimation()->getCurrentFrameNum(); - for (i = 0; i < mTracker->size(); ++i) // !found && // ueber TrackPerson + for(i = 0; i < mTracker->size(); ++i) // !found && // ueber TrackPerson { - if (((onlyVisible.empty()) || (onlyVisible.contains(i))) && mTracker->at(i).trackPointExist(frame)) + if(((onlyVisible.empty()) || (onlyVisible.contains(i))) && mTracker->at(i).trackPointExist(frame)) { dist = mTracker->at(i).trackPointAt(frame).distanceToPoint(p); - if (( dist < mMainWindow->getHeadSize(nullptr, i, frame)/2.) || - ( (mTracker->at(i).trackPointAt(frame).distanceToPoint(p.colPoint()) < mMainWindow->getHeadSize(nullptr, i, frame)/2.))) + if((dist < mMainWindow->getHeadSize(nullptr, i, frame) / 2.) || + ((mTracker->at(i).trackPointAt(frame).distanceToPoint(p.colPoint()) < + mMainWindow->getHeadSize(nullptr, i, frame) / 2.))) { - if (found) + if(found) { debout << "Warning: more possible trackpoints for point" << std::endl; debout << " " << p << " in frame " << frame << " with low distance:" << std::endl; - debout << " person " << i+1 << " (distance: " << dist << "), " << std::endl; - debout << " person " << iNearest+1 << " (distance: " << minDist << "), " << std::endl; - if (minDist > dist) + debout << " person " << i + 1 << " (distance: " << dist << "), " << std::endl; + debout << " person " << iNearest + 1 << " (distance: " << minDist << "), " << std::endl; + if(minDist > dist) { - minDist = dist; + minDist = dist; iNearest = i; } } else { - minDist = dist; + minDist = dist; iNearest = i; // WAR: break inner loop found = true; @@ -98,34 +106,41 @@ void TrackerItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) } } } - QMenu menu; + QMenu menu; TrackPerson tp; - float height = 0.f; - bool height_set_by_user = false; - QAction *delTrj = nullptr, *delFutureTrj = nullptr, *delPastTrj = nullptr, *creTrj = nullptr, *infoTrj = nullptr, *addComment = nullptr, *setHeight = nullptr, *resetHeight = nullptr; + float height = 0.f; + bool height_set_by_user = false; + QAction * delTrj = nullptr, *delFutureTrj = nullptr, *delPastTrj = nullptr, *creTrj = nullptr, + *infoTrj = nullptr, *addComment = nullptr, *setHeight = nullptr, *resetHeight = nullptr; if(found) { - i = iNearest; - tp = mTracker->at(i); + i = iNearest; + tp = mTracker->at(i); height = tp.height(); - if (height < MIN_HEIGHT+1) + if(height < MIN_HEIGHT + 1) { - if (tp.color().isValid()) + if(tp.color().isValid()) height = mControlWidget->getColorPlot()->map(tp.color()); - }else + } + else { height_set_by_user = true; } - infoTrj = menu.addAction(QString("PersonNr: %1 height: %2 frames: [%3..%4]").arg(i+1).arg(height).arg(tp.firstFrame()).arg(tp.lastFrame())); - delTrj = menu.addAction("Delete whole trajectory"); + infoTrj = menu.addAction(QString("PersonNr: %1 height: %2 frames: [%3..%4]") + .arg(i + 1) + .arg(height) + .arg(tp.firstFrame()) + .arg(tp.lastFrame())); + delTrj = menu.addAction("Delete whole trajectory"); delFutureTrj = menu.addAction("Delete past part of the trajectory"); - delPastTrj = menu.addAction("Delete future part of the trajectory"); - setHeight = menu.addAction("Set person height"); - if(height_set_by_user) resetHeight = menu.addAction("Reset height"); - addComment = menu.addAction("Edit comment"); + delPastTrj = menu.addAction("Delete future part of the trajectory"); + setHeight = menu.addAction("Set person height"); + if(height_set_by_user) + resetHeight = menu.addAction("Reset height"); + addComment = menu.addAction("Edit comment"); } else { @@ -133,97 +148,110 @@ void TrackerItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) } QAction *selectedAction = menu.exec(event->screenPos()); - if( selectedAction == creTrj ) + if(selectedAction == creTrj) { mMainWindow->addOrMoveManualTrackPoint(event->scenePos()); - }else if( selectedAction == delTrj ) + } + else if(selectedAction == delTrj) { - mMainWindow->deleteTrackPoint(event->scenePos(),0); - }else if( selectedAction == delFutureTrj ) + mMainWindow->deleteTrackPoint(event->scenePos(), 0); + } + else if(selectedAction == delFutureTrj) { - mMainWindow->deleteTrackPoint(event->scenePos(),-1); - }else if( selectedAction == delPastTrj ) + mMainWindow->deleteTrackPoint(event->scenePos(), -1); + } + else if(selectedAction == delPastTrj) { - mMainWindow->deleteTrackPoint(event->scenePos(),1); - }else if( selectedAction == addComment ) + mMainWindow->deleteTrackPoint(event->scenePos(), 1); + } + else if(selectedAction == addComment) { mMainWindow->editTrackPersonComment(event->scenePos()); - }else if( selectedAction == setHeight ) + } + else if(selectedAction == setHeight) { mMainWindow->setTrackPersonHeight(event->scenePos()); - }else if( selectedAction == resetHeight ) + } + else if(selectedAction == resetHeight) { mMainWindow->resetTrackPersonHeight(event->scenePos()); - }else if( selectedAction == infoTrj ) + } + else if(selectedAction == infoTrj) { - if (found) + if(found) { - QString out; + QString out; QMessageBox msgBox; - msgBox.setText(QString("Info for trajectory number %1:").arg(i+1)); + msgBox.setText(QString("Info for trajectory number %1:").arg(i + 1)); if(height_set_by_user) { out = QString("<table>" - "<tr><td>height:</td><td>%0 cm (edited by user)</td></tr>" - "<tr><td>frames:</td><td>[%1...%2]</td></tr>" - "<tr><td>color:</td><td><font style='display:inline;background:%3;color:#fff;'>%4</font></td></tr>" - "<tr><td>comment:</td><td>%5</td></tr>" - "<tr><td></td><td></td></tr>"); + "<tr><td>height:</td><td>%0 cm (edited by user)</td></tr>" + "<tr><td>frames:</td><td>[%1...%2]</td></tr>" + "<tr><td>color:</td><td><font " + "style='display:inline;background:%3;color:#fff;'>%4</font></td></tr>" + "<tr><td>comment:</td><td>%5</td></tr>" + "<tr><td></td><td></td></tr>"); } else { out = QString("<table>" - "<tr><td>height:</td><td>%0 cm</td></tr>" - "<tr><td>frames:</td><td>[%1...%2]</td></tr>" - "<tr><td>color:</td><td><font style='display:inline;background:%3;color:#fff;'>%4</font></td></tr>" - "<tr><td>comment:</td><td>%5</td></tr>" - "<tr><td></td><td></td></tr>"); + "<tr><td>height:</td><td>%0 cm</td></tr>" + "<tr><td>frames:</td><td>[%1...%2]</td></tr>" + "<tr><td>color:</td><td><font " + "style='display:inline;background:%3;color:#fff;'>%4</font></td></tr>" + "<tr><td>comment:</td><td>%5</td></tr>" + "<tr><td></td><td></td></tr>"); } - if( tp.lastFrame()-tp.firstFrame() > 5 ) + if(tp.lastFrame() - tp.firstFrame() > 5) { out.append(QString("<tr><td>frame [%6]:</td><td>[%7, %8]</td></tr>" - "<tr><td>frame [%9]:</td><td>[%10, %11]</td></tr>" - "<tr><td colspan='2'>...</td></tr>" - "<tr><td colspan='2'>...</td></tr>" - "<tr><td>frame [%12]:</td><td>[%13, %14]</td></tr>" - "<tr><td>frame [%15]:</td><td>[%16, %17]]</td></tr>" - "</table>").toLatin1()); - msgBox.setInformativeText( out.arg(height) - .arg(tp.firstFrame()) - .arg(tp.lastFrame()) - .arg(tp.color().name()) - .arg(tp.color().name()) - .arg(tp.comment()) - .arg(tp.firstFrame()) - .arg(tp.at(0).x()) - .arg(tp.at(0).y()) - .arg(tp.firstFrame()+1) - .arg(tp.at(1).x()) - .arg(tp.at(1).y()) - .arg(tp.lastFrame()-1) - .arg(tp.at(tp.size()-2).x()) - .arg(tp.at(tp.size()-2).y()) - .arg(tp.lastFrame()) - .arg(tp.at(tp.size()-1).x()) - .arg(tp.at(tp.size()-1).y())); + "<tr><td>frame [%9]:</td><td>[%10, %11]</td></tr>" + "<tr><td colspan='2'>...</td></tr>" + "<tr><td colspan='2'>...</td></tr>" + "<tr><td>frame [%12]:</td><td>[%13, %14]</td></tr>" + "<tr><td>frame [%15]:</td><td>[%16, %17]]</td></tr>" + "</table>") + .toLatin1()); + msgBox.setInformativeText(out.arg(height) + .arg(tp.firstFrame()) + .arg(tp.lastFrame()) + .arg(tp.color().name()) + .arg(tp.color().name()) + .arg(tp.comment()) + .arg(tp.firstFrame()) + .arg(tp.at(0).x()) + .arg(tp.at(0).y()) + .arg(tp.firstFrame() + 1) + .arg(tp.at(1).x()) + .arg(tp.at(1).y()) + .arg(tp.lastFrame() - 1) + .arg(tp.at(tp.size() - 2).x()) + .arg(tp.at(tp.size() - 2).y()) + .arg(tp.lastFrame()) + .arg(tp.at(tp.size() - 1).x()) + .arg(tp.at(tp.size() - 1).y())); } else { out.append(QString("</table>")); - msgBox.setInformativeText( out.arg(height) - .arg(tp.firstFrame()) - .arg(tp.lastFrame()) - .arg(tp.color().name()) - .arg(tp.color().name()) - .arg(tp.comment())); + msgBox.setInformativeText(out.arg(height) + .arg(tp.firstFrame()) + .arg(tp.lastFrame()) + .arg(tp.color().name()) + .arg(tp.color().name()) + .arg(tp.comment())); } out = QString(); - for(int frameTrackperson=tp.firstFrame(); frameTrackperson <= tp.lastFrame(); frameTrackperson++) + for(int frameTrackperson = tp.firstFrame(); frameTrackperson <= tp.lastFrame(); frameTrackperson++) { - out.append(QString("frame [%0]: [%1, %2]\n").arg(frameTrackperson).arg(tp.at(frameTrackperson - tp.firstFrame()).x()).arg(tp.at(frameTrackperson - tp.firstFrame()).y())); + out.append(QString("frame [%0]: [%1, %2]\n") + .arg(frameTrackperson) + .arg(tp.at(frameTrackperson - tp.firstFrame()).x()) + .arg(tp.at(frameTrackperson - tp.firstFrame()).y())); } msgBox.setDetailedText(out); @@ -239,42 +267,42 @@ void TrackerItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) } mMainWindow->getScene()->update(); } - -void TrackerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) + +void TrackerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - int from, to; - int curFrame = mMainWindow->getAnimation()->getCurrentFrameNum(); - QPen ellipsePen; - QRectF rect; - Vec2F normalVector; + int from, to; + int curFrame = mMainWindow->getAnimation()->getCurrentFrameNum(); + QPen ellipsePen; + QRectF rect; + Vec2F normalVector; cv::Subdiv2D subdiv; - QPen linePen; - QPen numberPen; - QPen groundPositionPen; - QPen groundPathPen; - double pSP = (double) mControlWidget->trackCurrentPointSize->value(); - double pS = (double) mControlWidget->trackPointSize->value(); - double pSC = (double) mControlWidget->trackColColorSize->value(); - double pSM = (double) mControlWidget->trackColorMarkerSize->value(); - double pSN = (double) mControlWidget->trackNumberSize->value(); - double pSG = (double) mControlWidget->trackGroundPositionSize->value(); - double pSGP = (double) mControlWidget->trackGroundPathSize->value(); + QPen linePen; + QPen numberPen; + QPen groundPositionPen; + QPen groundPathPen; + double pSP = (double) mControlWidget->trackCurrentPointSize->value(); + double pS = (double) mControlWidget->trackPointSize->value(); + double pSC = (double) mControlWidget->trackColColorSize->value(); + double pSM = (double) mControlWidget->trackColorMarkerSize->value(); + double pSN = (double) mControlWidget->trackNumberSize->value(); + double pSG = (double) mControlWidget->trackGroundPositionSize->value(); + double pSGP = (double) mControlWidget->trackGroundPathSize->value(); QColor pGPC = mControlWidget->getTrackGroundPathColor(); QColor pTPC = mControlWidget->getTrackPathColor(); - QFont font, heightFont; - float x_offset=0, y_offset=0; - float y_switch=0, x_switch=0; + QFont font, heightFont; + float x_offset = 0, y_offset = 0; + float y_switch = 0, x_switch = 0; double hS; - painter->drawRect( boundingRect() ); + painter->drawRect(boundingRect()); linePen.setColor(pTPC); linePen.setWidth(mControlWidget->trackPathWidth->value()); ellipsePen.setWidth(3); - if (mControlWidget->trackNumberBold->checkState() == Qt::Checked) + if(mControlWidget->trackNumberBold->checkState() == Qt::Checked) font.setBold(true); else font.setBold(false); @@ -293,82 +321,94 @@ void TrackerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*opt // ToDo: adjust subdiv rect to correct area QRectF qrect = mMainWindow->getRecoRoiItem()->rect(); - cv::Point3f leftTop = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(qrect.left(),qrect.top()),0); - cv::Point3f rightBottom = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(qrect.right(),qrect.bottom()),0); - - x_offset = -std::min(leftTop.x,rightBottom.x); - y_offset = -std::min(leftTop.y,rightBottom.y); - x_switch = rightBottom.x < leftTop.x ? abs(rightBottom.x-leftTop.x) : 0; - y_switch = rightBottom.y < leftTop.y ? abs(leftTop.y-rightBottom.y) : 0; - debout << "x_offset: " << x_offset << ", y_offset: " << y_offset << ", x_switch: " << x_switch << ", y_switch: " << y_switch << std::endl; - - cv::Rect delaunyROI(cv::Rect(leftTop.x+x_offset,leftTop.y+y_offset,x_switch>0 ? x_switch : (rightBottom.x-leftTop.x),y_switch>0 ? y_switch : (rightBottom.y-leftTop.y))); - debout << "Rect size: P(" << delaunyROI.x << ", " << delaunyROI.y << "), width: " << delaunyROI.width << ", height: " << delaunyROI.height << std::endl; + cv::Point3f leftTop = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(qrect.left(), qrect.top()), 0); + cv::Point3f rightBottom = + mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(qrect.right(), qrect.bottom()), 0); + + x_offset = -std::min(leftTop.x, rightBottom.x); + y_offset = -std::min(leftTop.y, rightBottom.y); + x_switch = rightBottom.x < leftTop.x ? abs(rightBottom.x - leftTop.x) : 0; + y_switch = rightBottom.y < leftTop.y ? abs(leftTop.y - rightBottom.y) : 0; + debout << "x_offset: " << x_offset << ", y_offset: " << y_offset << ", x_switch: " << x_switch + << ", y_switch: " << y_switch << std::endl; + + cv::Rect delaunyROI(cv::Rect( + leftTop.x + x_offset, + leftTop.y + y_offset, + x_switch > 0 ? x_switch : (rightBottom.x - leftTop.x), + y_switch > 0 ? y_switch : (rightBottom.y - leftTop.y))); + debout << "Rect size: P(" << delaunyROI.x << ", " << delaunyROI.y << "), width: " << delaunyROI.width + << ", height: " << delaunyROI.height << std::endl; subdiv.initDelaunay(delaunyROI); } auto pedestrianToPaint = mMainWindow->getPedestrianUserSelection(); - for (int i = 0; i < mTracker->size(); ++i) // ueber TrackPerson + for(int i = 0; i < mTracker->size(); ++i) // ueber TrackPerson { // show current frame - if (pedestrianToPaint.contains(i) || pedestrianToPaint.empty()) - { - if (mTracker->at(i).trackPointExist(curFrame)) + if(pedestrianToPaint.contains(i) || pedestrianToPaint.empty()) + { + if(mTracker->at(i).trackPointExist(curFrame)) { - if (mControlWidget->trackHeadSized->checkState() == Qt::Checked) - pSP = mMainWindow->getHeadSize(nullptr, i, curFrame); //headSize; - const TrackPoint &tp = (*mTracker)[i][curFrame-mTracker->at(i).firstFrame()]; - if (mControlWidget->trackShowCurrentPoint->checkState() == Qt::Checked) //(mControlWidget->recoShowColor->checkState() == Qt::Checked) + if(mControlWidget->trackHeadSized->checkState() == Qt::Checked) + pSP = mMainWindow->getHeadSize(nullptr, i, curFrame); // headSize; + const TrackPoint &tp = (*mTracker)[i][curFrame - mTracker->at(i).firstFrame()]; + if(mControlWidget->trackShowCurrentPoint->checkState() == + Qt::Checked) //(mControlWidget->recoShowColor->checkState() == Qt::Checked) { painter->setBrush(Qt::NoBrush); - if (mTracker->at(i).newReco()) + if(mTracker->at(i).newReco()) painter->setPen(Qt::green); else painter->setPen(Qt::blue); - rect.setRect(tp.x()-pSP/2., tp.y()-pSP/2., pSP, pSP); + rect.setRect(tp.x() - pSP / 2., tp.y() - pSP / 2., pSP, pSP); painter->drawEllipse(rect); // direkt waere nur int erlaubt tp.x()-5., tp.y()-5., 10., 10. } - if (mControlWidget->trackShowSearchSize->checkState() == Qt::Checked) + if(mControlWidget->trackShowSearchSize->checkState() == Qt::Checked) { painter->setBrush(Qt::NoBrush); painter->setPen(Qt::yellow); hS = mMainWindow->winSize(nullptr, i, curFrame); - if (hS < 2) + if(hS < 2) hS = 2; // entspricht Vorgehen in tracker.cpp - for (int j = 0; j <= mControlWidget->trackRegionLevels->value(); ++j) + for(int j = 0; j <= mControlWidget->trackRegionLevels->value(); ++j) { - rect.setRect(tp.x()-hS/2., tp.y()-hS/2., hS, hS); + rect.setRect(tp.x() - hS / 2., tp.y() - hS / 2., hS, hS); painter->drawRect(rect); hS *= 2; } } - if (mControlWidget->trackShowColorMarker->checkState() == Qt::Checked) + if(mControlWidget->trackShowColorMarker->checkState() == Qt::Checked) { // farbe des trackpoints - if (tp.color().isValid()) + if(tp.color().isValid()) { painter->setBrush(Qt::NoBrush); ellipsePen.setColor(tp.color()); painter->setPen(ellipsePen); - rect.setRect(tp.colPoint().x()-pSM/2., tp.colPoint().y()-pSM/2., pSM, pSM); + rect.setRect(tp.colPoint().x() - pSM / 2., tp.colPoint().y() - pSM / 2., pSM, pSM); painter->drawEllipse(rect); } } // berechnung der normalen, die zur positionierung der nummerieung und der gesamtfarbe dient - if (((mControlWidget->trackShowColColor->checkState() == Qt::Checked) && (mTracker->at(i).color().isValid())) || - (mControlWidget->trackShowNumber->checkState() == Qt::Checked) || - ((mControlWidget->trackShowColColor->checkState() == Qt::Checked) && - ((mTracker->at(i).height() > MIN_HEIGHT) || ((tp.sp().z() > 0.) && (mControlWidget->trackShowHeightIndividual->checkState() == Qt::Checked))))) // Hoehe kann auf Treppen auch negativ werden, wenn koord weiter oben angesetzt wird + if(((mControlWidget->trackShowColColor->checkState() == Qt::Checked) && + (mTracker->at(i).color().isValid())) || + (mControlWidget->trackShowNumber->checkState() == Qt::Checked) || + ((mControlWidget->trackShowColColor->checkState() == Qt::Checked) && + ((mTracker->at(i).height() > MIN_HEIGHT) || + ((tp.sp().z() > 0.) && (mControlWidget->trackShowHeightIndividual->checkState() == + Qt::Checked))))) // Hoehe kann auf Treppen auch negativ werden, wenn koord + // weiter oben angesetzt wird { - if (tp.color().isValid()) + if(tp.color().isValid()) { - normalVector = (tp-tp.colPoint()).normal(); + normalVector = (tp - tp.colPoint()).normal(); normalVector.normalize(); - if (normalVector.length()<.001) // wenn to und colpoint aufeinander liegen z bei colorMarker! + if(normalVector.length() < .001) // wenn to und colpoint aufeinander liegen z bei colorMarker! normalVector.set(1., 0.); } else @@ -376,21 +416,21 @@ void TrackerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*opt // man koennte auch lastNormal von anderem trackpath nehmen statt 1, 0 normalVector.set(1., 0.); // den vorherigen trackpoint finden, wo reco farbe erzeugt hat und somit colpoint vorliegt - for (int j = curFrame-mTracker->at(i).firstFrame(); j > -1; --j) - if (mTracker->at(i).at(j).color().isValid()) + for(int j = curFrame - mTracker->at(i).firstFrame(); j > -1; --j) + if(mTracker->at(i).at(j).color().isValid()) { - normalVector = (mTracker->at(i).at(j)-mTracker->at(i).at(j).colPoint()).normal(); + normalVector = (mTracker->at(i).at(j) - mTracker->at(i).at(j).colPoint()).normal(); normalVector.normalize(); break; } // einen nachfolgenden trackpoint suchen, wenn vorher keiner mit farbe war // zB wenn rueckwaerts abgespielt wird - if ((normalVector.x()==1.) && (normalVector.y()==0.)) + if((normalVector.x() == 1.) && (normalVector.y() == 0.)) { - for (int j = curFrame-mTracker->at(i).firstFrame()+1; j < mTracker->at(i).size(); ++j) - if (mTracker->at(i).at(j).color().isValid()) + for(int j = curFrame - mTracker->at(i).firstFrame() + 1; j < mTracker->at(i).size(); ++j) + if(mTracker->at(i).at(j).color().isValid()) { - normalVector = (mTracker->at(i).at(j)-mTracker->at(i).at(j).colPoint()).normal(); + normalVector = (mTracker->at(i).at(j) - mTracker->at(i).at(j).colPoint()).normal(); normalVector.normalize(); break; } @@ -400,226 +440,310 @@ void TrackerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*opt // farbe der gesamten trackperson double height = mTracker->at(i).height(); - if (mControlWidget->trackShowColColor->checkState() == Qt::Checked) + if(mControlWidget->trackShowColColor->checkState() == Qt::Checked) { painter->setPen(numberPen); painter->setBrush(Qt::NoBrush); - rect.setRect(tp.x()+10,tp.y()+10,15*pSC,10*pSC); - painter->drawText(rect,mTracker->at(i).comment()); - rect.setRect(tp.x()-pSC,tp.y()-pSC,50,50); - if (tp.getMarkerID()>0) + rect.setRect(tp.x() + 10, tp.y() + 10, 15 * pSC, 10 * pSC); + painter->drawText(rect, mTracker->at(i).comment()); + rect.setRect(tp.x() - pSC, tp.y() - pSC, 50, 50); + if(tp.getMarkerID() > 0) { - painter->drawText(rect,QString("id=%1").arg(tp.getMarkerID())); + painter->drawText(rect, QString("id=%1").arg(tp.getMarkerID())); } - } - if ((mControlWidget->trackShowColColor->checkState() == Qt::Checked) && (mTracker->at(i).color().isValid())) + if((mControlWidget->trackShowColColor->checkState() == Qt::Checked) && + (mTracker->at(i).color().isValid())) { painter->setPen(Qt::NoPen); painter->setBrush(QBrush(mTracker->at(i).color())); - rect.setRect(tp.x()+(pSP+pSC)*0.6*normalVector.x()-pSC/2., tp.y()+(pSP+pSC)*0.6*normalVector.y()-pSC/2., pSC, pSC); // 11 + rect.setRect( + tp.x() + (pSP + pSC) * 0.6 * normalVector.x() - pSC / 2., + tp.y() + (pSP + pSC) * 0.6 * normalVector.y() - pSC / 2., + pSC, + pSC); // 11 painter->drawEllipse(rect); } - else if ((mControlWidget->trackShowColColor->checkState() == Qt::Checked) && - ((height > MIN_HEIGHT) || ((tp.sp().z() > 0.) && (mControlWidget->trackShowHeightIndividual->checkState() == Qt::Checked)))) // Hoehe && (mTracker->at(i).height() > 0.) Hoehe kann auf Treppen auch negativ werden, wenn koord weiter oben angesetzt wird + else if( + (mControlWidget->trackShowColColor->checkState() == Qt::Checked) && + ((height > MIN_HEIGHT) || + ((tp.sp().z() > 0.) && + (mControlWidget->trackShowHeightIndividual->checkState() == + Qt::Checked)))) // Hoehe && (mTracker->at(i).height() > 0.) Hoehe kann auf Treppen auch negativ + // werden, wenn koord weiter oben angesetzt wird { painter->setFont(heightFont); - if ((mControlWidget->trackShowHeightIndividual->checkState() == Qt::Checked) && (tp.sp().z() > 0.)) // Hoehe incl individual fuer jeden trackpoint + if((mControlWidget->trackShowHeightIndividual->checkState() == Qt::Checked) && + (tp.sp().z() > 0.)) // Hoehe incl individual fuer jeden trackpoint { painter->setPen(numberPen); painter->setBrush(Qt::NoBrush); - rect.setRect(tp.x()+(pSP+pSC)*0.6*normalVector.x()-pSC/2., tp.y()+(pSP+pSC)*0.6*normalVector.y()-pSC/2., 3*pSC, 2.5*pSC); // 11 - if (height < MIN_HEIGHT+1) + rect.setRect( + tp.x() + (pSP + pSC) * 0.6 * normalVector.x() - pSC / 2., + tp.y() + (pSP + pSC) * 0.6 * normalVector.y() - pSC / 2., + 3 * pSC, + 2.5 * pSC); // 11 + if(height < MIN_HEIGHT + 1) { - if (mControlWidget->getCalibCoordDimension() == 0) // 3D - painter->drawText(rect, Qt::AlignHCenter, QString("-\n%2").arg(-mControlWidget->getCalibExtrTrans3()-tp.sp().z(), 6, 'f', 1)); + if(mControlWidget->getCalibCoordDimension() == 0) // 3D + painter->drawText( + rect, + Qt::AlignHCenter, + QString("-\n%2").arg( + -mControlWidget->getCalibExtrTrans3() - tp.sp().z(), 6, 'f', 1)); else - painter->drawText(rect, Qt::AlignHCenter, QString("-\n%2").arg(mControlWidget->coordAltitude->value()-tp.sp().z(), 6, 'f', 1)); - - }else + painter->drawText( + rect, + Qt::AlignHCenter, + QString("-\n%2").arg( + mControlWidget->coordAltitude->value() - tp.sp().z(), 6, 'f', 1)); + } + else { - if (mControlWidget->getCalibCoordDimension() == 0) // 3D - painter->drawText(rect, Qt::AlignHCenter, QString("%1\n%2").arg(height, 6, 'f', 1).arg(-mControlWidget->getCalibExtrTrans3()-tp.sp().z(), 6, 'f', 1)); + if(mControlWidget->getCalibCoordDimension() == 0) // 3D + painter->drawText( + rect, + Qt::AlignHCenter, + QString("%1\n%2") + .arg(height, 6, 'f', 1) + .arg(-mControlWidget->getCalibExtrTrans3() - tp.sp().z(), 6, 'f', 1)); else - painter->drawText(rect, Qt::AlignHCenter, QString("%1\n%2").arg(height, 6, 'f', 1).arg(mControlWidget->coordAltitude->value()-tp.sp().z(), 6, 'f', 1)); + painter->drawText( + rect, + Qt::AlignHCenter, + QString("%1\n%2") + .arg(height, 6, 'f', 1) + .arg(mControlWidget->coordAltitude->value() - tp.sp().z(), 6, 'f', 1)); } } else { painter->setPen(numberPen); painter->setBrush(Qt::NoBrush); - rect.setRect(tp.x()+(pSP+pSC)*0.6*normalVector.x()-pSC/2., tp.y()+(pSP+pSC)*0.6*normalVector.y()-pSC/2., 3*pSC, 2*pSC); // 11 + rect.setRect( + tp.x() + (pSP + pSC) * 0.6 * normalVector.x() - pSC / 2., + tp.y() + (pSP + pSC) * 0.6 * normalVector.y() - pSC / 2., + 3 * pSC, + 2 * pSC); // 11 painter->drawText(rect, Qt::AlignHCenter, QString("%1").arg(height, 6, 'f', 1)); } painter->setFont(font); } - if (mControlWidget->trackShowNumber->checkState() == Qt::Checked) + if(mControlWidget->trackShowNumber->checkState() == Qt::Checked) { // listennummer painter->setPen(numberPen); painter->setBrush(Qt::NoBrush); - rect.setRect(tp.x()-(pSP+pSN)*0.6*normalVector.x()-pSN, tp.y()-(pSP+pSN)*0.6*normalVector.y()-pSN/2., 2.*pSN, pSN); // 11 - painter->drawText(rect, Qt::AlignHCenter, QString("%1").arg(i+1)); + rect.setRect( + tp.x() - (pSP + pSN) * 0.6 * normalVector.x() - pSN, + tp.y() - (pSP + pSN) * 0.6 * normalVector.y() - pSN / 2., + 2. * pSN, + pSN); // 11 + painter->drawText(rect, Qt::AlignHCenter, QString("%1").arg(i + 1)); } - if (mControlWidget->trackShowGroundPosition->checkState() == Qt::Checked) + if(mControlWidget->trackShowGroundPosition->checkState() == Qt::Checked) { // ground position painter->setPen(groundPositionPen); painter->setBrush(Qt::NoBrush); - if( mControlWidget->getCalibCoordDimension() == 0) // 3D + if(mControlWidget->getCalibCoordDimension() == 0) // 3D { - double cross_size = 15+pSG*0.25; + double cross_size = 15 + pSG * 0.25; cv::Point3f p3d_height; - if (height < MIN_HEIGHT+1) + if(height < MIN_HEIGHT + 1) { - p3d_height = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(tp.x(),tp.y()),mControlWidget->getColorPlot()->map(mTracker->at(i).color())); - }else + p3d_height = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(tp.x(), tp.y()), + mControlWidget->getColorPlot()->map(mTracker->at(i).color())); + } + else { - if ( tp.sp().z() > 0 ) - p3d_height = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(tp.x(),tp.y()),-mControlWidget->getCalibExtrTrans3()-tp.sp().z()); + if(tp.sp().z() > 0) + p3d_height = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(tp.x(), tp.y()), -mControlWidget->getCalibExtrTrans3() - tp.sp().z()); else - p3d_height = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(tp.x(),tp.y()),height/*mControlWidget->mapDefaultHeight->value()*/); + p3d_height = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(tp.x(), tp.y()), height /*mControlWidget->mapDefaultHeight->value()*/); } - p3d_height.z = 0; + p3d_height.z = 0; cv::Point2f p2d_ground = mMainWindow->getExtrCalibration()->getImagePoint(p3d_height); - QPointF axis = mMainWindow->getImageItem()->getCmPerPixel(p2d_ground.x, p2d_ground.y, 0); - painter->drawLine(QLineF(p2d_ground.x-cross_size*0.5*pow(axis.x(),-1),p2d_ground.y-cross_size*0.5*pow(axis.y(),-1),p2d_ground.x+cross_size*0.5*pow(axis.x(),-1),p2d_ground.y+cross_size*0.5*pow(axis.y(),-1))); - painter->drawLine(QLineF(p2d_ground.x-cross_size*0.5*pow(axis.x(),-1),p2d_ground.y+cross_size*0.5*pow(axis.y(),-1),p2d_ground.x+cross_size*0.5*pow(axis.x(),-1),p2d_ground.y-cross_size*0.5*pow(axis.y(),-1))); - painter->drawLine(QLineF(p2d_ground.x,p2d_ground.y,tp.x(),tp.y())); - - - - }else // 2D + QPointF axis = mMainWindow->getImageItem()->getCmPerPixel(p2d_ground.x, p2d_ground.y, 0); + painter->drawLine(QLineF( + p2d_ground.x - cross_size * 0.5 * pow(axis.x(), -1), + p2d_ground.y - cross_size * 0.5 * pow(axis.y(), -1), + p2d_ground.x + cross_size * 0.5 * pow(axis.x(), -1), + p2d_ground.y + cross_size * 0.5 * pow(axis.y(), -1))); + painter->drawLine(QLineF( + p2d_ground.x - cross_size * 0.5 * pow(axis.x(), -1), + p2d_ground.y + cross_size * 0.5 * pow(axis.y(), -1), + p2d_ground.x + cross_size * 0.5 * pow(axis.x(), -1), + p2d_ground.y - cross_size * 0.5 * pow(axis.y(), -1))); + painter->drawLine(QLineF(p2d_ground.x, p2d_ground.y, tp.x(), tp.y())); + } + else // 2D { - - } - } - if( mControlWidget->showVoronoiCells->checkState() == Qt::Checked) + if(mControlWidget->showVoronoiCells->checkState() == Qt::Checked) { - if( mControlWidget->getCalibCoordDimension() == 0 ) // 3D + if(mControlWidget->getCalibCoordDimension() == 0) // 3D { cv::Point3f p3d_height; - if (height < MIN_HEIGHT+1) + if(height < MIN_HEIGHT + 1) { - p3d_height = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(tp.x(),tp.y()),mControlWidget->getColorPlot()->map(mTracker->at(i).color())); - }else + p3d_height = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(tp.x(), tp.y()), + mControlWidget->getColorPlot()->map(mTracker->at(i).color())); + } + else { - if ( tp.sp().z() > 0 ) - p3d_height = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(tp.x(),tp.y()),-mControlWidget->getCalibExtrTrans3()-tp.sp().z()); + if(tp.sp().z() > 0) + p3d_height = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(tp.x(), tp.y()), -mControlWidget->getCalibExtrTrans3() - tp.sp().z()); else - p3d_height = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(tp.x(),tp.y()),height/*mControlWidget->mapDefaultHeight->value()*/); + p3d_height = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(tp.x(), tp.y()), height /*mControlWidget->mapDefaultHeight->value()*/); } - debout << "insert P(" << p3d_height.x+x_offset << ", " << p3d_height.y+y_offset << ") to subdiv" << std::endl; - - subdiv.insert(cv::Point2f(x_switch>0 ? x_switch-p3d_height.x+x_offset : p3d_height.x+x_offset, y_switch>0 ? y_switch-p3d_height.y+y_offset : p3d_height.y+y_offset));// p2d_ground); + debout << "insert P(" << p3d_height.x + x_offset << ", " << p3d_height.y + y_offset + << ") to subdiv" << std::endl; + subdiv.insert(cv::Point2f( + x_switch > 0 ? x_switch - p3d_height.x + x_offset : p3d_height.x + x_offset, + y_switch > 0 ? y_switch - p3d_height.y + y_offset : + p3d_height.y + y_offset)); // p2d_ground); } } } - - if (((mControlWidget->trackShowPoints->checkState() == Qt::Checked) || (mControlWidget->trackShowPath->checkState() == Qt::Checked) || (mControlWidget->trackShowGroundPath->checkState() == Qt::Checked)) && ((mTracker->at(i).trackPointExist(curFrame)) || (mControlWidget->trackShowOnlyVisible->checkState() == Qt::Unchecked))) + + if(((mControlWidget->trackShowPoints->checkState() == Qt::Checked) || + (mControlWidget->trackShowPath->checkState() == Qt::Checked) || + (mControlWidget->trackShowGroundPath->checkState() == Qt::Checked)) && + ((mTracker->at(i).trackPointExist(curFrame)) || + (mControlWidget->trackShowOnlyVisible->checkState() == Qt::Unchecked))) { - if (mControlWidget->trackShowBefore->value() == -1) + if(mControlWidget->trackShowBefore->value() == -1) from = 0; else { - from = curFrame-mTracker->at(i).firstFrame()-mControlWidget->trackShowBefore->value(); - if (from < 0) + from = curFrame - mTracker->at(i).firstFrame() - mControlWidget->trackShowBefore->value(); + if(from < 0) from = 0; } - if (mControlWidget->trackShowAfter->value() == -1) + if(mControlWidget->trackShowAfter->value() == -1) to = mTracker->at(i).size(); else { - to = curFrame-mTracker->at(i).firstFrame()+mControlWidget->trackShowAfter->value()+1; - if (to > mTracker->at(i).size()) + to = curFrame - mTracker->at(i).firstFrame() + mControlWidget->trackShowAfter->value() + 1; + if(to > mTracker->at(i).size()) to = mTracker->at(i).size(); } - for (int j = from; j < to; ++j) // ueber TrackPoint + for(int j = from; j < to; ++j) // ueber TrackPoint { // path - if (mControlWidget->trackShowPath->checkState() == Qt::Checked) + if(mControlWidget->trackShowPath->checkState() == Qt::Checked) { - if (j != from) // autom. > 0 + if(j != from) // autom. > 0 { painter->setPen(linePen); painter->setBrush(Qt::NoBrush); // nur Linie zeichnen, wenn x oder y sich unterscheidet, sonst Punkt // die Unterscheidung ist noetig, da Qt sonst grosses quadrat beim ranzoomen zeichnet - if ((mTracker->at(i).at(j-1).toQPointF().x() != mTracker->at(i).at(j).toQPointF().x()) || - (mTracker->at(i).at(j-1).toQPointF().y() != mTracker->at(i).at(j).toQPointF().y())) - painter->drawLine(mTracker->at(i).at(j-1).toQPointF(), mTracker->at(i).at(j).toQPointF()); + if((mTracker->at(i).at(j - 1).toQPointF().x() != mTracker->at(i).at(j).toQPointF().x()) || + (mTracker->at(i).at(j - 1).toQPointF().y() != mTracker->at(i).at(j).toQPointF().y())) + painter->drawLine( + mTracker->at(i).at(j - 1).toQPointF(), mTracker->at(i).at(j).toQPointF()); else - painter->drawPoint(mTracker->at(i).at(j-1).toQPointF()); + painter->drawPoint(mTracker->at(i).at(j - 1).toQPointF()); } } // path on ground - if (mControlWidget->trackShowGroundPath->checkState() == Qt::Checked) + if(mControlWidget->trackShowGroundPath->checkState() == Qt::Checked) { - if (j != from) + if(j != from) { - // ground position painter->setPen(groundPathPen); painter->setBrush(Qt::NoBrush); - if( mControlWidget->getCalibCoordDimension() == 0) // 3D + if(mControlWidget->getCalibCoordDimension() == 0) // 3D { cv::Point3f p3d_height_p1, p3d_height_p2; - if (mTracker->at(i).height() < MIN_HEIGHT+1) + if(mTracker->at(i).height() < MIN_HEIGHT + 1) { - p3d_height_p1 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(mTracker->at(i).at(j-1).x(),mTracker->at(i).at(j-1).y()),mControlWidget->getColorPlot()->map(mTracker->at(i).color())); - p3d_height_p2 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(mTracker->at(i).at(j).x(),mTracker->at(i).at(j).y()),mControlWidget->getColorPlot()->map(mTracker->at(i).color())); - }else + p3d_height_p1 = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(mTracker->at(i).at(j - 1).x(), mTracker->at(i).at(j - 1).y()), + mControlWidget->getColorPlot()->map(mTracker->at(i).color())); + p3d_height_p2 = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(mTracker->at(i).at(j).x(), mTracker->at(i).at(j).y()), + mControlWidget->getColorPlot()->map(mTracker->at(i).color())); + } + else { - if ( mTracker->at(i).at(j-1).sp().z() > 0 && mTracker->at(i).at(j).sp().z() > 0 ) + if(mTracker->at(i).at(j - 1).sp().z() > 0 && mTracker->at(i).at(j).sp().z() > 0) { - p3d_height_p1 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(mTracker->at(i).at(j-1).x(),mTracker->at(i).at(j-1).y()),-mControlWidget->getCalibExtrTrans3()-mTracker->at(i).at(j-1).sp().z()); - p3d_height_p2 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(mTracker->at(i).at(j).x(),mTracker->at(i).at(j).y()),-mControlWidget->getCalibExtrTrans3()-mTracker->at(i).at(j).sp().z()); - }else + p3d_height_p1 = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(mTracker->at(i).at(j - 1).x(), mTracker->at(i).at(j - 1).y()), + -mControlWidget->getCalibExtrTrans3() - mTracker->at(i).at(j - 1).sp().z()); + p3d_height_p2 = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(mTracker->at(i).at(j).x(), mTracker->at(i).at(j).y()), + -mControlWidget->getCalibExtrTrans3() - mTracker->at(i).at(j).sp().z()); + } + else { - p3d_height_p1 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(mTracker->at(i).at(j-1).x(),mTracker->at(i).at(j-1).y()),mTracker->at(i).height()); - p3d_height_p2 = mMainWindow->getExtrCalibration()->get3DPoint(cv::Point2f(mTracker->at(i).at(j).x(),mTracker->at(i).at(j).y()),mTracker->at(i).height()); + p3d_height_p1 = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(mTracker->at(i).at(j - 1).x(), mTracker->at(i).at(j - 1).y()), + mTracker->at(i).height()); + p3d_height_p2 = mMainWindow->getExtrCalibration()->get3DPoint( + cv::Point2f(mTracker->at(i).at(j).x(), mTracker->at(i).at(j).y()), + mTracker->at(i).height()); } } p3d_height_p1.z = 0; p3d_height_p2.z = 0; - cv::Point2f p2d_ground_p1 = mMainWindow->getExtrCalibration()->getImagePoint(p3d_height_p1); - cv::Point2f p2d_ground_p2 = mMainWindow->getExtrCalibration()->getImagePoint(p3d_height_p2); + cv::Point2f p2d_ground_p1 = + mMainWindow->getExtrCalibration()->getImagePoint(p3d_height_p1); + cv::Point2f p2d_ground_p2 = + mMainWindow->getExtrCalibration()->getImagePoint(p3d_height_p2); // nur Linie zeichnen, wenn x oder y sich unterscheidet, sonst Punkt // die Unterscheidung ist noetig, da Qt sonst grosses quadrat beim ranzoomen zeichnet - if (p2d_ground_p1.x != p2d_ground_p2.x || p2d_ground_p1.y != p2d_ground_p2.y ) - painter->drawLine(QLineF(p2d_ground_p1.x,p2d_ground_p1.y,p2d_ground_p2.x,p2d_ground_p2.y)); + if(p2d_ground_p1.x != p2d_ground_p2.x || p2d_ground_p1.y != p2d_ground_p2.y) + painter->drawLine( + QLineF(p2d_ground_p1.x, p2d_ground_p1.y, p2d_ground_p2.x, p2d_ground_p2.y)); else - painter->drawPoint(p2d_ground_p1.x,p2d_ground_p1.y); - }else // 2D + painter->drawPoint(p2d_ground_p1.x, p2d_ground_p1.y); + } + else // 2D { - } } } // points before and after - if (mControlWidget->trackShowPoints->checkState() == Qt::Checked) + if(mControlWidget->trackShowPoints->checkState() == Qt::Checked) { - if (mTracker->at(i).firstFrame()+j != curFrame) + if(mTracker->at(i).firstFrame() + j != curFrame) { - if ((mControlWidget->trackShowPointsColored->checkState() == Qt::Checked) && (mTracker->at(i).at(j).color().isValid())) + if((mControlWidget->trackShowPointsColored->checkState() == Qt::Checked) && + (mTracker->at(i).at(j).color().isValid())) { painter->setPen(Qt::NoPen); painter->setBrush(QBrush(mTracker->at(i).at(j).color())); - rect.setRect(mTracker->at(i).at(j).x()-pS/2., mTracker->at(i).at(j).y()-pS/2., pS, pS); // 7 + rect.setRect( + mTracker->at(i).at(j).x() - pS / 2., + mTracker->at(i).at(j).y() - pS / 2., + pS, + pS); // 7 } else { painter->setPen(Qt::red); painter->setBrush(Qt::NoBrush); - // war noetig fuer alte qt-version: rect.setRect(mTracker->at(i).at(j).x()-(pS-1.)/2., mTracker->at(i).at(j).y()-(pS-1.)/2., pS-1., pS-1.); // 6 - rect.setRect(mTracker->at(i).at(j).x()-pS/2., mTracker->at(i).at(j).y()-pS/2., pS, pS); + // war noetig fuer alte qt-version: rect.setRect(mTracker->at(i).at(j).x()-(pS-1.)/2., + // mTracker->at(i).at(j).y()-(pS-1.)/2., pS-1., pS-1.); // 6 + rect.setRect( + mTracker->at(i).at(j).x() - pS / 2., mTracker->at(i).at(j).y() - pS / 2., pS, pS); } painter->drawEllipse(rect); } @@ -630,140 +754,156 @@ void TrackerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*opt } // Mat& img, Subdiv2D& subdiv ) - if( mControlWidget->showVoronoiCells->checkState() == Qt::Checked && !mTracker->isEmpty() ) + if(mControlWidget->showVoronoiCells->checkState() == Qt::Checked && !mTracker->isEmpty()) { - - std::vector<std::vector<cv::Point2f> > facets3D; - std::vector<cv::Point2f> centers3D; + std::vector<std::vector<cv::Point2f>> facets3D; + std::vector<cv::Point2f> centers3D; // get Voronoi cell info from subDiv in 3D coordinates on ground (z=0) subdiv.getVoronoiFacetList(std::vector<int>(), facets3D, centers3D); - painter->setClipRect(mMainWindow->getRecoRoiItem()->rect());//0,0,mMainWindow->getImage()->width(),mMainWindow->getImage()->height()); + painter->setClipRect(mMainWindow->getRecoRoiItem() + ->rect()); // 0,0,mMainWindow->getImage()->width(),mMainWindow->getImage()->height()); // cell by cell - for( size_t i = 0; i < facets3D.size(); i++ ) + for(size_t i = 0; i < facets3D.size(); i++) { - centers3D.at(i).x = x_switch>0 ? x_switch-centers3D.at(i).x-x_offset : centers3D.at(i).x-x_offset; - centers3D.at(i).y = y_switch>0 ? y_switch-centers3D.at(i).y-y_offset : centers3D.at(i).y-y_offset; + centers3D.at(i).x = x_switch > 0 ? x_switch - centers3D.at(i).x - x_offset : centers3D.at(i).x - x_offset; + centers3D.at(i).y = y_switch > 0 ? y_switch - centers3D.at(i).y - y_offset : centers3D.at(i).y - y_offset; // voronoi cell center in 2D - cv::Point2f center2D = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(centers3D.at(i).x, - centers3D.at(i).y,0)); + cv::Point2f center2D = + mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(centers3D.at(i).x, centers3D.at(i).y, 0)); std::vector<QPointF> ifacet2D; - QPointF circleStart, circleEnd; - float area = 0; - float r = 50, m = 0, n = 0, s1_x = 0, s2_x = 0, s1_y = 0, s2_y = 0; - bool circleStarted = false; - for( size_t j = 0; j < facets3D[i].size(); j++ ) + QPointF circleStart, circleEnd; + float area = 0; + float r = 50, m = 0, n = 0, s1_x = 0, s2_x = 0, s1_y = 0, s2_y = 0; + bool circleStarted = false; + for(size_t j = 0; j < facets3D[i].size(); j++) { - facets3D.at(i).at(j).x = x_switch>0 ? x_switch-facets3D.at(i).at(j).x-x_offset : facets3D.at(i).at(j).x-x_offset; - facets3D.at(i).at(j).y = y_switch>0 ? y_switch-facets3D.at(i).at(j).y-y_offset : facets3D.at(i).at(j).y-y_offset; + facets3D.at(i).at(j).x = + x_switch > 0 ? x_switch - facets3D.at(i).at(j).x - x_offset : facets3D.at(i).at(j).x - x_offset; + facets3D.at(i).at(j).y = + y_switch > 0 ? y_switch - facets3D.at(i).at(j).y - y_offset : facets3D.at(i).at(j).y - y_offset; - cv::Point2f point2D = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(facets3D.at(i).at(j).x,facets3D.at(i).at(j).y,0)); + cv::Point2f point2D = mMainWindow->getExtrCalibration()->getImagePoint( + cv::Point3f(facets3D.at(i).at(j).x, facets3D.at(i).at(j).y, 0)); - debout << "facets3D.at(" << i << ").at(" << j << ").x = " << facets3D.at(i).at(j).x << ", .y = " << facets3D.at(i).at(j).y << std::endl; + debout << "facets3D.at(" << i << ").at(" << j << ").x = " << facets3D.at(i).at(j).x + << ", .y = " << facets3D.at(i).at(j).y << std::endl; debout << "point2D.x = " << point2D.x << " , .y = " << point2D.y << std::endl; - if constexpr ( false && sqrt(pow((facets3D.at(i).at(j).x - centers3D.at(i).x),2) + - pow((facets3D.at(i).at(j).y - centers3D.at(i).y),2)) > r ) + if constexpr( + false && sqrt( + pow((facets3D.at(i).at(j).x - centers3D.at(i).x), 2) + + pow((facets3D.at(i).at(j).y - centers3D.at(i).y), 2)) > r) { - if (circleStarted) + if(circleStarted) { - - m = (facets3D.at(i).at(j).y - facets3D.at(i).at((j-1)%facets3D.at(i).size()).y) / - (facets3D.at(i).at(j).x - facets3D.at(i).at((j-1)%facets3D.at(i).size()).x); + m = (facets3D.at(i).at(j).y - facets3D.at(i).at((j - 1) % facets3D.at(i).size()).y) / + (facets3D.at(i).at(j).x - facets3D.at(i).at((j - 1) % facets3D.at(i).size()).x); // End punkt berechnen (Schnittpunkt Gerade-Kreis) // Steigung der Geraden - m = (facets3D.at(i).at(j).y - facets3D.at(i).at((j+1)%facets3D.at(i).size()).y) / - (facets3D.at(i).at(j).x - facets3D.at(i).at((j+1)%facets3D.at(i).size()).x); + m = (facets3D.at(i).at(j).y - facets3D.at(i).at((j + 1) % facets3D.at(i).size()).y) / + (facets3D.at(i).at(j).x - facets3D.at(i).at((j + 1) % facets3D.at(i).size()).x); // Achsenabschnitt der Geraden n = facets3D.at(i).at(j).y - m * facets3D.at(i).at(j).x; - float p = -( (m*n - m*centers3D.at(i).y - centers3D.at(i).x)/(1+pow(m,2)) ); - float q = sqrt((pow(r,2)-pow(centers3D.at(i).x,2)-pow(centers3D.at(i).y,2)-pow(n,2)-2*n*centers3D.at(i).y) / (1+pow(m,2)) + - pow((m*n-m*centers3D.at(i).y-centers3D.at(i).x)/(1+pow(m,2)),2)); + float p = -((m * n - m * centers3D.at(i).y - centers3D.at(i).x) / (1 + pow(m, 2))); + float q = sqrt( + (pow(r, 2) - pow(centers3D.at(i).x, 2) - pow(centers3D.at(i).y, 2) - pow(n, 2) - + 2 * n * centers3D.at(i).y) / + (1 + pow(m, 2)) + + pow((m * n - m * centers3D.at(i).y - centers3D.at(i).x) / (1 + pow(m, 2)), 2)); // Schnittpunkte mit Kreis s1_x = p + q; - s1_y = m*s1_x+n; + s1_y = m * s1_x + n; s2_x = p - q; - s2_y = m*s2_x+n; + s2_y = m * s2_x + n; - facets3D[i][j] = cv::Point2f(s1_x,s1_y); + facets3D[i][j] = cv::Point2f(s1_x, s1_y); - point2D = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(s1_x,s1_y,0)); - circleEnd = QPointF(point2D.x,point2D.y); + point2D = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(s1_x, s1_y, 0)); + circleEnd = QPointF(point2D.x, point2D.y); - ifacet2D.push_back(QPointF(center2D.x,center2D.y)); - ifacet2D.push_back(QPointF(point2D.x,point2D.y)); + ifacet2D.push_back(QPointF(center2D.x, center2D.y)); + ifacet2D.push_back(QPointF(point2D.x, point2D.y)); debout << "End point: (" << s1_x << ", " << s1_y << ")" << std::endl; - }else + } + else { // start punkt berechnen - m = (facets3D.at(i).at(j).y - facets3D.at(i).at((j-1)%facets3D.at(i).size()).y) / - (facets3D.at(i).at(j).x - facets3D.at(i).at((j-1)%facets3D.at(i).size()).x); + m = (facets3D.at(i).at(j).y - facets3D.at(i).at((j - 1) % facets3D.at(i).size()).y) / + (facets3D.at(i).at(j).x - facets3D.at(i).at((j - 1) % facets3D.at(i).size()).x); n = facets3D.at(i).at(j).y - m * facets3D.at(i).at(j).x; - float p = -( (m*n - m*centers3D.at(i).y - centers3D.at(i).x)/(1+pow(m,2)) ); - float q = sqrt((pow(r,2)-pow(centers3D.at(i).x,2)-pow(centers3D.at(i).y,2)-pow(n,2)-2*n*centers3D.at(i).y) / (1+pow(m,2)) + - pow((m*n-m*centers3D.at(i).y-centers3D.at(i).x)/(1+pow(m,2)),2)); + float p = -((m * n - m * centers3D.at(i).y - centers3D.at(i).x) / (1 + pow(m, 2))); + float q = sqrt( + (pow(r, 2) - pow(centers3D.at(i).x, 2) - pow(centers3D.at(i).y, 2) - pow(n, 2) - + 2 * n * centers3D.at(i).y) / + (1 + pow(m, 2)) + + pow((m * n - m * centers3D.at(i).y - centers3D.at(i).x) / (1 + pow(m, 2)), 2)); // Schnittpunkte mit Kreis s1_x = p + q; - s1_y = m*s1_x+n; + s1_y = m * s1_x + n; s2_x = p - q; - s2_y = m*s2_x+n; + s2_y = m * s2_x + n; - debout << "x=" << s1_x << " G(x)=" << (m*s1_x+n) << " K(x)=" << pow(s1_x-centers3D.at(i).x,2)+pow(s1_y-centers3D.at(i).y,2) << " = " << pow(r,2) << std::endl; - debout << "x=" << s2_x << " G(x)=" << (m*s2_x+n) << " K(x)=" << pow(s2_x-centers3D.at(i).x,2)+pow(s2_y-centers3D.at(i).y,2) << " = " << pow(r,2) << std::endl; + debout << "x=" << s1_x << " G(x)=" << (m * s1_x + n) + << " K(x)=" << pow(s1_x - centers3D.at(i).x, 2) + pow(s1_y - centers3D.at(i).y, 2) + << " = " << pow(r, 2) << std::endl; + debout << "x=" << s2_x << " G(x)=" << (m * s2_x + n) + << " K(x)=" << pow(s2_x - centers3D.at(i).x, 2) + pow(s2_y - centers3D.at(i).y, 2) + << " = " << pow(r, 2) << std::endl; - facets3D[i][j] = cv::Point2f(s1_x,s1_y); + facets3D[i][j] = cv::Point2f(s1_x, s1_y); - point2D = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(s1_x,s1_y,0)); - ifacet2D.push_back(QPointF(point2D.x,point2D.y)); - circleStart = QPointF(point2D.x,point2D.y); + point2D = mMainWindow->getExtrCalibration()->getImagePoint(cv::Point3f(s1_x, s1_y, 0)); + ifacet2D.push_back(QPointF(point2D.x, point2D.y)); + circleStart = QPointF(point2D.x, point2D.y); circleStarted = true; debout << "Start point: (" << s1_x << ", " << s1_y << ")" << std::endl; } - - }else + } + else { - ifacet2D.push_back(QPointF(point2D.x,point2D.y)); - area += (facets3D.at(i).at(j).x*facets3D.at(i).at((j+1)%facets3D[i].size()).y); - area -= (facets3D.at(i).at((j+1)%facets3D[i].size()).x*facets3D.at(i).at(j).y); + ifacet2D.push_back(QPointF(point2D.x, point2D.y)); + area += (facets3D.at(i).at(j).x * facets3D.at(i).at((j + 1) % facets3D[i].size()).y); + area -= (facets3D.at(i).at((j + 1) % facets3D[i].size()).x * facets3D.at(i).at(j).y); } } area *= 0.5; - area = 1.0/area; + area = 1.0 / area; area *= 10000; QColor color; - color.setHsv((255-area*25.5)<0?0:(255-area*25.5),255,255,128); + color.setHsv((255 - area * 25.5) < 0 ? 0 : (255 - area * 25.5), 255, 255, 128); QVector<QPointF> ifacet_vec; - for(size_t i=0; i<ifacet2D.size(); i++) + for(size_t i = 0; i < ifacet2D.size(); i++) { ifacet_vec.append(ifacet2D.at(i)); } painter->setBrush(color); painter->setPen(Qt::black); - if( ifacet2D.size() == 0 ) - painter->drawEllipse(QPointF(center2D.x,center2D.y),100,100); + if(ifacet2D.size() == 0) + painter->drawEllipse(QPointF(center2D.x, center2D.y), 100, 100); painter->drawConvexPolygon(QPolygonF(ifacet_vec)); // voronoi cell point painter->setBrush(Qt::black); painter->setPen(Qt::red); - painter->drawEllipse(QPointF(center2D.x,center2D.y),5,5); + painter->drawEllipse(QPointF(center2D.x, center2D.y), 5, 5); } } } diff --git a/src/trackerReal.cpp b/src/trackerReal.cpp index 3fda3240cc5260fad3153d19fa45bb61eac47dfb..da27682f42406d25a8b7662e261794b44896293a 100644 --- a/src/trackerReal.cpp +++ b/src/trackerReal.cpp @@ -19,59 +19,53 @@ */ #include "trackerReal.h" + #include "helper.h" #include "recognition.h" -TrackPointReal::TrackPointReal(const Vec3F &p, int frameNum) - : Vec3F(p), mFrameNum(frameNum) +TrackPointReal::TrackPointReal(const Vec3F &p, int frameNum) : Vec3F(p), mFrameNum(frameNum) { mAngleOfView = -1; - mMarkerID = -1; + mMarkerID = -1; } -TrackPointReal::TrackPointReal(const Vec3F &p, int frameNum, const Vec2F &d) - : Vec3F(p), mFrameNum(frameNum), mViewDir(d) +TrackPointReal::TrackPointReal(const Vec3F &p, int frameNum, const Vec2F &d) : + Vec3F(p), mFrameNum(frameNum), mViewDir(d) { mAngleOfView = -1; - mMarkerID = -1; + mMarkerID = -1; } //-------------------------------------------------------------------------- // the list index is the frame number plus mFirstFrame 0..mLastFrame-mFirstFrame // no frame is left blank -TrackPersonReal::TrackPersonReal() - : mHeight(-1.), - mFirstFrame(-1), - mLastFrame(0) -{ -} -TrackPersonReal::TrackPersonReal(int frame, const TrackPointReal &p) - : mHeight(-1.), - mFirstFrame(frame), - mLastFrame(frame) +TrackPersonReal::TrackPersonReal() : mHeight(-1.), mFirstFrame(-1), mLastFrame(0) {} +TrackPersonReal::TrackPersonReal(int frame, const TrackPointReal &p) : + mHeight(-1.), mFirstFrame(frame), mLastFrame(frame) { append(p); } bool TrackPersonReal::trackPointExist(int frame) const { - if (frame >= mFirstFrame && frame <= mLastFrame) + if(frame >= mFirstFrame && frame <= mLastFrame) return true; else return false; } -const TrackPointReal& TrackPersonReal::trackPointAt(int frame) const // & macht bei else probleme, sonst mit [] zugreifbar +const TrackPointReal & +TrackPersonReal::trackPointAt(int frame) const // & macht bei else probleme, sonst mit [] zugreifbar { - return at(frame-mFirstFrame); + return at(frame - mFirstFrame); } // gibt -1 zurueck, wenn frame oder naechster frame nicht existiert // entfernung ist absolut double TrackPersonReal::distanceToNextFrame(int frame) const { - if (frame >= mFirstFrame && frame+1 <= mLastFrame) - return at(frame-mFirstFrame).distanceToPoint(at(frame-mFirstFrame+1)); + if(frame >= mFirstFrame && frame + 1 <= mLastFrame) + return at(frame - mFirstFrame).distanceToPoint(at(frame - mFirstFrame + 1)); else return -1; } @@ -79,23 +73,23 @@ void TrackPersonReal::init(int firstFrame, double height, int markerID) { clear(); mFirstFrame = firstFrame; - mLastFrame = firstFrame-1; - mHeight = height; - mMarkerID = markerID; + mLastFrame = firstFrame - 1; + mHeight = height; + mMarkerID = markerID; } -void TrackPersonReal::addEnd(const QPointF& pos, int frame) +void TrackPersonReal::addEnd(const QPointF &pos, int frame) { Vec3F point(pos.x(), pos.y(), -1.); addEnd(point, frame); } -void TrackPersonReal::addEnd(const Vec3F& pos, int frame) +void TrackPersonReal::addEnd(const Vec3F &pos, int frame) { ++mLastFrame; append(TrackPointReal(pos, frame)); } -void TrackPersonReal::addEnd(const QPointF& pos, int frame, const QPointF& dir) +void TrackPersonReal::addEnd(const QPointF &pos, int frame, const QPointF &dir) { Vec3F point(pos.x(), pos.y(), -1.); Vec2F viewDirection(dir.x(), dir.y()); @@ -106,341 +100,431 @@ void TrackPersonReal::addEnd(const QPointF& pos, int frame, const QPointF& dir) //------------------------------------------------------------------------------------------------------------------------------------- -TrackerReal::TrackerReal(QWidget *wParent) - : mXMin(100000.), mXMax(-100000.), mYMin(100000.), mYMax(-100000.) +TrackerReal::TrackerReal(QWidget *wParent) : mXMin(100000.), mXMax(-100000.), mYMin(100000.), mYMax(-100000.) { - mMainWindow = (class Petrack*) wParent; + mMainWindow = (class Petrack *) wParent; } // default: int imageBorderSize = 0, bool missingFramesInserted = true, bool useTrackpoints = false -int TrackerReal::calculate(Tracker *tracker, ImageItem *imageItem, ColorPlot *colorPlot, int imageBorderSize, bool missingFramesInserted, - bool useTrackpoints, bool alternateHeight, double altitude, bool useCalibrationCenter, - bool exportElimTp, bool exportElimTrj, bool exportSmooth, - bool exportViewingDirection, bool exportAngleOfView, bool exportMarkerID, bool exportAutoCorrect) +int TrackerReal::calculate( + Tracker * tracker, + ImageItem *imageItem, + ColorPlot *colorPlot, + int imageBorderSize, + bool missingFramesInserted, + bool useTrackpoints, + bool alternateHeight, + double altitude, + bool useCalibrationCenter, + bool exportElimTp, + bool exportElimTrj, + bool exportSmooth, + bool exportViewingDirection, + bool exportAngleOfView, + bool exportMarkerID, + bool exportAutoCorrect) { - if (tracker || imageItem || colorPlot) + if(tracker || imageItem || colorPlot) { - if (size() > 0) + if(size() > 0) { clear(); } - int i, j, f; - QList<int> missingList; // frame nr wo ausgelassen; passend dazu: + int i, j, f; + QList<int> missingList; // frame nr wo ausgelassen; passend dazu: QList<int> missingListAnz; // anzahl ausgelassener frames - if (missingFramesInserted) + if(missingFramesInserted) { // finden von nicht aufgenommenen frames - int largestLastFrame = tracker->largestLastFrame(); - QMap<int, double> distanceMap; // map der distanzen zu frame - QMap<int, double> lastDistanceMap; // map der distanzen zu frame + int largestLastFrame = tracker->largestLastFrame(); + QMap<int, double> distanceMap; // map der distanzen zu frame + QMap<int, double> lastDistanceMap; // map der distanzen zu frame QMap<int, double>::const_iterator iter; - int anz, skipAnz; - double dist, sum, lastSum=0.; + int anz, skipAnz; + double dist, sum, lastSum = 0.; // (median neben durchschnittswert als bewertungszahl hinzugenommen, // da sonst bei wenigen personen und langsamen bewegungen nur ein kleiner ausreisser // einen frame hinzufuegt (insb linienexperiment mit vielen personen)) - for (f = tracker->smallestFirstFrame(); f <= largestLastFrame; ++f) + for(f = tracker->smallestFirstFrame(); f <= largestLastFrame; ++f) { distanceMap.clear(); skipAnz = anz = 0; - sum = 0.; + sum = 0.; // erzeugen distanz-map im aktuellen frame - for (i = 0; i < tracker->size(); ++i) - if ((dist = tracker->at(i).distanceToNextFrame(f)) > -1) + for(i = 0; i < tracker->size(); ++i) + if((dist = tracker->at(i).distanceToNextFrame(f)) > -1) distanceMap[i] = dist; // distanzliste mit vorherigem frame vergleichen iter = distanceMap.constBegin(); - while (iter != distanceMap.constEnd()) + while(iter != distanceMap.constEnd()) { - if (lastDistanceMap.contains(iter.key()) && - lastDistanceMap[iter.key()] > 1.) // damit bei ganz kleinen bewegungen nicht angeschlagen wird + if(lastDistanceMap.contains(iter.key()) && + lastDistanceMap[iter.key()] > 1.) // damit bei ganz kleinen bewegungen nicht angeschlagen wird { ++anz; - if (distanceMap[iter.key()] > 1.5*lastDistanceMap[iter.key()]) + if(distanceMap[iter.key()] > 1.5 * lastDistanceMap[iter.key()]) ++skipAnz; } sum += distanceMap[iter.key()]; ++iter; } - sum/=distanceMap.size(); + sum /= distanceMap.size(); // bei sprung in mehreren trackingpfaden als sprung markieren - if ((anz > 1) && (skipAnz/(double)anz > .5) && myRound(sum/lastSum - 1.) > 0) // 50% (war (anz > 2)) + if((anz > 1) && (skipAnz / (double) anz > .5) && myRound(sum / lastSum - 1.) > 0) // 50% (war (anz > 2)) { missingList.append(f); - missingListAnz.append(myRound(sum/lastSum - 1.)); - debout << "Warning: potentially missing " << myRound(sum/lastSum - 1.) << " frame(s) between " << f << " and " << f+1 << " will be inserted." << std::endl; + missingListAnz.append(myRound(sum / lastSum - 1.)); + debout << "Warning: potentially missing " << myRound(sum / lastSum - 1.) << " frame(s) between " + << f << " and " << f + 1 << " will be inserted." << std::endl; } lastDistanceMap = distanceMap; - lastSum = sum; + lastSum = sum; } } // fps ist nicht aussagekraeftig, da sie mgl von ausgelassenen herruehren - besser immer 25,01 fps annehmen - double height; // groesse in cm - int firstFrame, addFrames, anz; - Vec2F br(imageBorderSize, imageBorderSize); - QPointF pos, pos2; - QList<int> tmpMissingList; // frame nr - QList<int> tmpMissingListAnz; // anzahl frames + double height; // groesse in cm + int firstFrame, addFrames, anz; + Vec2F br(imageBorderSize, imageBorderSize); + QPointF pos, pos2; + QList<int> tmpMissingList; // frame nr + QList<int> tmpMissingListAnz; // anzahl frames TrackPersonReal trackPersonReal; - QPointF center = imageItem->getPosReal(QPointF(imageItem->boundingRect().width()/2., imageItem->boundingRect().height()/2.), 0.); - Vec3F sp; - int nrFor; - int nrRew; - int tsize; - double zMedian; - int extrapolated; + QPointF center = imageItem->getPosReal( + QPointF(imageItem->boundingRect().width() / 2., imageItem->boundingRect().height() / 2.), 0.); + Vec3F sp; + int nrFor; + int nrRew; + int tsize; + double zMedian; + int extrapolated; QPointF colPos; - float angle; + float angle; - for (i = 0; i < tracker->size(); ++i) // ueber trajektorien + for(i = 0; i < tracker->size(); ++i) // ueber trajektorien { - addFrames = 0; + addFrames = 0; firstFrame = tracker->at(i).firstFrame(); - if ((*tracker)[i].height() < MIN_HEIGHT+1) + if((*tracker)[i].height() < MIN_HEIGHT + 1) height = colorPlot->map((*tracker)[i].color()); else height = (*tracker)[i].height(); //(*tracker)[i].setHeight(height); - if (missingList.size() > 0) + if(missingList.size() > 0) { - tmpMissingList = missingList; + tmpMissingList = missingList; tmpMissingListAnz = missingListAnz; // vorspulen - while ((tmpMissingList.size() > 0) && (tmpMissingList.first() < firstFrame)) + while((tmpMissingList.size() > 0) && (tmpMissingList.first() < firstFrame)) { - tmpMissingList.removeFirst(); // frame + tmpMissingList.removeFirst(); // frame addFrames += tmpMissingListAnz.takeFirst(); // anzahl } } int markerID = (*tracker)[i].getMarkerID(); // set markerID to TrackPerson.markerID - trackPersonReal.init(firstFrame+addFrames, height, markerID); + trackPersonReal.init(firstFrame + addFrames, height, markerID); tsize = tracker->at(i).size(); - for (j = 0; (j < tsize); ++j) // ueber trackpoints + for(j = 0; (j < tsize); ++j) // ueber trackpoints { - // ausreisser ausfindig machen (dies geschieht, bevor -1 elemente herausgenommen werden, um die glaettung beim eliminieren der -1 elemente hier nicht einfluss nehmen zu lassen): - if (exportSmooth && (useTrackpoints || alternateHeight) && (tsize > 1)) // wenn direkt pointgrey hoehe oder eigene hoehenberechnung aber variierend ueber trj genommen werden soll + // ausreisser ausfindig machen (dies geschieht, bevor -1 elemente herausgenommen werden, um die + // glaettung beim eliminieren der -1 elemente hier nicht einfluss nehmen zu lassen): + if(exportSmooth && (useTrackpoints || alternateHeight) && + (tsize > 1)) // wenn direkt pointgrey hoehe oder eigene hoehenberechnung aber variierend ueber trj + // genommen werden soll { - // ACHTUNG: Aenderungen in Originaltrajektorie, so dass aenderungen auf folgeuntersuchungen einfluss haben: j auf j+1 - if ((*tracker)[i][j].sp().z() != -1) + // ACHTUNG: Aenderungen in Originaltrajektorie, so dass aenderungen auf folgeuntersuchungen einfluss + // haben: j auf j+1 + if((*tracker)[i][j].sp().z() != -1) { nrFor = 1; // anzahl der ztrackpoint ohne hoeheninfo nrRew = 1; - while ((j+nrFor < tsize) && ((*tracker)[i].at(j+nrFor).sp().z() < 0)) // nach && wird nur ausgefuehrt, wenn erstes true == size() also nicht + while((j + nrFor < tsize) && + ((*tracker)[i].at(j + nrFor).sp().z() < + 0)) // nach && wird nur ausgefuehrt, wenn erstes true == size() also nicht nrFor++; - while ((j-nrRew >= 0) && ((*tracker)[i].at(j-nrRew).sp().z() < 0)) // nach && wird nur ausgefuehrt, wenn erstes true == size() also nicht + while((j - nrRew >= 0) && + ((*tracker)[i].at(j - nrRew).sp().z() < + 0)) // nach && wird nur ausgefuehrt, wenn erstes true == size() also nicht nrRew++; - if (((j-nrRew >= 0) && (j+nrFor == tsize)) || ((j-nrRew >= 0) && (nrRew < nrFor))) // nur oder eher in Vergangenheit hoeheninfo gefunden + if(((j - nrRew >= 0) && (j + nrFor == tsize)) || + ((j - nrRew >= 0) && (nrRew < nrFor))) // nur oder eher in Vergangenheit hoeheninfo gefunden { - if(fabs((*tracker)[i].at(j-nrRew).sp().z()-(*tracker)[i].at(j).sp().z()) > nrRew*40.) // 40cm + if(fabs((*tracker)[i].at(j - nrRew).sp().z() - (*tracker)[i].at(j).sp().z()) > + nrRew * 40.) // 40cm { - (*tracker)[i][j].setSp((*tracker)[i].at(j).sp().x(),(*tracker)[i].at(j).sp().y(),(*tracker)[i].at(j-nrRew).sp().z()); - debout << "Warning: Trackpoint smoothed height at the end or next to unknown height in the future for trajectory " << i+1 << " in frame " << j+firstFrame << "." << std::endl; + (*tracker)[i][j].setSp( + (*tracker)[i].at(j).sp().x(), + (*tracker)[i].at(j).sp().y(), + (*tracker)[i].at(j - nrRew).sp().z()); + debout << "Warning: Trackpoint smoothed height at the end or next to unknown height in " + "the future for trajectory " + << i + 1 << " in frame " << j + firstFrame << "." << std::endl; } } - else if (((j+nrFor != tsize) && (j-nrRew < 0)) || ((j+nrFor != tsize) && (nrFor < nrRew))) // nur oder eher in der zukunft hoeheninfo gefunden + else if( + ((j + nrFor != tsize) && (j - nrRew < 0)) || + ((j + nrFor != tsize) && + (nrFor < nrRew))) // nur oder eher in der zukunft hoeheninfo gefunden { - if(fabs((*tracker)[i].at(j+nrFor).sp().z()-(*tracker)[i].at(j).sp().z()) > nrFor*40.) // 40cm + if(fabs((*tracker)[i].at(j + nrFor).sp().z() - (*tracker)[i].at(j).sp().z()) > + nrFor * 40.) // 40cm { - (*tracker)[i][j].setSp((*tracker)[i].at(j).sp().x(),(*tracker)[i].at(j).sp().y(),(*tracker)[i].at(j+nrFor).sp().z()); - debout << "Warning: Trackpoint smoothed height at the beginning or next to unknown height in the past for trajectory " << i+1 << " in frame " << j+firstFrame << "." << std::endl; + (*tracker)[i][j].setSp( + (*tracker)[i].at(j).sp().x(), + (*tracker)[i].at(j).sp().y(), + (*tracker)[i].at(j + nrFor).sp().z()); + debout << "Warning: Trackpoint smoothed height at the beginning or next to unknown " + "height in the past for trajectory " + << i + 1 << " in frame " << j + firstFrame << "." << std::endl; } } - else if ((j+nrFor != tsize) && (j-nrRew >= 0))// in beiden richtungen hoeheninfo gefunden und nrFor==nrRew + else if((j + nrFor != tsize) && (j - nrRew >= 0)) // in beiden richtungen hoeheninfo gefunden + // und nrFor==nrRew { - // median genommen um zwei fehlmessungen nebeneinander nicht dazu fuehren zu lassen, dass bessere daten veraendert werden - zMedian = getMedianOf3((*tracker)[i].at(j).sp().z(), (*tracker)[i].at(j-nrRew).sp().z(), (*tracker)[i].at(j+nrFor).sp().z()); + // median genommen um zwei fehlmessungen nebeneinander nicht dazu fuehren zu lassen, dass + // bessere daten veraendert werden + zMedian = getMedianOf3( + (*tracker)[i].at(j).sp().z(), + (*tracker)[i].at(j - nrRew).sp().z(), + (*tracker)[i].at(j + nrFor).sp().z()); // lineare interpolation - if(fabs(zMedian-(*tracker)[i].at(j).sp().z()) > 20.*(nrFor+nrRew)) // 20cm + if(fabs(zMedian - (*tracker)[i].at(j).sp().z()) > 20. * (nrFor + nrRew)) // 20cm { - (*tracker)[i][j].setSp((*tracker)[i].at(j).sp().x(),(*tracker)[i].at(j).sp().y(),zMedian); - debout << "Warning: Trackpoint smoothed height inside for trajectory " << i+1 << " in frame " << j+firstFrame << "." << std::endl; + (*tracker)[i][j].setSp( + (*tracker)[i].at(j).sp().x(), (*tracker)[i].at(j).sp().y(), zMedian); + debout << "Warning: Trackpoint smoothed height inside for trajectory " << i + 1 + << " in frame " << j + firstFrame << "." << std::endl; } } } } - if (useTrackpoints) + if(useTrackpoints) { // border unberuecksichtigt - if (useCalibrationCenter) - trackPersonReal.addEnd(Vec3F((*tracker)[i][j].sp().x()+center.x(), center.y()-(*tracker)[i][j].sp().y(), altitude-(*tracker)[i][j].sp().z()), firstFrame+j); + if(useCalibrationCenter) + trackPersonReal.addEnd( + Vec3F( + (*tracker)[i][j].sp().x() + center.x(), + center.y() - (*tracker)[i][j].sp().y(), + altitude - (*tracker)[i][j].sp().z()), + firstFrame + j); else - trackPersonReal.addEnd((*tracker)[i][j].sp(), firstFrame+j); + trackPersonReal.addEnd((*tracker)[i][j].sp(), firstFrame + j); } else { - if (alternateHeight) // personenhoehe variiert ueber trajektorie (unebene versuche); berechnung durch mich und nicht pointgrey nutzen, Kamera altitude nutzen + if(alternateHeight) // personenhoehe variiert ueber trajektorie (unebene versuche); berechnung durch + // mich und nicht pointgrey nutzen, Kamera altitude nutzen { extrapolated = 0; // 0 == false - double bestZ = (*tracker)[i].getNearestZ(j, &extrapolated); // gibt z wert zurueck bzw wenn -1, dann den neben diesem frame ersten z-wert ungleich -1 - if (bestZ < 0) // == -1 // es liegt gar keine berechnete hoehe vor + double bestZ = + (*tracker)[i].getNearestZ(j, &extrapolated); // gibt z wert zurueck bzw wenn -1, dann den + // neben diesem frame ersten z-wert ungleich -1 + if(bestZ < 0) // == -1 // es liegt gar keine berechnete hoehe vor { - if (exportElimTrj) + if(exportElimTrj) { - debout << "Warning: no calculated height for trackpoint " << j << " (frame " << tracker->at(i).firstFrame()+j<< ") of person " << i+1 << ", person is not exported!" << std::endl; - break; // TrackPerson ist angelegt, erhaelt aber keine Points und wird deshalb am ende nicht eingefuegt + debout << "Warning: no calculated height for trackpoint " << j << " (frame " + << tracker->at(i).firstFrame() + j << ") of person " << i + 1 + << ", person is not exported!" << std::endl; + break; // TrackPerson ist angelegt, erhaelt aber keine Points und wird deshalb am ende + // nicht eingefuegt } else { - bestZ = height; // wenn gar kein trackpoint ungleich -1 gefunden wird, dann wird zu allerletzt Hoehe genommen - debout << "Warning: no calculated height for trackpoint " << j << " (frame " << tracker->at(i).firstFrame()+j<< ") of person " << i+1 << ", default height is used!" << std::endl; + bestZ = height; // wenn gar kein trackpoint ungleich -1 gefunden wird, dann wird zu + // allerletzt Hoehe genommen + debout << "Warning: no calculated height for trackpoint " << j << " (frame " + << tracker->at(i).firstFrame() + j << ") of person " << i + 1 + << ", default height is used!" << std::endl; } } else - bestZ = altitude-bestZ; + bestZ = altitude - bestZ; // ab hier kann bestZ auch negativ sein, obwohl hoehe inhalt hatte - if (extrapolated && exportElimTp) + if(extrapolated && exportElimTp) { - if (extrapolated == 1) // zu beginn verworfen - trackPersonReal.setFirstFrame(trackPersonReal.firstFrame()+1); - debout << "Warning: no calculated height for trackpoint " << j << " (frame " << tracker->at(i).firstFrame()+j<< ") of person " << i+1 << ", extrapolated height not used, trackpoint not inserted!" << std::endl; + if(extrapolated == 1) // zu beginn verworfen + trackPersonReal.setFirstFrame(trackPersonReal.firstFrame() + 1); + debout << "Warning: no calculated height for trackpoint " << j << " (frame " + << tracker->at(i).firstFrame() + j << ") of person " << i + 1 + << ", extrapolated height not used, trackpoint not inserted!" << std::endl; } else { - if (extrapolated) - debout << "Warning: no calculated height for trackpoint " << j << " (frame " << tracker->at(i).firstFrame()+j<< ") of person " << i+1 << ", extrapolated height is used!" << std::endl; + if(extrapolated) + debout << "Warning: no calculated height for trackpoint " << j << " (frame " + << tracker->at(i).firstFrame() + j << ") of person " << i + 1 + << ", extrapolated height is used!" << std::endl; - Vec2F moveDir(0,0); - if (exportAutoCorrect) - moveDir += reco::autoCorrectColorMarker((*tracker)[i][j], mMainWindow->getControlWidget()); + Vec2F moveDir(0, 0); + if(exportAutoCorrect) + moveDir += + reco::autoCorrectColorMarker((*tracker)[i][j], mMainWindow->getControlWidget()); - pos = imageItem->getPosReal(((*tracker)[i][j]+moveDir+br).toQPointF(), bestZ); + pos = imageItem->getPosReal(((*tracker)[i][j] + moveDir + br).toQPointF(), bestZ); - if ((exportViewingDirection) && ((*tracker)[i][j].color().isValid())) // wenn blickrichtung mit ausgegeben werden soll + if((exportViewingDirection) && + ((*tracker)[i][j].color().isValid())) // wenn blickrichtung mit ausgegeben werden soll { - colPos = imageItem->getPosReal(((*tracker)[i][j].colPoint()+moveDir+br).toQPointF(), bestZ); - trackPersonReal.addEnd(pos, firstFrame+j, colPos-pos); + colPos = imageItem->getPosReal( + ((*tracker)[i][j].colPoint() + moveDir + br).toQPointF(), bestZ); + trackPersonReal.addEnd(pos, firstFrame + j, colPos - pos); } else - trackPersonReal.addEnd(Vec3F(pos.x(), pos.y(), bestZ), firstFrame+j); + trackPersonReal.addEnd(Vec3F(pos.x(), pos.y(), bestZ), firstFrame + j); } } else { - Vec2F moveDir(0,0); - if (exportAutoCorrect) + Vec2F moveDir(0, 0); + if(exportAutoCorrect) moveDir += reco::autoCorrectColorMarker((*tracker)[i][j], mMainWindow->getControlWidget()); - pos = imageItem->getPosReal(((*tracker)[i][j]+moveDir+br).toQPointF(), height); + pos = imageItem->getPosReal(((*tracker)[i][j] + moveDir + br).toQPointF(), height); // die frame nummer der animation wird TrackPoint der PersonReal mitgegeben, - // da Index groesser sein kann, da vorher frames hinzugefuegt wurden duch trackPersonReal.init(firstFrame+addFrames, height) - // oder aber innerhalb des trackink path mit for schleife ueber f - if ((exportViewingDirection) && ((*tracker)[i][j].color().isValid())) // wenn blickrichtung mit ausgegeben werden soll + // da Index groesser sein kann, da vorher frames hinzugefuegt wurden duch + // trackPersonReal.init(firstFrame+addFrames, height) oder aber innerhalb des trackink path mit + // for schleife ueber f + if((exportViewingDirection) && + ((*tracker)[i][j].color().isValid())) // wenn blickrichtung mit ausgegeben werden soll { - colPos = imageItem->getPosReal(((*tracker)[i][j].colPoint()+moveDir+br).toQPointF(), height); - trackPersonReal.addEnd(pos, firstFrame+j, colPos-pos); + colPos = + imageItem->getPosReal(((*tracker)[i][j].colPoint() + moveDir + br).toQPointF(), height); + trackPersonReal.addEnd(pos, firstFrame + j, colPos - pos); } else - trackPersonReal.addEnd(pos, firstFrame+j); - if (exportAngleOfView) + trackPersonReal.addEnd(pos, firstFrame + j); + if(exportAngleOfView) { - angle = (90.-imageItem->getAngleToGround(((*tracker)[i][j]+br).x(), ((*tracker)[i][j]+br).y(), height))*PI/180.; + angle = (90. - imageItem->getAngleToGround( + ((*tracker)[i][j] + br).x(), ((*tracker)[i][j] + br).y(), height)) * + PI / 180.; trackPersonReal.last().setAngleOfView(angle); } - if (exportMarkerID) + if(exportMarkerID) { trackPersonReal.last().setMarkerID((*tracker)[i][j].getMarkerID()); } } } - if (tmpMissingList.size() > 0) + if(tmpMissingList.size() > 0) { - if ((tmpMissingList.first() == firstFrame+j) && (tracker->at(i).trackPointExist(firstFrame+j+1))) + if((tmpMissingList.first() == firstFrame + j) && + (tracker->at(i).trackPointExist(firstFrame + j + 1))) { - tmpMissingList.removeFirst(); // frame + tmpMissingList.removeFirst(); // frame anz = tmpMissingListAnz.takeFirst(); // anzahl - if (useTrackpoints) + if(useTrackpoints) { // border unberuecksichtigt - for (f = 1; f <= anz; ++f) + for(f = 1; f <= anz; ++f) { - sp = (*tracker)[i][j].sp()+f*((*tracker)[i][j+1].sp()-(*tracker)[i][j].sp())/(anz+1); - if (useCalibrationCenter) - trackPersonReal.addEnd(Vec3F(sp.x()+center.x(), center.y()-sp.y(), altitude-sp.z()), firstFrame+j); + sp = (*tracker)[i][j].sp() + + f * ((*tracker)[i][j + 1].sp() - (*tracker)[i][j].sp()) / (anz + 1); + if(useCalibrationCenter) + trackPersonReal.addEnd( + Vec3F(sp.x() + center.x(), center.y() - sp.y(), altitude - sp.z()), + firstFrame + j); else trackPersonReal.addEnd(sp, -1); // -1 zeigt an, dass nur interpoliert } } else { - if (alternateHeight) // personenhoehe variiert ueber trajektorie (unebene versuche); berechnung durch mich und nicht pointgrey nutzen + if(alternateHeight) // personenhoehe variiert ueber trajektorie (unebene versuche); + // berechnung durch mich und nicht pointgrey nutzen { - debout << "Warning: No interpolation is done, because alternate height is enabled - has to be implemented!" << std::endl; + debout << "Warning: No interpolation is done, because alternate height is enabled - " + "has to be implemented!" + << std::endl; } else { - Vec2F moveDir(0,0); - if (exportAutoCorrect) - moveDir += reco::autoCorrectColorMarker((*tracker)[i][j], mMainWindow->getControlWidget()); - - pos2 = (imageItem->getPosReal(((*tracker)[i][j+1]+moveDir+br).toQPointF(), height) - pos)/(anz+1); - for (f = 1; f <= anz; ++f) - trackPersonReal.addEnd(pos+f*pos2, -1); // -1 zeigt an, dass nur interpoliert + Vec2F moveDir(0, 0); + if(exportAutoCorrect) + moveDir += + reco::autoCorrectColorMarker((*tracker)[i][j], mMainWindow->getControlWidget()); + + pos2 = + (imageItem->getPosReal(((*tracker)[i][j + 1] + moveDir + br).toQPointF(), height) - + pos) / + (anz + 1); + for(f = 1; f <= anz; ++f) + trackPersonReal.addEnd(pos + f * pos2, -1); // -1 zeigt an, dass nur interpoliert } } - } - else if (tmpMissingList.first() < firstFrame) // while, wenn nicht kontinuierlich waere + } + else if(tmpMissingList.first() < firstFrame) // while, wenn nicht kontinuierlich waere { - tmpMissingList.removeFirst(); // frame + tmpMissingList.removeFirst(); // frame tmpMissingListAnz.removeFirst(); // anzahl } } } - tsize = trackPersonReal.size(); - double maxHeightDiff = 30.;// 30cm - int numBorderPoints = 50; - int k; - int delNumFront = 0; - // die ersten und letzten numBorderPoints trackpoints untersuchen, ob die hoehe einen sprung groesser maxHeightDiff aufweist - for (j = 1; j < tsize; ++j) // ueber trackpoints of personreal; ab 1, da vergleich zu vorherigem + tsize = trackPersonReal.size(); + double maxHeightDiff = 30.; // 30cm + int numBorderPoints = 50; + int k; + int delNumFront = 0; + // die ersten und letzten numBorderPoints trackpoints untersuchen, ob die hoehe einen sprung groesser + // maxHeightDiff aufweist + for(j = 1; j < tsize; ++j) // ueber trackpoints of personreal; ab 1, da vergleich zu vorherigem { - if ((j < numBorderPoints) && ((trackPersonReal.at(j).z()-trackPersonReal.at(j-1).z()) > maxHeightDiff)) + if((j < numBorderPoints) && + ((trackPersonReal.at(j).z() - trackPersonReal.at(j - 1).z()) > maxHeightDiff)) { delNumFront = j; } - else if (((tsize - numBorderPoints) < j) && ((trackPersonReal.at(j).z()-trackPersonReal.at(j-1).z()) > maxHeightDiff)) + else if( + ((tsize - numBorderPoints) < j) && + ((trackPersonReal.at(j).z() - trackPersonReal.at(j - 1).z()) > maxHeightDiff)) { - for (k = j; k < tsize; k++) + for(k = j; k < tsize; k++) { - trackPersonReal.setLastFrame(trackPersonReal.lastFrame()-1); + trackPersonReal.setLastFrame(trackPersonReal.lastFrame() - 1); trackPersonReal.removeLast(); } - debout << "Warning: delete last " << tsize-j << " frames of person " << i+1 << " because of height jump!" << std::endl; + debout << "Warning: delete last " << tsize - j << " frames of person " << i + 1 + << " because of height jump!" << std::endl; break; } } tsize = trackPersonReal.size(); - if (delNumFront > 0) + if(delNumFront > 0) { - debout << "Warning: delete first " << delNumFront << " frames of person " << i+1 << " because of height jump!" << std::endl; - for (k = 0; (k < delNumFront) && (k < tsize); k++) + debout << "Warning: delete first " << delNumFront << " frames of person " << i + 1 + << " because of height jump!" << std::endl; + for(k = 0; (k < delNumFront) && (k < tsize); k++) { - trackPersonReal.setFirstFrame(trackPersonReal.firstFrame()+1); + trackPersonReal.setFirstFrame(trackPersonReal.firstFrame() + 1); trackPersonReal.removeFirst(); } } - if (trackPersonReal.size() < 20) - debout << "Warning: Person " << i+1 << " has only " << trackPersonReal.size() << " trackpoints!" << std::endl; - if (trackPersonReal.size() > 0) + if(trackPersonReal.size() < 20) + debout << "Warning: Person " << i + 1 << " has only " << trackPersonReal.size() << " trackpoints!" + << std::endl; + if(trackPersonReal.size() > 0) append(trackPersonReal); else // ggf weil keine calculated height vorlag (siehe exportElimTrj) - debout << "Warning: Person " << i+1 << " is not inserted, because of no trackpoints!" << std::endl; - + debout << "Warning: Person " << i + 1 << " is not inserted, because of no trackpoints!" << std::endl; } return size(); } else { - debout << "Warning: no real tracking data calculated, because of missing tracking data, image reference or color map!" << std::endl; + debout << "Warning: no real tracking data calculated, because of missing tracking data, image reference or " + "color map!" + << std::endl; return -1; } } @@ -448,17 +532,17 @@ int TrackerReal::calculate(Tracker *tracker, ImageItem *imageItem, ColorPlot *co void TrackerReal::calcMinMax() { Vec3F pos; - for (int i = 0; i < size(); ++i) - for (int j = 0; j < at(i).size(); ++j) + for(int i = 0; i < size(); ++i) + for(int j = 0; j < at(i).size(); ++j) { pos = at(i).at(j); - if (mXMin > pos.x()) + if(mXMin > pos.x()) mXMin = pos.x(); - else if (mXMax < pos.x()) + else if(mXMax < pos.x()) mXMax = pos.x(); - if (mYMin > pos.y()) + if(mYMin > pos.y()) mYMin = pos.y(); - else if (mYMax < pos.y()) + else if(mYMax < pos.y()) mYMax = pos.y(); } } @@ -466,9 +550,9 @@ void TrackerReal::calcMinMax() int TrackerReal::largestFirstFrame() { int max = -1, i; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if (at(i).firstFrame() > max) + if(at(i).firstFrame() > max) max = at(i).firstFrame(); } return max; @@ -476,62 +560,69 @@ int TrackerReal::largestFirstFrame() int TrackerReal::largestLastFrame() { int max = -1, i; - for (i = 0; i < size(); ++i) + for(i = 0; i < size(); ++i) { - if (at(i).lastFrame() > max) + if(at(i).lastFrame() > max) max = at(i).lastFrame(); } return max; } int TrackerReal::smallestFirstFrame() { - int i, min = ((size()>0) ? at(0).firstFrame() : -1); - for (i = 1; i < size(); ++i) + int i, min = ((size() > 0) ? at(0).firstFrame() : -1); + for(i = 1; i < size(); ++i) { - if (at(i).firstFrame() < min) + if(at(i).firstFrame() < min) min = at(i).firstFrame(); } return min; } int TrackerReal::smallestLastFrame() { - int i, min = ((size()>0) ? at(0).lastFrame() : -1); - for (i = 1; i < size(); ++i) + int i, min = ((size() > 0) ? at(0).lastFrame() : -1); + for(i = 1; i < size(); ++i) { - if (at(i).lastFrame() < min) + if(at(i).lastFrame() < min) min = at(i).lastFrame(); } return min; } -void TrackerReal::exportTxt(QTextStream &out, bool alternateHeight, bool useTrackpoints, bool exportViewingDirection, bool exportAngleOfView, bool exportUseM, bool exportMarkerID) +void TrackerReal::exportTxt( + QTextStream &out, + bool alternateHeight, + bool useTrackpoints, + bool exportViewingDirection, + bool exportAngleOfView, + bool exportUseM, + bool exportMarkerID) { float scale; out << "# z: can be 3d position or height of person (alternating or not)" << Qt::endl; - if (exportViewingDirection) + if(exportViewingDirection) out << "# viewDirX viewDirY: vector of direction of head of person" << Qt::endl; - if (exportAngleOfView) + if(exportAngleOfView) out << "# viewAngle: angle of view of camera to person from perpendicular [0..Pi/2]" << Qt::endl; - if (exportUseM) + if(exportUseM) out << "# id frame x/m y/m z/m"; else out << "# id frame x/cm y/cm z/cm"; - if (exportViewingDirection) + if(exportViewingDirection) out << " viewDirX viewDirY"; - if (exportAngleOfView) + if(exportAngleOfView) out << " viewAngle" << Qt::endl; - if (exportMarkerID) + if(exportMarkerID) out << " markerID" << Qt::endl; else out << Qt::endl; - if (exportUseM) + if(exportUseM) scale = .01f; else scale = 1.f; - QProgressDialog progress("Export TXT-File",nullptr,0,size(),mMainWindow->window()); + QProgressDialog progress("Export TXT-File", nullptr, 0, size(), mMainWindow->window()); progress.setWindowTitle("Export .txt-File"); progress.setWindowModality(Qt::WindowModal); progress.setVisible(true); @@ -539,28 +630,30 @@ void TrackerReal::exportTxt(QTextStream &out, bool alternateHeight, bool useTrac progress.setLabelText(QString("Export tracking data ...")); qApp->processEvents(); - for (int i = 0; i < size(); ++i){ - + for(int i = 0; i < size(); ++i) + { qApp->processEvents(); - progress.setLabelText(QString("Export person %1 of %2 ...").arg(i+1).arg(size())); - progress.setValue(i+1); + progress.setLabelText(QString("Export person %1 of %2 ...").arg(i + 1).arg(size())); + progress.setValue(i + 1); - for (int j = 0; j < at(i).size(); ++j) + for(int j = 0; j < at(i).size(); ++j) { - out << i+1 << " " << at(i).firstFrame()+j << " " << at(i).at(j).x()*scale << " " << at(i).at(j).y()*scale << " "; + out << i + 1 << " " << at(i).firstFrame() + j << " " << at(i).at(j).x() * scale << " " + << at(i).at(j).y() * scale << " "; - if (alternateHeight || useTrackpoints) - out << at(i).at(j).z()*scale; + if(alternateHeight || useTrackpoints) + out << at(i).at(j).z() * scale; else - out << at(i).height()*scale; + out << at(i).height() * scale; - if (exportViewingDirection) // && (at(i).at(j).viewDir() != Vec2F(0,0)) zeigt an, dass keine richtung berechnet werden konnte + if(exportViewingDirection) // && (at(i).at(j).viewDir() != Vec2F(0,0)) zeigt an, dass keine richtung + // berechnet werden konnte out << " " << at(i).at(j).viewDir(); - if (exportAngleOfView) + if(exportAngleOfView) out << " " << at(i).at(j).angleOfView() << Qt::endl; - if (exportMarkerID) + if(exportMarkerID) out << " " << at(i).getMarkerID() << Qt::endl; else out << Qt::endl; @@ -571,43 +664,46 @@ void TrackerReal::exportTxt(QTextStream &out, bool alternateHeight, bool useTrac // old - not all export options supported!!!! void TrackerReal::exportDat(QTextStream &out, bool alternateHeight, bool useTrackpoints) // fuer gnuplot { - QProgressDialog progress("Export DAT-File",nullptr,0,size(),mMainWindow->window()); + QProgressDialog progress("Export DAT-File", nullptr, 0, size(), mMainWindow->window()); progress.setWindowTitle("Export .dat-File"); progress.setWindowModality(Qt::WindowModal); progress.setVisible(true); progress.setValue(0); progress.setLabelText(QString("Export tracking data ...")); debout << "size:" << size() << std::endl; - if (useTrackpoints) + if(useTrackpoints) { - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) { - progress.setLabelText(QString("Export person %1 of %2 ...").arg(i+1).arg(size())); + progress.setLabelText(QString("Export person %1 of %2 ...").arg(i + 1).arg(size())); qApp->processEvents(); - progress.setValue(i+1); + progress.setValue(i + 1); - for (int j = 0; j < at(i).size(); ++j) + for(int j = 0; j < at(i).size(); ++j) // Umrechnung in coordSystem fehlt, auch camera altitude unberuecksichtigt!!! - out << at(i).firstFrame()+j << " " << at(i).at(j) << " " << at(i).at(j).z() << Qt::endl; // z Koordinate ist Kopf + out << at(i).firstFrame() + j << " " << at(i).at(j) << " " << at(i).at(j).z() + << Qt::endl; // z Koordinate ist Kopf out << Qt::endl; } } else { - for (int i = 0; i < size(); ++i) + for(int i = 0; i < size(); ++i) { - progress.setLabelText(QString("Export person %1 of %2 ...").arg(i+1).arg(size())); + progress.setLabelText(QString("Export person %1 of %2 ...").arg(i + 1).arg(size())); qApp->processEvents(); - progress.setValue(i+1); + progress.setValue(i + 1); debout << "person: " << i << std::endl; - for (int j = 0; j < at(i).size(); ++j) + for(int j = 0; j < at(i).size(); ++j) { - if (alternateHeight) - out << at(i).firstFrame()+j << " " << at(i).at(j) << " " << at(i).at(j).z() << Qt::endl; // z Koordinate ist Kopf + if(alternateHeight) + out << at(i).firstFrame() + j << " " << at(i).at(j) << " " << at(i).at(j).z() + << Qt::endl; // z Koordinate ist Kopf else - out << at(i).firstFrame()+j << " " << at(i).at(j) << " " << at(i).height() << Qt::endl; // z Koordinate ist Kopf - } + out << at(i).firstFrame() + j << " " << at(i).at(j) << " " << at(i).height() + << Qt::endl; // z Koordinate ist Kopf + } out << Qt::endl; } } @@ -615,11 +711,11 @@ void TrackerReal::exportDat(QTextStream &out, bool alternateHeight, bool useTrac void TrackerReal::exportXml(QTextStream &outXml, bool alternateHeight, bool useTrackpoints) { - int i, j, largestLastFr = largestLastFrame(); + int i, j, largestLastFr = largestLastFrame(); double z; - int defaultPersonHeight = 176; + int defaultPersonHeight = 176; - QProgressDialog progress("Export XML-File",nullptr,0,largestLastFr,mMainWindow->window()); + QProgressDialog progress("Export XML-File", nullptr, 0, largestLastFr, mMainWindow->window()); progress.setWindowTitle("Export .xml-File"); progress.setWindowModality(Qt::WindowModal); progress.setVisible(true); @@ -628,41 +724,49 @@ void TrackerReal::exportXml(QTextStream &outXml, bool alternateHeight, bool useT qApp->processEvents(); outXml << " <shape>" << Qt::endl; - for (j = 0; j < size(); ++j) + for(j = 0; j < size(); ++j) { - if (alternateHeight) // bei variierender groesse wird einfach durchschnittsgroesse genommen, da an treppen gar keine vernuempftige Groesse vorliegt - outXml << " <agentInfo ID=\"" << j+1 << "\" color=\"100\" height=\"" << defaultPersonHeight << "\"/>" << Qt::endl; + if(alternateHeight) // bei variierender groesse wird einfach durchschnittsgroesse genommen, da an treppen gar + // keine vernuempftige Groesse vorliegt + outXml << " <agentInfo ID=\"" << j + 1 << "\" color=\"100\" height=\"" << defaultPersonHeight + << "\"/>" << Qt::endl; else - outXml << " <agentInfo ID=\"" << j+1 << "\" color=\"100\" height=\"" << at(j).height() << "\"/>" << Qt::endl; + outXml << " <agentInfo ID=\"" << j + 1 << "\" color=\"100\" height=\"" << at(j).height() << "\"/>" + << Qt::endl; } outXml << " </shape>" << Qt::endl << Qt::endl; // i = frame; j = person - for (i = smallestFirstFrame(); i <= largestLastFr; ++i) + for(i = smallestFirstFrame(); i <= largestLastFr; ++i) { progress.setLabelText(QString("Export data ...")); qApp->processEvents(); progress.setValue(i); - outXml << " <frame ID=\""<< i <<"\">" << Qt::endl; - for (j = 0; j < size(); ++j) + outXml << " <frame ID=\"" << i << "\">" << Qt::endl; + for(j = 0; j < size(); ++j) { - if (at(j).trackPointExist(i)) + if(at(j).trackPointExist(i)) { - // z-wert ist hier ausnahmsweise nicht der kopf, sondern der boden, die prsonengroesse wird dem obigem person-datenentnommen - //personID, Frame ID(?) , X , Y , Z - if (useTrackpoints) - z = at(j).trackPointAt(i).z()+defaultPersonHeight; - //war, wenn ebene versuche sinnvoll:z = at(j).trackPointAt(i).z()+at(j).height(); + // z-wert ist hier ausnahmsweise nicht der kopf, sondern der boden, die prsonengroesse wird dem obigem + // person-datenentnommen + // personID, Frame ID(?) , X , Y , Z + if(useTrackpoints) + z = at(j).trackPointAt(i).z() + defaultPersonHeight; + // war, wenn ebene versuche sinnvoll:z = at(j).trackPointAt(i).z()+at(j).height(); else { - if (alternateHeight) - z = at(j).trackPointAt(i).z()-defaultPersonHeight; - //war, wenn ebene versuche sinnvoll: z = at(j).trackPointAt(i).z()-at(j).height(); + if(alternateHeight) + z = at(j).trackPointAt(i).z() - defaultPersonHeight; + // war, wenn ebene versuche sinnvoll: z = at(j).trackPointAt(i).z()-at(j).height(); else - z = 0; //at(j).height(); + z = 0; // at(j).height(); } - outXml << " <agent ID=\"" << j+1 << "\" xPos=\"" << at(j).trackPointAt(i).x() << "\" yPos=\"" << at(j).trackPointAt(i).y() << "\" zPos=\"" << z << "\" xVel=\"0\" yVel=\"0\" zVel=\"0\" radiusA=\"18\" radiusB=\"15\" ellipseOrientation=\"130\" ellipseColor=\"0\"/>" << Qt::endl; // z Koordinate ist Boden + outXml << " <agent ID=\"" << j + 1 << "\" xPos=\"" << at(j).trackPointAt(i).x() << "\" yPos=\"" + << at(j).trackPointAt(i).y() << "\" zPos=\"" << z + << "\" xVel=\"0\" yVel=\"0\" zVel=\"0\" radiusA=\"18\" radiusB=\"15\" " + "ellipseOrientation=\"130\" ellipseColor=\"0\"/>" + << Qt::endl; // z Koordinate ist Boden } } outXml << " </frame>" << Qt::endl; diff --git a/src/trackingRoiItem.cpp b/src/trackingRoiItem.cpp index 2a484a9fc3a7bf793a77ed996800c0dbf87abef6..9dd9bf56f6c008880c7ef9e3e0a84385bd9b3a42 100644 --- a/src/trackingRoiItem.cpp +++ b/src/trackingRoiItem.cpp @@ -18,40 +18,41 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> +#include "trackingRoiItem.h" -#include "petrack.h" #include "control.h" +#include "petrack.h" #include "view.h" -#include "trackingRoiItem.h" -TrackingRoiItem::TrackingRoiItem(QWidget *wParent, QGraphicsItem *parent) - : QGraphicsRectItem(parent) +#include <QtWidgets> + +TrackingRoiItem::TrackingRoiItem(QWidget *wParent, QGraphicsItem *parent) : QGraphicsRectItem(parent) { - mMainWindow = (class Petrack*) wParent; + mMainWindow = (class Petrack *) wParent; mControlWidget = mMainWindow->getControlWidget(); - setRect(0, 0, 0, 0); //qreal x, qreal y, qreal width, qreal height + setRect(0, 0, 0, 0); // qreal x, qreal y, qreal width, qreal height QPen pen(Qt::blue); setPen(pen); setAcceptHoverEvents(true); setFlags(ItemIsMovable); // default in control - hide(); // default in control + hide(); // default in control } -void TrackingRoiItem::mousePressEvent(QGraphicsSceneMouseEvent * event) +void TrackingRoiItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (!mControlWidget->getTrackRoiFix()) + if(!mControlWidget->getTrackRoiFix()) { - mPressRect = QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); + mPressRect = + QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); mPressPos = event->pos(); - if ((event->pos()).x() < DISTANCE_TO_BORDER+mPressRect.x()) + if((event->pos()).x() < DISTANCE_TO_BORDER + mPressRect.x()) { - if ((event->pos()).y() < DISTANCE_TO_BORDER+mPressRect.y()) + if((event->pos()).y() < DISTANCE_TO_BORDER + mPressRect.y()) { mPressLocation = topLeft; setCursor(Qt::SizeFDiagCursor); } - else if ((event->pos()).y() > mPressRect.height()+mPressRect.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > mPressRect.height() + mPressRect.y() - DISTANCE_TO_BORDER) { mPressLocation = bottomLeft; setCursor(Qt::SizeBDiagCursor); @@ -62,14 +63,14 @@ void TrackingRoiItem::mousePressEvent(QGraphicsSceneMouseEvent * event) setCursor(Qt::SizeHorCursor); } } - else if ((event->pos()).x() > mPressRect.width()+mPressRect.x()-DISTANCE_TO_BORDER) + else if((event->pos()).x() > mPressRect.width() + mPressRect.x() - DISTANCE_TO_BORDER) { - if ((event->pos()).y() < DISTANCE_TO_BORDER+mPressRect.y()) + if((event->pos()).y() < DISTANCE_TO_BORDER + mPressRect.y()) { mPressLocation = topRight; setCursor(Qt::SizeBDiagCursor); } - else if ((event->pos()).y() > mPressRect.height()+mPressRect.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > mPressRect.height() + mPressRect.y() - DISTANCE_TO_BORDER) { mPressLocation = bottomRight; setCursor(Qt::SizeFDiagCursor); @@ -80,12 +81,12 @@ void TrackingRoiItem::mousePressEvent(QGraphicsSceneMouseEvent * event) setCursor(Qt::SizeHorCursor); } } - else if ((event->pos()).y() < DISTANCE_TO_BORDER+mPressRect.y()) + else if((event->pos()).y() < DISTANCE_TO_BORDER + mPressRect.y()) { mPressLocation = top; setCursor(Qt::SizeVerCursor); } - else if ((event->pos()).y() > mPressRect.height()+mPressRect.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > mPressRect.height() + mPressRect.y() - DISTANCE_TO_BORDER) { mPressLocation = bottom; setCursor(Qt::SizeVerCursor); @@ -100,11 +101,11 @@ void TrackingRoiItem::mousePressEvent(QGraphicsSceneMouseEvent * event) QGraphicsRectItem::mousePressEvent(event); } -void TrackingRoiItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) +void TrackingRoiItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { mMainWindow->setTrackChanged(true); - //mMainWindow->setRecognitionChanged(true); - if( !mMainWindow->isLoading() ) + // mMainWindow->setRecognitionChanged(true); + if(!mMainWindow->isLoading()) mMainWindow->updateImage(); QGraphicsRectItem::mouseReleaseEvent(event); @@ -113,62 +114,78 @@ void TrackingRoiItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) // event, of moving mouse while mouse button is pressed void TrackingRoiItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (!mControlWidget->getTrackRoiFix()) + if(!mControlWidget->getTrackRoiFix()) { - QImage *img = mMainWindow->getImage(); - QPoint diff = QPoint(myRound((event->pos()-mPressPos).x()), myRound((event->pos()-mPressPos).y())); + QImage *img = mMainWindow->getImage(); + QPoint diff = QPoint(myRound((event->pos() - mPressPos).x()), myRound((event->pos() - mPressPos).y())); // raender des bildes nicht ueberscheiten // swappen des rechtecks vermeiden, damit keine negativen width... - if (img != nullptr) + if(img != nullptr) { - if (mPressLocation == inside || mPressLocation == topLeft || mPressLocation == left || mPressLocation == bottomLeft) + if(mPressLocation == inside || mPressLocation == topLeft || mPressLocation == left || + mPressLocation == bottomLeft) { - if (mPressRect.x()+diff.x() < -mMainWindow->getImageBorderSize()) - diff.setX(-mPressRect.x()-mMainWindow->getImageBorderSize()); - if (mPressLocation != inside && mPressRect.width()-diff.x() < MIN_SIZE) - diff.setX(mPressRect.width()-MIN_SIZE); + if(mPressRect.x() + diff.x() < -mMainWindow->getImageBorderSize()) + diff.setX(-mPressRect.x() - mMainWindow->getImageBorderSize()); + if(mPressLocation != inside && mPressRect.width() - diff.x() < MIN_SIZE) + diff.setX(mPressRect.width() - MIN_SIZE); } - if (mPressLocation == inside || mPressLocation == topLeft || mPressLocation == top || mPressLocation == topRight) + if(mPressLocation == inside || mPressLocation == topLeft || mPressLocation == top || + mPressLocation == topRight) { - if (mPressRect.y()+diff.y() < -mMainWindow->getImageBorderSize()) - diff.setY(-mPressRect.y()-mMainWindow->getImageBorderSize()); - if (mPressLocation != inside && mPressRect.height()-diff.y() < MIN_SIZE) - diff.setY(mPressRect.height()-MIN_SIZE); + if(mPressRect.y() + diff.y() < -mMainWindow->getImageBorderSize()) + diff.setY(-mPressRect.y() - mMainWindow->getImageBorderSize()); + if(mPressLocation != inside && mPressRect.height() - diff.y() < MIN_SIZE) + diff.setY(mPressRect.height() - MIN_SIZE); } - if (mPressLocation == inside || mPressLocation == topRight || mPressLocation == right || mPressLocation == bottomRight) + if(mPressLocation == inside || mPressLocation == topRight || mPressLocation == right || + mPressLocation == bottomRight) { - if (mPressRect.x()+diff.x()+mPressRect.width() > img->width()-mMainWindow->getImageBorderSize()) - diff.setX(img->width()-mPressRect.x()-mPressRect.width()-mMainWindow->getImageBorderSize()); - if (mPressLocation != inside && mPressRect.width()+diff.x() < MIN_SIZE) - diff.setX(-mPressRect.width()+MIN_SIZE); + if(mPressRect.x() + diff.x() + mPressRect.width() > img->width() - mMainWindow->getImageBorderSize()) + diff.setX(img->width() - mPressRect.x() - mPressRect.width() - mMainWindow->getImageBorderSize()); + if(mPressLocation != inside && mPressRect.width() + diff.x() < MIN_SIZE) + diff.setX(-mPressRect.width() + MIN_SIZE); } - if (mPressLocation == inside || mPressLocation == bottomLeft || mPressLocation == bottom || mPressLocation == bottomRight) + if(mPressLocation == inside || mPressLocation == bottomLeft || mPressLocation == bottom || + mPressLocation == bottomRight) { - if (mPressRect.y()+diff.y()+mPressRect.height() > img->height()-mMainWindow->getImageBorderSize()) - diff.setY(img->height()-mPressRect.y()-mPressRect.height()-mMainWindow->getImageBorderSize()); - if (mPressLocation != inside && mPressRect.height()+diff.y() < MIN_SIZE) - diff.setY(-mPressRect.height()+MIN_SIZE); + if(mPressRect.y() + diff.y() + mPressRect.height() > img->height() - mMainWindow->getImageBorderSize()) + diff.setY(img->height() - mPressRect.y() - mPressRect.height() - mMainWindow->getImageBorderSize()); + if(mPressLocation != inside && mPressRect.height() + diff.y() < MIN_SIZE) + diff.setY(-mPressRect.height() + MIN_SIZE); } } - if (mPressLocation == topLeft) - setRect(mPressRect.x()+diff.x(), mPressRect.y()+diff.y(), mPressRect.width()-diff.x(), mPressRect.height()-diff.y()); - else if (mPressLocation == topRight) - setRect(mPressRect.x(), mPressRect.y()+diff.y(), mPressRect.width()+diff.x(), mPressRect.height()-diff.y()); - else if (mPressLocation == bottomLeft) - setRect(mPressRect.x()+diff.x(), mPressRect.y(), mPressRect.width()-diff.x(), mPressRect.height()+diff.y()); - else if (mPressLocation == bottomRight) - setRect(mPressRect.x(), mPressRect.y(), mPressRect.width()+diff.x(), mPressRect.height()+diff.y()); - else if (mPressLocation == left) - setRect(mPressRect.x()+diff.x(), mPressRect.y(), mPressRect.width()-diff.x(), mPressRect.height()); - else if (mPressLocation == right) - setRect(mPressRect.x(), mPressRect.y(), mPressRect.width()+diff.x(), mPressRect.height()); - else if (mPressLocation == top) - setRect(mPressRect.x(), mPressRect.y()+diff.y(), mPressRect.width(), mPressRect.height()-diff.y()); - else if (mPressLocation == bottom) - setRect(mPressRect.x(), mPressRect.y(), mPressRect.width(), mPressRect.height()+diff.y()); + if(mPressLocation == topLeft) + setRect( + mPressRect.x() + diff.x(), + mPressRect.y() + diff.y(), + mPressRect.width() - diff.x(), + mPressRect.height() - diff.y()); + else if(mPressLocation == topRight) + setRect( + mPressRect.x(), + mPressRect.y() + diff.y(), + mPressRect.width() + diff.x(), + mPressRect.height() - diff.y()); + else if(mPressLocation == bottomLeft) + setRect( + mPressRect.x() + diff.x(), + mPressRect.y(), + mPressRect.width() - diff.x(), + mPressRect.height() + diff.y()); + else if(mPressLocation == bottomRight) + setRect(mPressRect.x(), mPressRect.y(), mPressRect.width() + diff.x(), mPressRect.height() + diff.y()); + else if(mPressLocation == left) + setRect(mPressRect.x() + diff.x(), mPressRect.y(), mPressRect.width() - diff.x(), mPressRect.height()); + else if(mPressLocation == right) + setRect(mPressRect.x(), mPressRect.y(), mPressRect.width() + diff.x(), mPressRect.height()); + else if(mPressLocation == top) + setRect(mPressRect.x(), mPressRect.y() + diff.y(), mPressRect.width(), mPressRect.height() - diff.y()); + else if(mPressLocation == bottom) + setRect(mPressRect.x(), mPressRect.y(), mPressRect.width(), mPressRect.height() + diff.y()); else // entspricht: if (mPressLocation == inside) - setRect(mPressRect.x()+diff.x(), mPressRect.y()+diff.y(), mPressRect.width(), mPressRect.height()); - // nicht, da sonst koordinatensystem verschoben wird: QGraphicsRectItem::mouseMoveEvent(event); // drag + setRect(mPressRect.x() + diff.x(), mPressRect.y() + diff.y(), mPressRect.width(), mPressRect.height()); + // nicht, da sonst koordinatensystem verschoben wird: QGraphicsRectItem::mouseMoveEvent(event); // drag } else // drag mach ich selber QGraphicsRectItem::mouseMoveEvent(event); @@ -182,40 +199,44 @@ void TrackingRoiItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) pos.setY(pos.y() + mMainWindow->getImageBorderSize()); // abfrage auf width() ..., da durch rectLinie die recoBox etwas groesser ist als das Bild und // es bei mMainWindow->setMousePosOnImage(pos); zum fehler beim bildzugriff kommen kann!!! - if (mMainWindow->getImage() && //(pos.x() > 0) && (pos.y() > 0) && - (pos.x() < mMainWindow->getImage()->width()) && (pos.y() < mMainWindow->getImage()->height())) + if(mMainWindow->getImage() && //(pos.x() > 0) && (pos.y() > 0) && + (pos.x() < mMainWindow->getImage()->width()) && (pos.y() < mMainWindow->getImage()->height())) { mMainWindow->setMousePosOnImage(pos); - if (!mControlWidget->getTrackRoiFix()) + if(!mControlWidget->getTrackRoiFix()) { - QRect r = QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); - if ((event->pos()).x() < DISTANCE_TO_BORDER+r.x()) + QRect r = + QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); + if((event->pos()).x() < DISTANCE_TO_BORDER + r.x()) { - if ((event->pos()).y() < DISTANCE_TO_BORDER+r.y()) + if((event->pos()).y() < DISTANCE_TO_BORDER + r.y()) setCursor(Qt::SizeFDiagCursor); - else if ((event->pos()).y() > r.height()+r.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > r.height() + r.y() - DISTANCE_TO_BORDER) setCursor(Qt::SizeBDiagCursor); else setCursor(Qt::SizeHorCursor); } - else if ((event->pos()).x() > r.width()+r.x()-DISTANCE_TO_BORDER) + else if((event->pos()).x() > r.width() + r.x() - DISTANCE_TO_BORDER) { - if ((event->pos()).y() < DISTANCE_TO_BORDER+r.y()) + if((event->pos()).y() < DISTANCE_TO_BORDER + r.y()) setCursor(Qt::SizeBDiagCursor); - else if ((event->pos()).y() > r.height()+r.y()-DISTANCE_TO_BORDER) + else if((event->pos()).y() > r.height() + r.y() - DISTANCE_TO_BORDER) setCursor(Qt::SizeFDiagCursor); else setCursor(Qt::SizeHorCursor); } - else if (((event->pos()).y() < DISTANCE_TO_BORDER+r.y()) || ((event->pos()).y() > r.height()+r.y()-DISTANCE_TO_BORDER)) + else if( + ((event->pos()).y() < DISTANCE_TO_BORDER + r.y()) || + ((event->pos()).y() > r.height() + r.y() - DISTANCE_TO_BORDER)) setCursor(Qt::SizeVerCursor); else setCursor(Qt::OpenHandCursor); } else // wird nur einmal durchaufen - ruecksetzen in control.cpp { - setAcceptHoverEvents(false); // verhoindert nicht, dass wenn objekt darunter liegt, was andereen cursor haette - cursor wird weiterhin beim drueberfahren auf cross gesetzt + setAcceptHoverEvents(false); // verhoindert nicht, dass wenn objekt darunter liegt, was andereen cursor + // haette - cursor wird weiterhin beim drueberfahren auf cross gesetzt setCursor(Qt::CrossCursor); } } @@ -229,29 +250,37 @@ void TrackingRoiItem::checkRect() // not QImage *img = mMainWindow->getImage(); as size is not adapted yet cv::Mat img = mMainWindow->getImageFiltered(); - if (!img.empty()) + if(!img.empty()) { - QRect r = QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); - if (r.x() > img.cols-mMainWindow->getImageBorderSize()-MIN_SIZE || - r.y() > img.rows-mMainWindow->getImageBorderSize()-MIN_SIZE || - r.x()+r.width() < -mMainWindow->getImageBorderSize()+MIN_SIZE || - r.y()+r.height() < -mMainWindow->getImageBorderSize()+MIN_SIZE) + QRect r = + QRect(myRound(rect().left()), myRound(rect().top()), myRound(rect().width()), myRound(rect().height())); + if(r.x() > img.cols - mMainWindow->getImageBorderSize() - MIN_SIZE || + r.y() > img.rows - mMainWindow->getImageBorderSize() - MIN_SIZE || + r.x() + r.width() < -mMainWindow->getImageBorderSize() + MIN_SIZE || + r.y() + r.height() < -mMainWindow->getImageBorderSize() + MIN_SIZE) setRect(-mMainWindow->getImageBorderSize(), -mMainWindow->getImageBorderSize(), img.cols, img.rows); else { - if (r.x() < -mMainWindow->getImageBorderSize()) - setRect(-mMainWindow->getImageBorderSize(), r.y(), r.width()+(mMainWindow->getImageBorderSize()+r.x()), r.height()); - if (r.y() < -mMainWindow->getImageBorderSize()) - setRect(r.x(), -mMainWindow->getImageBorderSize(), r.width(), r.height()+(mMainWindow->getImageBorderSize()+r.y())); - if (r.x()+mMainWindow->getImageBorderSize()+r.width() > img.cols) + if(r.x() < -mMainWindow->getImageBorderSize()) + setRect( + -mMainWindow->getImageBorderSize(), + r.y(), + r.width() + (mMainWindow->getImageBorderSize() + r.x()), + r.height()); + if(r.y() < -mMainWindow->getImageBorderSize()) + setRect( + r.x(), + -mMainWindow->getImageBorderSize(), + r.width(), + r.height() + (mMainWindow->getImageBorderSize() + r.y())); + if(r.x() + mMainWindow->getImageBorderSize() + r.width() > img.cols) { - setRect(r.x(), r.y(), img.cols-r.x()-mMainWindow->getImageBorderSize(), r.height()); + setRect(r.x(), r.y(), img.cols - r.x() - mMainWindow->getImageBorderSize(), r.height()); } - if (r.y()+mMainWindow->getImageBorderSize()+r.height() > img.rows) - setRect(r.x(), r.y(), r.width(), img.rows-r.y()-mMainWindow->getImageBorderSize()); + if(r.y() + mMainWindow->getImageBorderSize() + r.height() > img.rows) + setRect(r.x(), r.y(), r.width(), img.rows - r.y() - mMainWindow->getImageBorderSize()); } } else setRect(0, 0, 0, 0); } - diff --git a/src/vector.cpp b/src/vector.cpp index 67be438a77f1affdc96a8b8cb6caff17bae2331d..363b83cf26d30dfbec3092ea1490fd3010addcc5 100644 --- a/src/vector.cpp +++ b/src/vector.cpp @@ -18,32 +18,19 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <opencv2/opencv.hpp> +#include "vector.h" + +#include "helper.h" -#include <QPointF> #include <QPoint> +#include <QPointF> #include <limits> +#include <opencv2/opencv.hpp> -#include "vector.h" -#include "helper.h" +Vec3F::Vec3F() : mX(0), mY(0), mZ(0) {} +Vec3F::Vec3F(double x, double y, double z) : mX(x), mY(y), mZ(z) {} -Vec3F::Vec3F() - : mX(0), - mY(0), - mZ(0) -{ -} -Vec3F::Vec3F(double x, double y, double z) - : mX(x), - mY(y), - mZ(z) -{ -} - -Vec3F::Vec3F(const cv::Point3f& v) - : mX(v.x), mY(v.y), mZ(v.z) -{ -} +Vec3F::Vec3F(const cv::Point3f &v) : mX(v.x), mY(v.y), mZ(v.z) {} double Vec3F::x() const { @@ -79,7 +66,7 @@ void Vec3F::set(double x, double y, double z) } -Vec3F& Vec3F::operator=(const cv::Point3f& v) +Vec3F &Vec3F::operator=(const cv::Point3f &v) { mX = v.x; mY = v.y; @@ -87,17 +74,17 @@ Vec3F& Vec3F::operator=(const cv::Point3f& v) return *this; } -Vec3F Vec3F::operator+(const Vec3F& v) const +Vec3F Vec3F::operator+(const Vec3F &v) const { return Vec3F(*this) += v; } -Vec3F Vec3F::operator-(const Vec3F& v) const +Vec3F Vec3F::operator-(const Vec3F &v) const { return Vec3F(*this) -= v; } -Vec3F& Vec3F::operator+=(const Vec3F& v) +Vec3F &Vec3F::operator+=(const Vec3F &v) { mX += v.mX; mY += v.mY; @@ -105,7 +92,7 @@ Vec3F& Vec3F::operator+=(const Vec3F& v) return *this; } -Vec3F& Vec3F::operator-=(const Vec3F& v) +Vec3F &Vec3F::operator-=(const Vec3F &v) { mX -= v.mX; mY -= v.mY; @@ -132,31 +119,31 @@ Vec3F Vec3F::operator/(double n) const * @brief Calculates the dot product. * @return The dot product. */ -double Vec3F::operator*(const Vec3F& v) const +double Vec3F::operator*(const Vec3F &v) const { return mX * v.mX + mY * v.mY; } -bool Vec3F::operator==(const Vec3F& v) const +bool Vec3F::operator==(const Vec3F &v) const { return mX == v.mX && mY == v.mY && mZ == v.mZ; } -bool Vec3F::operator!=(const Vec3F& v) const +bool Vec3F::operator!=(const Vec3F &v) const { return !(*this == v); } double Vec3F::length() const { - return sqrt(mX*mX+mY*mY+mZ*mZ); + return sqrt(mX * mX + mY * mY + mZ * mZ); } /** -* @brief Gets this vector in normalized form. -* -* @return A copy of this vector normalized to unit length. -*/ + * @brief Gets this vector in normalized form. + * + * @return A copy of this vector normalized to unit length. + */ Vec3F Vec3F::unit() const { Vec3F tmp(*this); @@ -173,20 +160,22 @@ Vec3F Vec3F::unit() const void Vec3F::normalize() { double len = length(); - if (fabs(len) > std::numeric_limits<double>::epsilon()) + if(fabs(len) > std::numeric_limits<double>::epsilon()) + { + mX /= len; + mY /= len; + mZ /= len; + } + else { - mX/=len; - mY/=len; - mZ/=len; - }else{ - //vector assumed to be 0 or very close to 0 + // vector assumed to be 0 or very close to 0 mX = 0.; mY = 0.; mZ = 0.; } } -double Vec3F::distanceToPoint(const Vec3F& p) const +double Vec3F::distanceToPoint(const Vec3F &p) const { return (*this - p).length(); } @@ -194,38 +183,14 @@ double Vec3F::distanceToPoint(const Vec3F& p) const //--------------------------------------------------------------------------- -Vec2F::Vec2F() - : mX(0), - mY(0) -{ -} -Vec2F::Vec2F(double x, double y) - : mX(x), - mY(y) -{ -} -Vec2F::Vec2F(const QPointF& v) - : mX(v.x()), - mY(v.y()) -{ -} +Vec2F::Vec2F() : mX(0), mY(0) {} +Vec2F::Vec2F(double x, double y) : mX(x), mY(y) {} +Vec2F::Vec2F(const QPointF &v) : mX(v.x()), mY(v.y()) {} -Vec2F::Vec2F(const cv::Point2f &p) - : mX(p.x), - mY(p.y) -{ -} +Vec2F::Vec2F(const cv::Point2f &p) : mX(p.x), mY(p.y) {} -Vec2F::Vec2F(const CvPoint* v) - : mX(v->x), - mY(v->y) -{ -} -Vec2F::Vec2F(const CvPoint2D32f* v) - : mX(v->x), - mY(v->y) -{ -} +Vec2F::Vec2F(const CvPoint *v) : mX(v->x), mY(v->y) {} +Vec2F::Vec2F(const CvPoint2D32f *v) : mX(v->x), mY(v->y) {} CvPoint Vec2F::toCvPoint() const { @@ -279,24 +244,24 @@ void Vec2F::set(double x, double y) mY = y; } -Vec2F& Vec2F::operator+=(const Vec2F& v) +Vec2F &Vec2F::operator+=(const Vec2F &v) { mX += v.mX; mY += v.mY; return *this; } -Vec2F Vec2F::operator+(const Vec2F& v) const +Vec2F Vec2F::operator+(const Vec2F &v) const { return Vec2F(*this) += v; } -Vec2F& Vec2F::operator-=(const Vec2F& v) +Vec2F &Vec2F::operator-=(const Vec2F &v) { mX -= v.mX; mY -= v.mY; return *this; } -Vec2F Vec2F::operator-(const Vec2F& v) const +Vec2F Vec2F::operator-(const Vec2F &v) const { return Vec2F(*this) -= v; } @@ -321,17 +286,17 @@ Vec2F Vec2F::operator/(double n) const * * @return The dot product. */ -double Vec2F::operator*(const Vec2F& v) const +double Vec2F::operator*(const Vec2F &v) const { return mX * v.mX + mY * v.mY; } -bool Vec2F::operator==(const Vec2F& v) const +bool Vec2F::operator==(const Vec2F &v) const { return mX == v.mX && mY == v.mY; } -bool Vec2F::operator!=(const Vec2F& v) const +bool Vec2F::operator!=(const Vec2F &v) const { return !(*this == v); } @@ -359,7 +324,7 @@ double Vec2F::angle() const return atan2(mY, mX); } - /** +/** * @brief Gets this vector in normalized form. * * @return A copy of this vector normalized to unit length. @@ -385,31 +350,33 @@ Vec2F Vec2F::normal() const void Vec2F::normalize() { double len = length(); - if (len > std::numeric_limits<double>::epsilon()) + if(len > std::numeric_limits<double>::epsilon()) + { + mX /= len; + mY /= len; + } + else { - mX/=len; - mY/=len; - }else{ mX = 0.; mY = 0.; } } -double Vec2F::distanceToPoint(const Vec2F& p) const +double Vec2F::distanceToPoint(const Vec2F &p) const { return (*this - p).length(); } -double Vec2F::distanceToLine(const Vec2F& p1, const Vec2F& p2) const +double Vec2F::distanceToLine(const Vec2F &p1, const Vec2F &p2) const { - Vec2F n = (p2-p1).normal(); // normal vector - n.normalize(); // normalized normal vector - return fabs(*this * n - p1*n); + Vec2F n = (p2 - p1).normal(); // normal vector + n.normalize(); // normalized normal vector + return fabs(*this * n - p1 * n); } -double Vec2F::angleBetweenVec(const Vec2F& v) const +double Vec2F::angleBetweenVec(const Vec2F &v) const { - return acos((*this * v)/(length()*v.length())); + return acos((*this * v) / (length() * v.length())); } Vec2F Vec2F::fromAngle(double angle) diff --git a/src/view.cpp b/src/view.cpp index a8d26a9a5cc9a9eb5005738750a469e34fe3d825..87adad26eb88a08228dbe412cc2fd50ad8efa9f5 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -18,79 +18,80 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <QtWidgets> - -#include <cmath> - #include "view.h" -#include "vector.h" -#include "petrack.h" + #include "control.h" +#include "petrack.h" +#include "vector.h" -GraphicsView::GraphicsView(ViewWidget *viewWidget) - : QGraphicsView() +#include <QtWidgets> +#include <cmath> + +GraphicsView::GraphicsView(ViewWidget *viewWidget) : QGraphicsView() { mViewWidget = viewWidget; setTransformationAnchor(AnchorUnderMouse); // for wheel - setResizeAnchor(AnchorUnderMouse); // for scroll? + setResizeAnchor(AnchorUnderMouse); // for scroll? } -void GraphicsView::wheelEvent(QWheelEvent * event) +void GraphicsView::wheelEvent(QWheelEvent *event) { QPoint numDegrees = event->angleDelta() / 8; - if (event->modifiers() == Qt::ShiftModifier) // nur shift zugelassen ... + if(event->modifiers() == Qt::ShiftModifier) // nur shift zugelassen ... { // Check if horizontal scroll - if (event->angleDelta().x() != 0) // warum orienttion? - emit mouseShiftWheel(numDegrees.x()/15); + if(event->angleDelta().x() != 0) // warum orienttion? + emit mouseShiftWheel(numDegrees.x() / 15); else - emit mouseShiftWheel(-numDegrees.y()/15); + emit mouseShiftWheel(-numDegrees.y() / 15); } else { // Check if horizontal scroll - if (event->angleDelta().x() != 0) // warum orienttion? - mViewWidget->zoomIn(numDegrees.x()/2); + if(event->angleDelta().x() != 0) // warum orienttion? + mViewWidget->zoomIn(numDegrees.x() / 2); else - mViewWidget->zoomOut(numDegrees.y()/2); + mViewWidget->zoomOut(numDegrees.y() / 2); } } void GraphicsView::mouseDoubleClickEvent(QMouseEvent *event) { - if (event->button() == Qt::LeftButton) + if(event->button() == Qt::LeftButton) { - if (event->modifiers() & Qt::ShiftModifier) // mit & genuegt, dass unter anderem shift gedrueckt wird (zb mit conrol) + if(event->modifiers() & + Qt::ShiftModifier) // mit & genuegt, dass unter anderem shift gedrueckt wird (zb mit conrol) { - if (event->modifiers() & Qt::ControlModifier) // mindestens shift und control gedrueckt + if(event->modifiers() & Qt::ControlModifier) // mindestens shift und control gedrueckt emit mouseShiftControlDoubleClick(mapToScene(event->pos())); else - emit mouseShiftDoubleClick(mapToScene(event->pos())); //const QPoint & //const QPointF &pos + emit mouseShiftDoubleClick(mapToScene(event->pos())); // const QPoint & //const QPointF &pos } - else if (event->modifiers() & Qt::ControlModifier) // mit & genuegt, dass unter anderem control gedrueckt wird (zb mit shift) - emit mouseControlDoubleClick(mapToScene(event->pos())); //const QPoint & //const QPointF &pos + else if(event->modifiers() & Qt::ControlModifier) // mit & genuegt, dass unter anderem control gedrueckt wird + // (zb mit shift) + emit mouseControlDoubleClick(mapToScene(event->pos())); // const QPoint & //const QPointF &pos else emit mouseDoubleClick(); } - else if (event->button() == Qt::RightButton) + else if(event->button() == Qt::RightButton) { - if (event->modifiers() == Qt::ShiftModifier) // nur shift zugelassen ... + if(event->modifiers() == Qt::ShiftModifier) // nur shift zugelassen ... emit mouseRightDoubleClick(mapToScene(event->pos()), -1); - else if (event->modifiers() == Qt::ControlModifier) + else if(event->modifiers() == Qt::ControlModifier) emit mouseRightDoubleClick(mapToScene(event->pos()), 0); - else if (event->modifiers() == Qt::AltModifier) + else if(event->modifiers() == Qt::AltModifier) emit mouseRightDoubleClick(mapToScene(event->pos()), 1); } - else if (event->button() == Qt::MiddleButton) + else if(event->button() == Qt::MiddleButton) { - if (event->modifiers() == Qt::ShiftModifier) // nur shift zugelassen ... + if(event->modifiers() == Qt::ShiftModifier) // nur shift zugelassen ... emit mouseMiddleDoubleClick(-1); - else if (event->modifiers() == Qt::ControlModifier) + else if(event->modifiers() == Qt::ControlModifier) emit mouseMiddleDoubleClick(0); - else if (event->modifiers() == Qt::AltModifier) + else if(event->modifiers() == Qt::AltModifier) emit mouseMiddleDoubleClick(1); } @@ -104,29 +105,31 @@ void GraphicsView::keyPressEvent(QKeyEvent *event) // forward the arrow keys for handling in petrack player switch(event->key()) { - case Qt::Key_Up: - mViewWidget->parent()->event(event); - break; - case Qt::Key_Down: - mViewWidget->parent()->event(event); - break; - case Qt::Key_Left: - mViewWidget->parent()->event(event); - break; - case Qt::Key_Right: - mViewWidget->parent()->event(event); - break; - default: - QGraphicsView::keyPressEvent(event); + case Qt::Key_Up: + mViewWidget->parent()->event(event); + break; + case Qt::Key_Down: + mViewWidget->parent()->event(event); + break; + case Qt::Key_Left: + mViewWidget->parent()->event(event); + break; + case Qt::Key_Right: + mViewWidget->parent()->event(event); + break; + default: + QGraphicsView::keyPressEvent(event); } } void GraphicsView::mousePressEvent(QMouseEvent *event) { - - if(event->modifiers() & Qt::ShiftModifier){ + if(event->modifiers() & Qt::ShiftModifier) + { emit setColorEvent(); - }else{ + } + else + { emit colorSelected(); } QGraphicsView::mousePressEvent(event); @@ -135,16 +138,15 @@ void GraphicsView::mousePressEvent(QMouseEvent *event) //--------------------------------------------------------------------- -ViewWidget::ViewWidget(QWidget *parent) - : QFrame(parent) +ViewWidget::ViewWidget(QWidget *parent) : QFrame(parent) { - mMainWindow = (class Petrack*) parent; + mMainWindow = (class Petrack *) parent; setContentsMargins(0, 0, 0, 0); mGraphicsView = new GraphicsView(this); mGraphicsView->setRenderHint(QPainter::Antialiasing, false); - mGraphicsView->setDragMode(QGraphicsView::ScrollHandDrag); //RubberBandDrag + mGraphicsView->setDragMode(QGraphicsView::ScrollHandDrag); // RubberBandDrag - int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize); + int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize); QSize iconSize(size, size); // Hide|Show Button @@ -170,7 +172,7 @@ ViewWidget::ViewWidget(QWidget *parent) rotateRightIcon->setIconSize(iconSize); mRotateSlider = new QSlider; mRotateSlider->setMinimum(-180); //-360 - mRotateSlider->setMaximum(180); // 360 + mRotateSlider->setMaximum(180); // 360 mRotateSlider->setValue(0); mRotateSlider->setTickPosition(QSlider::TicksBelow); @@ -236,24 +238,29 @@ void ViewWidget::resetView() void ViewWidget::fitInView() { - mGraphicsView->fitInView(mGraphicsView->sceneRect(), Qt::KeepAspectRatio); // Qt::KeepAspectRatioByExpanding wuerde nur in eine dimension passend machen - // doesnt work: mGraphicsView->fitInView(mGraphicsView->sceneRect(), Qt::KeepAspectRatio); // two times, while in the first run possibly the scrollbars have been there for calculation + mGraphicsView->fitInView( + mGraphicsView->sceneRect(), + Qt::KeepAspectRatio); // Qt::KeepAspectRatioByExpanding wuerde nur in eine dimension passend machen + // doesnt work: mGraphicsView->fitInView(mGraphicsView->sceneRect(), Qt::KeepAspectRatio); // two times, while in + // the first run possibly the scrollbars have been there for calculation QTransform matrix = mGraphicsView->transform(); // calculates the sclaing of matrix // see http://www.robertblum.com/articles/2005/02/14/decomposing-matrices for rotation out of matrix double scale = Vec2F(matrix.m11(), matrix.m21()).length(); - mZoomSlider->setValue((int) (250.+50.*log(scale)/log(2.))); + mZoomSlider->setValue((int) (250. + 50. * log(scale) / log(2.))); } void ViewWidget::fitInROI(QRectF rect) { - mGraphicsView->fitInView(rect, Qt::KeepAspectRatio); // Qt::KeepAspectRatioByExpanding wuerde nur in eine dimension passend machen - // doesnt work: mGraphicsView->fitInView(mGraphicsView->sceneRect(), Qt::KeepAspectRatio); // two times, while in the first run possibly the scrollbars have been there for calculation + mGraphicsView->fitInView( + rect, Qt::KeepAspectRatio); // Qt::KeepAspectRatioByExpanding wuerde nur in eine dimension passend machen + // doesnt work: mGraphicsView->fitInView(mGraphicsView->sceneRect(), Qt::KeepAspectRatio); // two times, while in + // the first run possibly the scrollbars have been there for calculation QTransform matrix = mGraphicsView->transform(); // calculates the sclaing of matrix // see http://www.robertblum.com/articles/2005/02/14/decomposing-matrices for rotation out of matrix double scale = Vec2F(matrix.m11(), matrix.m21()).length(); - mZoomSlider->setValue((int) (250.+50.*log(scale)/log(2.))); + mZoomSlider->setValue((int) (250. + 50. * log(scale) / log(2.))); } void ViewWidget::setupMatrix() @@ -267,12 +274,12 @@ void ViewWidget::setupMatrix() mGraphicsView->setTransform(matrix); } -void ViewWidget::zoomIn(int i) //default i = 1 +void ViewWidget::zoomIn(int i) // default i = 1 { mZoomSlider->setValue(mZoomSlider->value() + i); } -void ViewWidget::zoomOut(int i) //default i = 1 +void ViewWidget::zoomOut(int i) // default i = 1 { mZoomSlider->setValue(mZoomSlider->value() - i); } @@ -289,11 +296,12 @@ void ViewWidget::rotateRight() void ViewWidget::hideControls(bool hide) { - if ( hide ) + if(hide) { mMainWindow->getControlWidget()->setVisible(false); hideShowControlsButton->setIcon(QPixmap(":/arrowLeft")); - }else + } + else { mMainWindow->getControlWidget()->setVisible(true); hideShowControlsButton->setIcon(QPixmap(":/arrowRight")); diff --git a/tests/unit_test/main.cpp b/tests/unit_test/main.cpp index ff63ecda9a346b96591ebebee16a78d94bc52fc7..859693c730629bc6b211e53b94a04a9514a7775a 100644 --- a/tests/unit_test/main.cpp +++ b/tests/unit_test/main.cpp @@ -19,31 +19,34 @@ */ #define CATCH_CONFIG_RUNNER -#include <catch2/catch.hpp> - #include <QApplication> #include <QtTest> +#include <catch2/catch.hpp> #include <vector> -int main( int argc, char* argv[] ) +int main(int argc, char *argv[]) { // always start unit tests as offscreen, so PMessageBox-es only log bool platformAlreadyGiven = false; - for(int i = 0; i < argc; ++i){ - if(qstrcmp("-platform", argv[i]) == 0){ + for(int i = 0; i < argc; ++i) + { + if(qstrcmp("-platform", argv[i]) == 0) + { platformAlreadyGiven = true; } } - int argc2; + int argc2; char **argv2; - auto args = std::vector<const char*>(argv, argv+argc); + auto args = std::vector<const char *>(argv, argv + argc); if(!platformAlreadyGiven) { args.push_back("-platform"); args.push_back("offscreen"); - argc2 = argc+2; + argc2 = argc + 2; argv2 = const_cast<char **>(args.data()); - }else{ + } + else + { argc2 = argc; argv2 = argv; } @@ -51,7 +54,7 @@ int main( int argc, char* argv[] ) QApplication a(argc2, argv2); QTEST_SET_MAIN_SOURCE_PATH - const int result = Catch::Session().run( argc2, argv2 ); + const int result = Catch::Session().run(argc2, argv2); - return ( result < 0xff ? result : 0xff ); + return (result < 0xff ? result : 0xff); } diff --git a/tests/unit_test/tst_SkeletonTree.cpp b/tests/unit_test/tst_SkeletonTree.cpp index b4281850c137ca714c3a3be65471831dd9bf08de..f52e81d99ccb748f91c58c47be98d976d1bf020f 100644 --- a/tests/unit_test/tst_SkeletonTree.cpp +++ b/tests/unit_test/tst_SkeletonTree.cpp @@ -18,186 +18,172 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <catch2/catch.hpp> - -#include "skeletonTreeFactory.h" #include "skeletonTree.h" +#include "skeletonTreeFactory.h" + +#include <catch2/catch.hpp> -const XSenseStruct XSENSE_DUMMY_DATA = { - {0,0,0}, - {1,1,1}, - {2,2,2}, - {3,3,3}, - {4,4,4}, - {5,5,5}, - {6,6,6}, - {7,7,7}, - {8,8,8}, - {9,9,9}, - {10,10,10}, - {11,11,11}, - {12,12,12}, - {13,13,13}, - {14,14,14}, - {15,15,15}, - {16,16,16}, - {17,17,17}, - {18,18,18}, - {19,19,19}, - {20,20,20}, +const XSenseStruct XSENSE_DUMMY_DATA = { + {0, 0, 0}, {1, 1, 1}, {2, 2, 2}, {3, 3, 3}, {4, 4, 4}, {5, 5, 5}, {6, 6, 6}, + {7, 7, 7}, {8, 8, 8}, {9, 9, 9}, {10, 10, 10}, {11, 11, 11}, {12, 12, 12}, {13, 13, 13}, + {14, 14, 14}, {15, 15, 15}, {16, 16, 16}, {17, 17, 17}, {18, 18, 18}, {19, 19, 19}, {20, 20, 20}, }; -TEST_CASE("SkeletonTree for XSenseData is built") { +TEST_CASE("SkeletonTree for XSenseData is built") +{ SkeletonTree skel = SkeletonTreeFactory::generateTree(XSENSE_DUMMY_DATA); - SECTION( "Check all bone connections and positions" ) { - auto& rootNode = skel.getRoot(); + SECTION("Check all bone connections and positions") + { + auto &rootNode = skel.getRoot(); REQUIRE(rootNode.getPos() == XSENSE_DUMMY_DATA.mRoot); REQUIRE(rootNode.getChildrenCount() == 3); - //own id + // own id REQUIRE_THROWS(rootNode.getChildById(0)); - //does not exist + // does not exist REQUIRE_THROWS(rootNode.getChildById(100)); - //neck + // neck REQUIRE_NOTHROW(rootNode.getChildById(1)); - //left hip + // left hip REQUIRE_NOTHROW(rootNode.getChildById(11)); - //right hip + // right hip REQUIRE_NOTHROW(rootNode.getChildById(15)); - //check neck next - auto& neckNode = rootNode.getChildById(1); + // check neck next + auto &neckNode = rootNode.getChildById(1); REQUIRE(neckNode.getPos() == XSENSE_DUMMY_DATA.mNeck); REQUIRE(neckNode.getChildrenCount() == 3); - //head + // head REQUIRE_NOTHROW(neckNode.getChildById(2)); - //left shoulder + // left shoulder REQUIRE_NOTHROW(neckNode.getChildById(3)); - //right shoulder + // right shoulder REQUIRE_NOTHROW(neckNode.getChildById(7)); - //head - auto& headNode = neckNode.getChildById(2); + // head + auto &headNode = neckNode.getChildById(2); REQUIRE(headNode.getPos() == XSENSE_DUMMY_DATA.mHeadTop); REQUIRE(headNode.getChildrenCount() == 0); - //left shoulder - auto& lShldrNode = neckNode.getChildById(3); + // left shoulder + auto &lShldrNode = neckNode.getChildById(3); REQUIRE(lShldrNode.getPos() == XSENSE_DUMMY_DATA.mShldrL); REQUIRE(lShldrNode.getChildrenCount() == 1); REQUIRE_NOTHROW(lShldrNode.getChildById(4)); - //left shoulder - auto& lElbowNode = lShldrNode.getChildById(4); + // left shoulder + auto &lElbowNode = lShldrNode.getChildById(4); REQUIRE(lElbowNode.getPos() == XSENSE_DUMMY_DATA.mElbowL); REQUIRE(lElbowNode.getChildrenCount() == 1); - //left wrist + // left wrist REQUIRE_NOTHROW(lElbowNode.getChildById(5)); - //left wrist - auto& lWristNode = lElbowNode.getChildById(5); + // left wrist + auto &lWristNode = lElbowNode.getChildById(5); REQUIRE(lWristNode.getPos() == XSENSE_DUMMY_DATA.mWristL); REQUIRE(lWristNode.getChildrenCount() == 1); - //left hand + // left hand REQUIRE_NOTHROW(lWristNode.getChildById(6)); - //left hand - auto& lHandNode = lWristNode.getChildById(6); + // left hand + auto &lHandNode = lWristNode.getChildById(6); REQUIRE(lHandNode.getPos() == XSENSE_DUMMY_DATA.mHandL); REQUIRE(lHandNode.getChildrenCount() == 0); - //right shoulder - auto& rShldrNode = neckNode.getChildById(7); + // right shoulder + auto &rShldrNode = neckNode.getChildById(7); REQUIRE(rShldrNode.getPos() == XSENSE_DUMMY_DATA.mShldrR); REQUIRE(rShldrNode.getChildrenCount() == 1); REQUIRE_NOTHROW(rShldrNode.getChildById(8)); - //right shoulder - auto& rElbowNode = rShldrNode.getChildById(8); + // right shoulder + auto &rElbowNode = rShldrNode.getChildById(8); REQUIRE(rElbowNode.getPos() == XSENSE_DUMMY_DATA.mElbowR); REQUIRE(rElbowNode.getChildrenCount() == 1); - //right wrist + // right wrist REQUIRE_NOTHROW(rElbowNode.getChildById(9)); - //right wrist - auto& rWristNode = rElbowNode.getChildById(9); + // right wrist + auto &rWristNode = rElbowNode.getChildById(9); REQUIRE(rWristNode.getPos() == XSENSE_DUMMY_DATA.mWristR); REQUIRE(rWristNode.getChildrenCount() == 1); - //right hand + // right hand REQUIRE_NOTHROW(rWristNode.getChildById(10)); - //right hand - auto& rHandNode = rWristNode.getChildById(10); + // right hand + auto &rHandNode = rWristNode.getChildById(10); REQUIRE(rHandNode.getPos() == XSENSE_DUMMY_DATA.mHandR); REQUIRE(rHandNode.getChildrenCount() == 0); - //left hip - auto& lHipNode = rootNode.getChildById(11); + // left hip + auto &lHipNode = rootNode.getChildById(11); REQUIRE(lHipNode.getPos() == XSENSE_DUMMY_DATA.mHipL); - REQUIRE(lHipNode.getChildrenCount() == 1 ); + REQUIRE(lHipNode.getChildrenCount() == 1); REQUIRE_NOTHROW(lHipNode.getChildById(12)); - //left knee - auto& lKneeNode = lHipNode.getChildById(12); + // left knee + auto &lKneeNode = lHipNode.getChildById(12); REQUIRE(lKneeNode.getPos() == XSENSE_DUMMY_DATA.mKneeL); - REQUIRE(lKneeNode.getChildrenCount() == 1 ); + REQUIRE(lKneeNode.getChildrenCount() == 1); REQUIRE_NOTHROW(lKneeNode.getChildById(13)); - //left heel - auto& lHeelNode = lKneeNode.getChildById(13); + // left heel + auto &lHeelNode = lKneeNode.getChildById(13); REQUIRE(lKneeNode.getPos() == XSENSE_DUMMY_DATA.mKneeL); - REQUIRE(lKneeNode.getChildrenCount() == 1 ); + REQUIRE(lKneeNode.getChildrenCount() == 1); REQUIRE_NOTHROW(lHeelNode.getChildById(14)); - //left toe - auto& lToeNode = lHeelNode.getChildById(14); + // left toe + auto &lToeNode = lHeelNode.getChildById(14); REQUIRE(lToeNode.getPos() == XSENSE_DUMMY_DATA.mToeL); - REQUIRE(lToeNode.getChildrenCount() == 0 ); + REQUIRE(lToeNode.getChildrenCount() == 0); - //right hip - auto& rHipNode = rootNode.getChildById(15); + // right hip + auto &rHipNode = rootNode.getChildById(15); REQUIRE(rHipNode.getPos() == XSENSE_DUMMY_DATA.mHipR); - REQUIRE(rHipNode.getChildrenCount() == 1 ); + REQUIRE(rHipNode.getChildrenCount() == 1); REQUIRE_NOTHROW(rHipNode.getChildById(16)); - //right knee - auto& rKneeNode = rHipNode.getChildById(16); + // right knee + auto &rKneeNode = rHipNode.getChildById(16); REQUIRE(rKneeNode.getPos() == XSENSE_DUMMY_DATA.mKneeR); - REQUIRE(rKneeNode.getChildrenCount() == 1 ); + REQUIRE(rKneeNode.getChildrenCount() == 1); REQUIRE_NOTHROW(rKneeNode.getChildById(17)); - //right heel - auto& rHeelNode = rKneeNode.getChildById(17); + // right heel + auto &rHeelNode = rKneeNode.getChildById(17); REQUIRE(rKneeNode.getPos() == XSENSE_DUMMY_DATA.mKneeR); - REQUIRE(rKneeNode.getChildrenCount() == 1 ); + REQUIRE(rKneeNode.getChildrenCount() == 1); REQUIRE_NOTHROW(rHeelNode.getChildById(18)); - //right toe - auto& rToeNode = rHeelNode.getChildById(18); + // right toe + auto &rToeNode = rHeelNode.getChildById(18); REQUIRE(rToeNode.getPos() == XSENSE_DUMMY_DATA.mToeR); - REQUIRE(rToeNode.getChildrenCount() == 0 ); + REQUIRE(rToeNode.getChildrenCount() == 0); } - SECTION("Test the line data"){ + SECTION("Test the line data") + { auto lines = skel.getLines(); REQUIRE(lines.size() == 18); - for(SkeletonLine& line : lines){ + for(SkeletonLine &line : lines) + { REQUIRE(line.start_id != line.end_id); REQUIRE(line.start != line.end); } diff --git a/tests/unit_test/tst_apptest.cpp b/tests/unit_test/tst_apptest.cpp index 0295d5dbb542c6c87c2874f84abd2505843eb507..3edaf9dbfc60b88c6413d26703f81dc3305e6165 100644 --- a/tests/unit_test/tst_apptest.cpp +++ b/tests/unit_test/tst_apptest.cpp @@ -18,17 +18,12 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include <QSignalSpy> #include <catch2/catch.hpp> - #include <iostream> -#include <QSignalSpy> - SCENARIO("Application Tests", "[app]") { - - GIVEN("Hello World") { - REQUIRE(true); - } + GIVEN("Hello World") { REQUIRE(true); } } diff --git a/tests/unit_test/tst_codeMarkerWidget.cpp b/tests/unit_test/tst_codeMarkerWidget.cpp index 4db371b653611a92f8a72dc9594e7dc99bcfc35f..2b22219c3483928e597ab150482ef9bbc97d0186 100644 --- a/tests/unit_test/tst_codeMarkerWidget.cpp +++ b/tests/unit_test/tst_codeMarkerWidget.cpp @@ -18,24 +18,24 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <catch2/catch.hpp> - -#include "recognition.h" #include "codeMarkerWidget.h" +#include "recognition.h" #include "ui_codeMarker.h" +#include <catch2/catch.hpp> + SCENARIO("The user opens the CodeMarkerWidget", "[ui]") { // create the dialog - Petrack petrack; + Petrack petrack; reco::CodeMarkerOptions options; - Ui::CodeMarker *view = new Ui::CodeMarker(); - CodeMarkerWidget widget {&petrack, options, view}; + Ui::CodeMarker * view = new Ui::CodeMarker(); + CodeMarkerWidget widget{&petrack, options, view}; THEN("The view shows the correct values") { - const auto& params = options.getDetectorParams(); - const auto displayedParams = packDetectorParams(view); + const auto ¶ms = options.getDetectorParams(); + const auto displayedParams = packDetectorParams(view); REQUIRE(params == displayedParams); } @@ -88,9 +88,9 @@ SCENARIO("The user opens the CodeMarkerWidget", "[ui]") auto oldValues = packDetectorParams(view); // Since min already has minimal value this isn't properly tested with the default min view->adaptiveThreshWinSizeMin->setValue(10); - view->adaptiveThreshWinSizeMax->setValue(view->adaptiveThreshWinSizeMin->value()-1); - //view->minMarkerPerimeter-> - view->maxMarkerPerimeter->setValue(view->minMarkerPerimeter->value()-1); + view->adaptiveThreshWinSizeMax->setValue(view->adaptiveThreshWinSizeMin->value() - 1); + // view->minMarkerPerimeter-> + view->maxMarkerPerimeter->setValue(view->minMarkerPerimeter->value() - 1); THEN("It is not changed") { REQUIRE(view->adaptiveThreshWinSizeMax->value() == oldValues.getAdaptiveThreshWinSizeMax()); @@ -101,81 +101,55 @@ SCENARIO("The user opens the CodeMarkerWidget", "[ui]") GIVEN("A cornerRefinementWinSize less than 1") { view->cornerRefinementWinSize->setValue(-2); - THEN("The value gets set to 1") - { - REQUIRE(view->cornerRefinementWinSize->value() == 1); - } + THEN("The value gets set to 1") { REQUIRE(view->cornerRefinementWinSize->value() == 1); } } GIVEN("A cornerRefinementMaxIterations less than 1") { view->cornerRefinementMaxIterations->setValue(0); - THEN("The value gets set to 1") - { - REQUIRE(view->cornerRefinementMaxIterations->value() == 1); - } + THEN("The value gets set to 1") { REQUIRE(view->cornerRefinementMaxIterations->value() == 1); } } GIVEN("A cornerRefinementMinAccuracy less than or equal to 0") { view->cornerRefinementMinAccuracy->setValue(-3); - THEN("It is set to 0.01") - { - REQUIRE(view->cornerRefinementMinAccuracy->value() == Approx(0.01)); - } + THEN("It is set to 0.01") { REQUIRE(view->cornerRefinementMinAccuracy->value() == Approx(0.01)); } } GIVEN("markerBorderBits less than 1") { view->markerBorderBits->setValue(0); - THEN("The value is set to 1") - { - REQUIRE(view->markerBorderBits->value() == 1); - } + THEN("The value is set to 1") { REQUIRE(view->markerBorderBits->value() == 1); } } GIVEN("minStdDevOtsu less than or equal to 0") { view->minOtsuStdDev->setValue(-2); - THEN("The value is set to 0.01") - { - REQUIRE(view->minOtsuStdDev->value() == Approx(0.01)); - } + THEN("The value is set to 0.01") { REQUIRE(view->minOtsuStdDev->value() == Approx(0.01)); } } GIVEN("adaptiveThreshSizeMin less than 3") { view->adaptiveThreshWinSizeMin->setValue(1); - THEN("The value is set to 3"){ - REQUIRE(view->adaptiveThreshWinSizeMin->value() == 3); - } + THEN("The value is set to 3") { REQUIRE(view->adaptiveThreshWinSizeMin->value() == 3); } } GIVEN("adaptiveThreshSizeMax less than 3") { view->adaptiveThreshWinSizeMax->setValue(1); - THEN("The value is set to 3") - { - REQUIRE(view->adaptiveThreshWinSizeMax->value() == 3); - } + THEN("The value is set to 3") { REQUIRE(view->adaptiveThreshWinSizeMax->value() == 3); } } GIVEN("adaptiveThreshWinSizeStep less than or equal to 0") { view->adaptiveThreshWinSizeStep->setValue(0); - THEN("The value is set to 1") - { - REQUIRE(view->adaptiveThreshWinSizeStep->value() == 1); - } + THEN("The value is set to 1") { REQUIRE(view->adaptiveThreshWinSizeStep->value() == 1); } } GIVEN("minMarkerPerimeter less than or equal to 0") { view->minMarkerPerimeter->setValue(0); - THEN("The value is set to 0.1") - { - REQUIRE(view->minMarkerPerimeter->value() == Approx(0.1)); - } + THEN("The value is set to 0.1") { REQUIRE(view->minMarkerPerimeter->value() == Approx(0.1)); } } GIVEN("maxMarkerPerimeter less than or equal to 0") @@ -183,36 +157,24 @@ SCENARIO("The user opens the CodeMarkerWidget", "[ui]") auto oldVal = view->maxMarkerPerimeter->value(); view->minMarkerPerimeter->setValue(0); // since max cannot be lower than min view->maxMarkerPerimeter->setValue(0); - THEN("The value is not changed") - { - REQUIRE(view->maxMarkerPerimeter->value() == Approx(oldVal)); - } + THEN("The value is not changed") { REQUIRE(view->maxMarkerPerimeter->value() == Approx(oldVal)); } } GIVEN("cornerRefinementMinAccuracy less than or equal to 0") { view->cornerRefinementMinAccuracy->setValue(0); - THEN("The value is set to 0.01") - { - REQUIRE(view->cornerRefinementMinAccuracy->value() == Approx(0.01)); - } + THEN("The value is set to 0.01") { REQUIRE(view->cornerRefinementMinAccuracy->value() == Approx(0.01)); } } GIVEN("minCornerDistance less than 0") { view->minCornerDistance->setValue(-1); - THEN("The value is set to 1") - { - REQUIRE(view->minCornerDistance->value() == Approx(0)); - } + THEN("The value is set to 1") { REQUIRE(view->minCornerDistance->value() == Approx(0)); } } GIVEN("minDistanceToBorder less than 0") { view->minDistanceToBorder->setValue(-2); - THEN("The value is set to 0") - { - REQUIRE(view->minDistanceToBorder->value() == 0); - } + THEN("The value is set to 0") { REQUIRE(view->minDistanceToBorder->value() == 0); } } } diff --git a/tests/unit_test/tst_control.cpp b/tests/unit_test/tst_control.cpp index 9337288514fa4d1fabf02591f7dfd6ad7d36700f..86a32580e4e1c906675d8a0e93153a5527dca686 100644 --- a/tests/unit_test/tst_control.cpp +++ b/tests/unit_test/tst_control.cpp @@ -18,29 +18,37 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <catch2/catch.hpp> - -#include <iostream> #include "control.h" +#include "imageItem.h" +#include "view.h" +#include <QGraphicsScene> #include <QSignalSpy> #include <QTestEventList> -#include <QGraphicsScene> -#include "imageItem.h" - -#include "view.h" +#include <catch2/catch.hpp> +#include <iostream> // TODO Connect und Disconnect vom Event (lässt sich an und abschalten) // TODO Weitere Testcases überlegen -void checkSelectedColor(Control* con, bool invHue, int toHue, int fromHue, - int toSat, int fromSat, int toVal, int fromVal, - int mapX, int mapW, int mapY, int mapH){ - +void checkSelectedColor( + Control *con, + bool invHue, + int toHue, + int fromHue, + int toSat, + int fromSat, + int toVal, + int fromVal, + int mapX, + int mapW, + int mapY, + int mapH) +{ REQUIRE(con->getColorPlot()->getMapItem()->getActMapInvHue() == invHue); - QColor toColor = con->getColorPlot()->getMapItem()->getActMapToColor(); + QColor toColor = con->getColorPlot()->getMapItem()->getActMapToColor(); QColor fromColor = con->getColorPlot()->getMapItem()->getActMapFromColor(); // Hue @@ -65,8 +73,8 @@ void checkSelectedColor(Control* con, bool invHue, int toHue, int fromHue, SCENARIO("I open PeTrack with a red image", "[ui][config]") { - Petrack pet {}; - cv::Mat redTestImage {cv::Size(50, 50), CV_8UC3, cv::Scalar(179,255,200)}; + Petrack pet{}; + cv::Mat redTestImage{cv::Size(50, 50), CV_8UC3, cv::Scalar(179, 255, 200)}; cv::cvtColor(redTestImage, redTestImage, cv::COLOR_HSV2BGR); // NOTE Gibt es eine bessere Methode, als das Bild erst zu speichern? cv::imwrite("TESTBILD_DELETE_ME.png", redTestImage); @@ -75,17 +83,17 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") QPointer<Control> con = pet.getControlWidget(); - GIVEN("I click the colorPickerButton") { + GIVEN("I click the colorPickerButton") + { QTestEventList eventList; - QPushButton* colorPickerButton = con->findChild<QPushButton*>("colorPickerButton"); + QPushButton * colorPickerButton = con->findChild<QPushButton *>("colorPickerButton"); eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier); eventList.simulate(colorPickerButton); - THEN("The Button is checked") { - REQUIRE(colorPickerButton->isChecked()); - } + THEN("The Button is checked") { REQUIRE(colorPickerButton->isChecked()); } - AND_GIVEN("I shift+click on one point of the (red) image"){ + AND_GIVEN("I shift+click on one point of the (red) image") + { eventList.clear(); eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::ShiftModifier, viewCenter); eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::ShiftModifier, viewCenter); @@ -96,7 +104,8 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") eventList.simulate(pet.getView()->viewport()); REQUIRE(setColorSpy.count() == 2); - THEN("This pixel and its sourroundings get selected as new color"){ + THEN("This pixel and its sourroundings get selected as new color") + { // Red, so we need Inverse Hue bool invHue = true; @@ -118,7 +127,7 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") // x = 2 * 3 = 6 int mapX = 6; // w = |toHue - fromHue| = 350 - int mapW= 350; + int mapW = 350; // y = 2 * fromSaturation = 500 int mapY = 500; // h = toSaturation - fromSaturation = 5 @@ -126,8 +135,9 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") checkSelectedColor(con, invHue, toHue, fromHue, toSat, fromSat, toVal, fromVal, mapX, mapW, mapY, mapH); - AND_GIVEN("Afterwards I left-click on a slightly different red pixel"){ - cv::Mat differentRedTestImage {cv::Size(50, 50), CV_8UC3, cv::Scalar(170,235,220)}; + AND_GIVEN("Afterwards I left-click on a slightly different red pixel") + { + cv::Mat differentRedTestImage{cv::Size(50, 50), CV_8UC3, cv::Scalar(170, 235, 220)}; cv::cvtColor(differentRedTestImage, differentRedTestImage, cv::COLOR_HSV2BGR); pet.updateImage(differentRedTestImage); @@ -135,7 +145,8 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, viewCenter); eventList.simulate(pet.getView()->viewport()); - THEN("The selected color is expanded accordingly"){ + THEN("The selected color is expanded accordingly") + { // new lower bound on Hue is 340 - 10 -> 330 fromHue = 330; // 330 (fromHue) - 3 (toHue) = 327 @@ -149,14 +160,16 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") // new upper bound on Value is 220 + 10 -> 230 toVal = 230; - checkSelectedColor(con, invHue, toHue, fromHue, toSat, fromSat, toVal, fromVal, mapX, mapW, mapY, mapH); + checkSelectedColor( + con, invHue, toHue, fromHue, toSat, fromSat, toVal, fromVal, mapX, mapW, mapY, mapH); } } } } - AND_GIVEN("I shift+click on a red-isch/magenta pixel (Hue=340)"){ - cv::Mat magentaTestImage {cv::Size(50, 50), CV_8UC3, cv::Scalar(170,235,220)}; + AND_GIVEN("I shift+click on a red-isch/magenta pixel (Hue=340)") + { + cv::Mat magentaTestImage{cv::Size(50, 50), CV_8UC3, cv::Scalar(170, 235, 220)}; cv::cvtColor(magentaTestImage, magentaTestImage, cv::COLOR_HSV2BGR); pet.updateImage(magentaTestImage); @@ -167,8 +180,9 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") REQUIRE(!con->getColorPlot()->getMapItem()->getActMapInvHue()); - AND_GIVEN("Afterwards I click on an red image (Hue=10)"){ - cv::Mat otherSideRedImage {cv::Size(50, 50), CV_8UC3, cv::Scalar(5,235,220)}; + AND_GIVEN("Afterwards I click on an red image (Hue=10)") + { + cv::Mat otherSideRedImage{cv::Size(50, 50), CV_8UC3, cv::Scalar(5, 235, 220)}; cv::cvtColor(otherSideRedImage, otherSideRedImage, cv::COLOR_HSV2BGR); pet.updateImage(otherSideRedImage); @@ -176,13 +190,14 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, viewCenter); eventList.simulate(pet.getView()->viewport()); - THEN("Inverse hue gets checked"){ /*Lieber color changed accordingly und dementsprechend weiterarbeiten?*/ + THEN("Inverse hue gets checked") + { /*Lieber color changed accordingly und dementsprechend weiterarbeiten?*/ REQUIRE(con->getColorPlot()->getMapItem()->getActMapInvHue()); - } } - AND_GIVEN("Afterwards I click on an pink Image (Hue=320)"){ - cv::Mat pinkTestImage {cv::Size(50, 50), CV_8UC3, cv::Scalar(160,235,220)}; + AND_GIVEN("Afterwards I click on an pink Image (Hue=320)") + { + cv::Mat pinkTestImage{cv::Size(50, 50), CV_8UC3, cv::Scalar(160, 235, 220)}; cv::cvtColor(pinkTestImage, pinkTestImage, cv::COLOR_HSV2BGR); pet.updateImage(pinkTestImage); @@ -191,30 +206,31 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier, viewCenter); eventList.simulate(pet.getView()->viewport()); - THEN("I still do not use inverse Hue"){ + THEN("I still do not use inverse Hue") + { REQUIRE(!con->getColorPlot()->getMapItem()->getActMapInvHue()); } } } - AND_GIVEN("I shift+click on one specific pixel"){ - cv::Mat newTestImage {cv::Size(50, 50), CV_8UC3, cv::Scalar(50,235,220)}; + AND_GIVEN("I shift+click on one specific pixel") + { + cv::Mat newTestImage{cv::Size(50, 50), CV_8UC3, cv::Scalar(50, 235, 220)}; // set middle Pixel (clicked pixel) to other Value - newTestImage.at<cv::Vec3b>(cv::Point(25,25)) = cv::Vec3b(100,255,255); + newTestImage.at<cv::Vec3b>(cv::Point(25, 25)) = cv::Vec3b(100, 255, 255); cv::cvtColor(newTestImage, newTestImage, cv::COLOR_HSV2BGR); pet.updateImage(newTestImage); - QMouseEvent event {QEvent::HoverMove, QPoint(25, 25), Qt::NoButton, Qt::NoButton, Qt::NoModifier}; + QMouseEvent event{QEvent::HoverMove, QPoint(25, 25), Qt::NoButton, Qt::NoButton, Qt::NoModifier}; - QPointF pointOnScene = pet.getImageItem()->mapToScene(QPoint(25, 25)); - QPoint pointOnViewport = pet.getView()->mapFromScene(pointOnScene); + QPointF pointOnScene = pet.getImageItem()->mapToScene(QPoint(25, 25)); + QPoint pointOnViewport = pet.getView()->mapFromScene(pointOnScene); // Only after a click the hover event setting mMousePosOnImage gets fired. Focus? - eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::ShiftModifier, - pointOnViewport); - eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::ShiftModifier, - pointOnViewport); + eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::ShiftModifier, pointOnViewport); + eventList.addMouseClick(Qt::MouseButton::LeftButton, Qt::KeyboardModifier::ShiftModifier, pointOnViewport); eventList.simulate(pet.getView()->viewport()); - THEN("I get a color selection fitting this single pixel"){ + THEN("I get a color selection fitting this single pixel") + { bool invHue = false; // Upper Bound Hue 200 + 5 -> 205 Lower Bound: 200 - 5 -> 195 int fromHue = 195, toHue = 205; @@ -239,6 +255,6 @@ SCENARIO("I open PeTrack with a red image", "[ui][config]") SCENARIO("Open PeTrack check defaults", "[ui][config]") { - Petrack pet {}; + Petrack pet{}; REQUIRE(pet.getRecognizer().getRecoMethod() == reco::RecognitionMethod::MultiColor); } diff --git a/tests/unit_test/tst_io.cpp b/tests/unit_test/tst_io.cpp index 8b3835ebe0884467cb7c5f29525492259eeb285e..4aa678995d37dbc3c51f66b327d84d62138426ee 100644 --- a/tests/unit_test/tst_io.cpp +++ b/tests/unit_test/tst_io.cpp @@ -18,13 +18,13 @@ * along with this program. If not, see <https://cdwww.gnu.org/licenses/>. */ +#include "IO.h" +#include "moCapPerson.h" + #include <catch2/catch.hpp> #include <fstream> #include <ostream> -#include "IO.h" -#include "moCapPerson.h" - TEST_CASE("src/IO", "[tracking][io]") { SECTION("readHeightFile") @@ -44,7 +44,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readHeightFile("wrong.extension"); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, Catch::Matchers::Equals( + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals( "Cannot load wrong.extension maybe because of wrong file extension. Needs to be .txt.")); } @@ -56,7 +58,7 @@ TEST_CASE("src/IO", "[tracking][io]") REQUIRE_THAT(errorAsString, Catch::Matchers::Equals("No file provided.")); } - std::string heigtFileName{"heights.txt"}; + std::string heigtFileName{"heights.txt"}; std::ofstream heightFile(heigtFileName); heightFile << "# id z/cm" << std::endl; @@ -84,8 +86,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, - Catch::Matchers::Equals("Marker needs to be an integer value, but is 234.234")); + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals("Marker needs to be an integer value, but is 234.234")); } SECTION("arbitrary string") @@ -96,8 +99,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, - Catch::Matchers::Equals("Marker needs to be an integer value, but is WRONG")); + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals("Marker needs to be an integer value, but is WRONG")); } } @@ -111,8 +115,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, Catch::Matchers::Equals( - "Height needs to be a positive numerical value, but is WRONG")); + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals("Height needs to be a positive numerical value, but is WRONG")); } SECTION("not positive") @@ -123,8 +128,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, Catch::Matchers::Equals( - "Height needs to be a positive numerical value, but is 0")); + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals("Height needs to be a positive numerical value, but is 0")); } } @@ -136,7 +142,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, Catch::Matchers::Equals( + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals( "Line should contain exactly 2 values: id height. But it contains 4 entries.")); } @@ -148,7 +156,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, Catch::Matchers::Equals( + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals( "Line should contain exactly 2 values: id height. But it contains 1 entries.")); } } @@ -159,7 +169,7 @@ TEST_CASE("src/IO", "[tracking][io]") SECTION("correct input") { - std::string heigtFileName{"heights.txt"}; + std::string heigtFileName{"heights.txt"}; std::ofstream heightFile(heigtFileName); SECTION("file empty") @@ -172,35 +182,35 @@ TEST_CASE("src/IO", "[tracking][io]") } std::unordered_map<int, float> referenceValuesMap{ - {987, 184}, //NOLINT - {988, 179}, //NOLINT - {989, 177.5}, //NOLINT - {990, 154.5}, //NOLINT - {991, 177}, //NOLINT - {992, 177}, //NOLINT - {993, 175.5}, //NOLINT - {994, 194}, //NOLINT - {995, 177}, //NOLINT - {996, 167}, //NOLINT - {997, 174}, //NOLINT - {998, 190}, //NOLINT - {999, 174} //NOLINT + {987, 184}, // NOLINT + {988, 179}, // NOLINT + {989, 177.5}, // NOLINT + {990, 154.5}, // NOLINT + {991, 177}, // NOLINT + {992, 177}, // NOLINT + {993, 175.5}, // NOLINT + {994, 194}, // NOLINT + {995, 177}, // NOLINT + {996, 167}, // NOLINT + {997, 174}, // NOLINT + {998, 190}, // NOLINT + {999, 174} // NOLINT }; std::vector<std::pair<int, float>> referenceValuesVec; referenceValuesVec.assign(std::begin(referenceValuesMap), std::end(referenceValuesMap)); SECTION("no comments") { - std::for_each(std::begin(referenceValuesMap), std::end(referenceValuesMap), - [&heightFile](const std::pair<int, float> & element) - { - heightFile << element.first << " " << element.second << std::endl; - }); + std::for_each( + std::begin(referenceValuesMap), + std::end(referenceValuesMap), + [&heightFile](const std::pair<int, float> &element) + { heightFile << element.first << " " << element.second << std::endl; }); heightFile.close(); auto ret = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::unordered_map<int, float>>(ret)); - std::unordered_map<int, float> markerHeights = std::get<std::unordered_map<int, float>>(ret); + std::unordered_map<int, float> markerHeights = std::get<std::unordered_map<int, float>>(ret); std::vector<std::pair<int, float>> markerHeightsVec; markerHeightsVec.assign(std::begin(markerHeights), std::end(markerHeights)); CHECK_THAT(markerHeightsVec, Catch::UnorderedEquals(referenceValuesVec)); @@ -210,16 +220,16 @@ TEST_CASE("src/IO", "[tracking][io]") SECTION("z-coordinate in cm") { heightFile << "# id z/cm" << std::endl; - std::for_each(std::begin(referenceValuesMap), std::end(referenceValuesMap), - [&heightFile](const std::pair<int, float> & element) - { - heightFile << element.first << " " << element.second << std::endl; - }); + std::for_each( + std::begin(referenceValuesMap), + std::end(referenceValuesMap), + [&heightFile](const std::pair<int, float> &element) + { heightFile << element.first << " " << element.second << std::endl; }); heightFile.close(); auto ret = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::unordered_map<int, float>>(ret)); - std::unordered_map<int, float> markerHeights = std::get<std::unordered_map<int, float>>(ret); + std::unordered_map<int, float> markerHeights = std::get<std::unordered_map<int, float>>(ret); std::vector<std::pair<int, float>> markerHeightsVec; markerHeightsVec.assign(std::begin(markerHeights), std::end(markerHeights)); CHECK_THAT(markerHeightsVec, Catch::UnorderedEquals(referenceValuesVec)); @@ -228,16 +238,16 @@ TEST_CASE("src/IO", "[tracking][io]") SECTION("z-coordinate in m") { heightFile << "# id z/m" << std::endl; - std::for_each(std::begin(referenceValuesMap), std::end(referenceValuesMap), - [&heightFile](const std::pair<int, float> & element) - { - heightFile << element.first << " " << element.second/100.F << std::endl; - }); + std::for_each( + std::begin(referenceValuesMap), + std::end(referenceValuesMap), + [&heightFile](const std::pair<int, float> &element) + { heightFile << element.first << " " << element.second / 100.F << std::endl; }); heightFile.close(); auto ret = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::unordered_map<int, float>>(ret)); - std::unordered_map<int, float> markerHeights = std::get<std::unordered_map<int, float>>(ret); + std::unordered_map<int, float> markerHeights = std::get<std::unordered_map<int, float>>(ret); std::vector<std::pair<int, float>> markerHeightsVec; markerHeightsVec.assign(std::begin(markerHeights), std::end(markerHeights)); @@ -247,23 +257,22 @@ TEST_CASE("src/IO", "[tracking][io]") SECTION("z-coordinate unit not specified") { heightFile << "# id z/not_specifies" << std::endl; - std::for_each(std::begin(referenceValuesMap), std::end(referenceValuesMap), - [&heightFile](const std::pair<int, float> & element) - { - heightFile << element.first << " " << element.second << std::endl; - }); + std::for_each( + std::begin(referenceValuesMap), + std::end(referenceValuesMap), + [&heightFile](const std::pair<int, float> &element) + { heightFile << element.first << " " << element.second << std::endl; }); heightFile.close(); auto ret = IO::readHeightFile(QString::fromStdString(heigtFileName)); REQUIRE(std::holds_alternative<std::unordered_map<int, float>>(ret)); - std::unordered_map<int, float> markerHeights = std::get<std::unordered_map<int, float>>(ret); + std::unordered_map<int, float> markerHeights = std::get<std::unordered_map<int, float>>(ret); std::vector<std::pair<int, float>> markerHeightsVec; markerHeightsVec.assign(std::begin(markerHeights), std::end(markerHeights)); CHECK_THAT(markerHeightsVec, Catch::UnorderedEquals(referenceValuesVec)); } std::remove(heigtFileName.c_str()); - } } @@ -284,7 +293,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readMarkerIDFile("wrong.extension"); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, Catch::Matchers::Equals( + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals( "Cannot load wrong.extension maybe because of wrong file extension. Needs to be .txt.")); } @@ -296,7 +307,7 @@ TEST_CASE("src/IO", "[tracking][io]") REQUIRE_THAT(errorAsString, Catch::Matchers::Equals("No file provided.")); } - std::string markerFileName{"marker.txt"}; + std::string markerFileName{"marker.txt"}; std::ofstream markerFile(markerFileName); markerFile << "# id markerID" << std::endl; @@ -324,8 +335,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readMarkerIDFile(QString::fromStdString(markerFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, - Catch::Matchers::Equals("PersonID needs to be an integer value, but is 234.234")); + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals("PersonID needs to be an integer value, but is 234.234")); } SECTION("arbitrary string") @@ -336,8 +348,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readMarkerIDFile(QString::fromStdString(markerFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, - Catch::Matchers::Equals("PersonID needs to be an integer value, but is WRONG")); + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals("PersonID needs to be an integer value, but is WRONG")); } } @@ -351,8 +364,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readMarkerIDFile(QString::fromStdString(markerFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, - Catch::Matchers::Equals("MarkerID needs to be an integer value, but is 43.56")); + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals("MarkerID needs to be an integer value, but is 43.56")); } SECTION("arbitrary string") @@ -363,8 +377,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readMarkerIDFile(QString::fromStdString(markerFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, - Catch::Matchers::Equals("MarkerID needs to be an integer value, but is WRONG")); + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals("MarkerID needs to be an integer value, but is WRONG")); } } @@ -376,7 +391,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readMarkerIDFile(QString::fromStdString(markerFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, Catch::Matchers::Equals( + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals( "Line should contain exactly 2 values: personID markerID. But it contains 4 entries.")); } @@ -388,7 +405,9 @@ TEST_CASE("src/IO", "[tracking][io]") auto errorMessage = IO::readMarkerIDFile(QString::fromStdString(markerFileName)); REQUIRE(std::holds_alternative<std::string>(errorMessage)); std::string errorAsString = std::get<std::string>(errorMessage); - REQUIRE_THAT(errorAsString, Catch::Matchers::Equals( + REQUIRE_THAT( + errorAsString, + Catch::Matchers::Equals( "Line should contain exactly 2 values: personID markerID. But it contains 1 entries.")); } } @@ -398,7 +417,7 @@ TEST_CASE("src/IO", "[tracking][io]") SECTION("correct input") { - std::string markerFileName{"marker.txt"}; + std::string markerFileName{"marker.txt"}; std::ofstream markerFile(markerFileName); SECTION("file empty") @@ -411,26 +430,26 @@ TEST_CASE("src/IO", "[tracking][io]") } std::unordered_map<int, int> referenceValuesMap{ - {1, 987}, //NOLINT - {2, 988}, //NOLINT - {3, 989}, //NOLINT - {4, 990}, //NOLINT - {5, 991}, //NOLINT - {6, 992}, //NOLINT - {7, 993}, //NOLINT - {8, 994}, //NOLINT - {9, 995}, //NOLINT - {10, 996}, //NOLINT - {11, 997}, //NOLINT - {12, 998}, //NOLINT - {14, 999} //NOLINT + {1, 987}, // NOLINT + {2, 988}, // NOLINT + {3, 989}, // NOLINT + {4, 990}, // NOLINT + {5, 991}, // NOLINT + {6, 992}, // NOLINT + {7, 993}, // NOLINT + {8, 994}, // NOLINT + {9, 995}, // NOLINT + {10, 996}, // NOLINT + {11, 997}, // NOLINT + {12, 998}, // NOLINT + {14, 999} // NOLINT }; std::vector<std::pair<int, int>> referenceValuesVec; referenceValuesVec.assign(std::begin(referenceValuesMap), std::end(referenceValuesMap)); SECTION("no comments") { - for (const auto & [personID, markerID] : referenceValuesMap) + for(const auto &[personID, markerID] : referenceValuesMap) { markerFile << personID << " " << markerID << std::endl; } @@ -438,7 +457,7 @@ TEST_CASE("src/IO", "[tracking][io]") auto ret = IO::readMarkerIDFile(QString::fromStdString(markerFileName)); REQUIRE(std::holds_alternative<std::unordered_map<int, int>>(ret)); - auto markerIDs = std::get<std::unordered_map<int, int>>(ret); + auto markerIDs = std::get<std::unordered_map<int, int>>(ret); std::vector<std::pair<int, int>> markerHeightsVec; markerHeightsVec.assign(std::begin(markerIDs), std::end(markerIDs)); CHECK_THAT(markerHeightsVec, Catch::UnorderedEquals(referenceValuesVec)); @@ -447,7 +466,7 @@ TEST_CASE("src/IO", "[tracking][io]") SECTION("with comments") { markerFile << "# this is a comment at the beginning" << std::endl; - for (const auto & [personID, markerID] : referenceValuesMap) + for(const auto &[personID, markerID] : referenceValuesMap) { markerFile << personID << " " << markerID << std::endl; markerFile << "# this is a comment in the middle" << std::endl; @@ -457,7 +476,7 @@ TEST_CASE("src/IO", "[tracking][io]") auto ret = IO::readMarkerIDFile(QString::fromStdString(markerFileName)); REQUIRE(std::holds_alternative<std::unordered_map<int, int>>(ret)); - auto markerIDs = std::get<std::unordered_map<int, int>>(ret); + auto markerIDs = std::get<std::unordered_map<int, int>>(ret); std::vector<std::pair<int, int>> markerHeightsVec; markerHeightsVec.assign(std::begin(markerIDs), std::end(markerIDs)); CHECK_THAT(markerHeightsVec, Catch::UnorderedEquals(referenceValuesVec)); @@ -482,14 +501,16 @@ SCENARIO("I want to read a XSens c3d file", "[io]") unit.set("cm"); c3d.parameter("POINT", unit); - for(int i = 0; i < 64; ++i){ - c3d.point("marker_" + std::to_string(i+1)); + for(int i = 0; i < 64; ++i) + { + c3d.point("marker_" + std::to_string(i + 1)); } - ezc3d::DataNS::Frame f; - int nPoints(c3d.parameters().group("POINT").parameter("USED").valuesAsInt()[0]); + ezc3d::DataNS::Frame f; + int nPoints(c3d.parameters().group("POINT").parameter("USED").valuesAsInt()[0]); ezc3d::DataNS::Points3dNS::Points pts; - for (size_t i=0; i<static_cast<size_t>(nPoints); ++i){ + for(size_t i = 0; i < static_cast<size_t>(nPoints); ++i) + { ezc3d::DataNS::Points3dNS::Point pt; // See i-value via x/y/z value pt.x(i); @@ -498,17 +519,21 @@ SCENARIO("I want to read a XSens c3d file", "[io]") pts.point(pt); } f.add(pts); - for(int i = 0; i < 10; ++i){ + for(int i = 0; i < 10; ++i) + { c3d.frame(f); } AND_GIVEN("I read that c3d-file into a MoCapPerson") { MoCapPerson person; - auto c3dToPoint3f = [](ezc3d::DataNS::Points3dNS::Point point){ - return cv::Point3f{static_cast<float>(point.x()), - static_cast<float>(point.y()), - static_cast<float>(point.z())} * 1; + auto c3dToPoint3f = [](ezc3d::DataNS::Points3dNS::Point point) + { + return cv::Point3f{ + static_cast<float>(point.x()), + static_cast<float>(point.y()), + static_cast<float>(point.z())} * + 1; }; IO::readSkeletonC3D_XSENS(c3d, person, c3dToPoint3f); @@ -516,15 +541,12 @@ SCENARIO("I want to read a XSens c3d file", "[io]") THEN("The MoCapPerson is properly initialized") { auto skeleton = person.getSkeleton(0); - auto root = skeleton.getRoot(); + auto root = skeleton.getRoot(); // NOTE checking everything should be part of a test for the SkeletonFactory - REQUIRE(root.getPos() == cv::Point3f{7,7,7}); // pSacrum point[7] - REQUIRE(root.getChildById(1).getPos() == cv::Point3f(15,15,15)); // pC7SpinalProcess point[15] + REQUIRE(root.getPos() == cv::Point3f{7, 7, 7}); // pSacrum point[7] + REQUIRE(root.getChildById(1).getPos() == cv::Point3f(15, 15, 15)); // pC7SpinalProcess point[15] } } } - } - - diff --git a/tests/unit_test/tst_moCapController.cpp b/tests/unit_test/tst_moCapController.cpp index 581008dbc3653a4418271307042ab1a9c1b2cd3a..956d0c58838a931525bdb0efcb5f684cd344ee7c 100644 --- a/tests/unit_test/tst_moCapController.cpp +++ b/tests/unit_test/tst_moCapController.cpp @@ -18,12 +18,12 @@ * along with this program. If not, see <https://cdwww.gnu.org/licenses/>. */ -#include <catch2/catch.hpp> -#include <catch2/trompeloeil.hpp> - #include "moCapController.h" #include "moCapPerson.h" +#include <catch2/catch.hpp> +#include <catch2/trompeloeil.hpp> + using namespace Catch::Matchers; class ExtrCalibMock : public trompeloeil::mock_interface<ExtrCalibration> @@ -36,20 +36,21 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") { MoCapStorage storage; // TODO without any persons in the storage?? (Other Scenario) - // NOTE SkeletonTree needs nodes with id 1 and 2 which are connected in the right order, but we do not enforce that in any way + // NOTE SkeletonTree needs nodes with id 1 and 2 which are connected in the right order, but we do not enforce that + // in any way /* * Resulting Lines should be: root to child; child to grandchild; */ - SkeletonNode rootA {0, cv::Point3f{100,100,0}}; - SkeletonNode& childA = rootA.addChild({1, cv::Point3f{200, 100, 69}}); - SkeletonNode& grandchildA = childA.addChild({1, cv::Point3f{50,50,42}}); - grandchildA.addChild({2, cv::Point3f{150,150,1337}}); + SkeletonNode rootA{0, cv::Point3f{100, 100, 0}}; + SkeletonNode &childA = rootA.addChild({1, cv::Point3f{200, 100, 69}}); + SkeletonNode &grandchildA = childA.addChild({1, cv::Point3f{50, 50, 42}}); + grandchildA.addChild({2, cv::Point3f{150, 150, 1337}}); - SkeletonNode rootB {0, cv::Point3f{50,50,0}}; - SkeletonNode& childB = rootB.addChild({1, cv::Point3f{100, 50, 69}}); - SkeletonNode& grandchildB = childB.addChild({1, cv::Point3f{25,25,42}}); - grandchildB.addChild({2, cv::Point3f{75,75,1337}}); + SkeletonNode rootB{0, cv::Point3f{50, 50, 0}}; + SkeletonNode &childB = rootB.addChild({1, cv::Point3f{100, 50, 69}}); + SkeletonNode &grandchildB = childB.addChild({1, cv::Point3f{25, 25, 42}}); + grandchildB.addChild({2, cv::Point3f{75, 75, 1337}}); MoCapPerson person; person.setSamplerate(1); @@ -64,14 +65,13 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") * for this test and ignore different projections from * 3D to 2D due to different settings */ - ALLOW_CALL(extrCalib, getImagePoint(ANY(cv::Point3f))) - .RETURN(cv::Point2f(_1.x,_1.y)); + ALLOW_CALL(extrCalib, getImagePoint(ANY(cv::Point3f))).RETURN(cv::Point2f(_1.x, _1.y)); - MoCapController moCapController {storage, extrCalib}; + MoCapController moCapController{storage, extrCalib}; GIVEN("a skeleton with a head direction") { - person.addSkeleton({rootA, Vec3F{1,0,0}}); + person.addSkeleton({rootA, Vec3F{1, 0, 0}}); // TODO Person entsprechend anpassen // NOTE Also am besten Person in der arrow/narrow GIVEN aufbauen AND_GIVEN("no interpolation") @@ -81,17 +81,20 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") THEN("we get the correct render data") { // Get renderData for Second 0, which would be sample 1 (samplerate set to 1) - std::vector<SegmentRenderData> renderData = moCapController.getRenderData(0,25); - SegmentRenderData schablone; + std::vector<SegmentRenderData> renderData = moCapController.getRenderData(0, 25); + SegmentRenderData schablone; schablone.mThickness = 2; - schablone.mColor = QColor(255,255,55); - schablone.mDirected = false; + schablone.mColor = QColor(255, 255, 55); + schablone.mDirected = false; std::vector<SegmentRenderData> correctData; - schablone.mLine = QLine(100,100,200,100); correctData.push_back(schablone); - schablone.mLine = QLine(200,100,50,50); correctData.push_back(schablone); - schablone.mLine = QLine(50,50,150,150); correctData.push_back(schablone); + schablone.mLine = QLine(100, 100, 200, 100); + correctData.push_back(schablone); + schablone.mLine = QLine(200, 100, 50, 50); + correctData.push_back(schablone); + schablone.mLine = QLine(50, 50, 150, 150); + correctData.push_back(schablone); schablone.mDirected = true; - schablone.mLine = QLine(125, 125, 1427, 125); + schablone.mLine = QLine(125, 125, 1427, 125); correctData.push_back(schablone); REQUIRE_THAT(renderData, UnorderedEquals(correctData)); @@ -99,23 +102,26 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") } AND_GIVEN("interpolation") { - person.addSkeleton({rootB, Vec3F{0,1,0}}); + person.addSkeleton({rootB, Vec3F{0, 1, 0}}); storage.addPerson(person); THEN("we get the correct render data") { // Get renderData for Second 1.5, which would be sample 1.5 (samplerate set to 1) - auto renderData = moCapController.getRenderData(25,50); + auto renderData = moCapController.getRenderData(25, 50); SegmentRenderData schablone; schablone.mThickness = 2; - schablone.mColor = QColor(255,255,55); - schablone.mDirected = false; + schablone.mColor = QColor(255, 255, 55); + schablone.mDirected = false; std::vector<SegmentRenderData> correctData; - schablone.mLine = QLine(75,75, 150, 75); correctData.push_back(schablone); - schablone.mLine = QLine(150,75, 37, 37); correctData.push_back(schablone); - schablone.mLine = QLine(37, 37, 112,112); correctData.push_back(schablone); + schablone.mLine = QLine(75, 75, 150, 75); + correctData.push_back(schablone); + schablone.mLine = QLine(150, 75, 37, 37); + correctData.push_back(schablone); + schablone.mLine = QLine(37, 37, 112, 112); + correctData.push_back(schablone); schablone.mDirected = true; - schablone.mLine = QLine(93, 93, 1012, 1012); + schablone.mLine = QLine(93, 93, 1012, 1012); correctData.push_back(schablone); REQUIRE_THAT(renderData, UnorderedEquals(correctData)); @@ -129,10 +135,11 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") { THEN("the lines are blue") { - QColor blue {0,0,255}; + QColor blue{0, 0, 255}; moCapController.setColor(blue); - auto renderData = moCapController.getRenderData(0,25); - for(const auto &line : renderData){ + auto renderData = moCapController.getRenderData(0, 25); + for(const auto &line : renderData) + { REQUIRE(line.mColor == blue); } } @@ -144,8 +151,9 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") { int thickness = 4; moCapController.setThickness(thickness); - auto renderData = moCapController.getRenderData(0,25); - for(const auto &line : renderData){ + auto renderData = moCapController.getRenderData(0, 25); + for(const auto &line : renderData) + { REQUIRE(line.mThickness == thickness); } } @@ -155,7 +163,7 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") { // NOTE if current frame is 0, then pre-sample is just 0; possible to have no pre-sample? int currentFrame = -10; - int framerate = 25; + int framerate = 25; THEN("no render data is generated") { auto renderData = moCapController.getRenderData(currentFrame, framerate); @@ -165,7 +173,7 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") AND_GIVEN("no post-sample") { int currentFrame = 10; - int framerate = 25; + int framerate = 25; THEN("no render data is generated") { auto renderData = moCapController.getRenderData(currentFrame, framerate); @@ -175,7 +183,7 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") AND_GIVEN("neither pre- or post-sample") { int currentFrame = 100; - int framerate = 25; + int framerate = 25; THEN("no render data is generated") { auto renderData = moCapController.getRenderData(currentFrame, framerate); diff --git a/tests/unit_test/tst_recognition.cpp b/tests/unit_test/tst_recognition.cpp index 758c1cb4b2ac3faabdba6b272b45e8a828612909..e30a226fb7fb3f5b8c2eb112166df7715000e71d 100644 --- a/tests/unit_test/tst_recognition.cpp +++ b/tests/unit_test/tst_recognition.cpp @@ -18,12 +18,11 @@ * along with this program. If not, see <https://cdwww.gnu.org/licenses/>. */ -#include <catch2/catch.hpp> +#include "petrack.h" +#include "recognition.h" #include <QSignalSpy> - -#include "recognition.h" -#include "petrack.h" +#include <catch2/catch.hpp> using namespace reco; @@ -42,26 +41,25 @@ TEST_CASE("src/recognition", "[recognition]") } } -SCENARIO("I change Aruco parameters (via UI)"){ +SCENARIO("I change Aruco parameters (via UI)") +{ CodeMarkerOptions options; - GIVEN("I change the detector params"){ - QSignalSpy spy{&options, &CodeMarkerOptions::detectorParamsChanged}; + GIVEN("I change the detector params") + { + QSignalSpy spy{&options, &CodeMarkerOptions::detectorParamsChanged}; ArucoCodeParams params; params.setAdaptiveThreshConstant(20); options.setDetectorParams(params); - THEN("A corresponding change signal was emitted"){ - REQUIRE(spy.count() == 1); - } + THEN("A corresponding change signal was emitted") { REQUIRE(spy.count() == 1); } } - GIVEN("I change the index of the marker dict"){ + GIVEN("I change the index of the marker dict") + { QSignalSpy spy{&options, &CodeMarkerOptions::indexOfMarkerDictChanged}; - const int newIndex = options.getIndexOfMarkerDict() + 1; + const int newIndex = options.getIndexOfMarkerDict() + 1; options.setIndexOfMarkerDict(newIndex); - THEN("A corresponding change signal was emitted"){ - REQUIRE(spy.count() == 1); - } + THEN("A corresponding change signal was emitted") { REQUIRE(spy.count() == 1); } } } @@ -70,10 +68,10 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") ArucoCodeParams params; GIVEN("I set a minimum larger than the maximum") { - const int newAdaptiveThreshWinSizeMin = params.getAdaptiveThreshWinSizeMax() + 1; - const double newMinMarkerPerimeter = params.getMaxMarkerPerimeter() + 1; - const auto oldAdaptiveThreshWinSizeMin = params.getAdaptiveThreshWinSizeMin(); - const auto oldMinMarkerPerimeter = params.getMinMarkerPerimeter(); + const int newAdaptiveThreshWinSizeMin = params.getAdaptiveThreshWinSizeMax() + 1; + const double newMinMarkerPerimeter = params.getMaxMarkerPerimeter() + 1; + const auto oldAdaptiveThreshWinSizeMin = params.getAdaptiveThreshWinSizeMin(); + const auto oldMinMarkerPerimeter = params.getMinMarkerPerimeter(); THEN("An exception is thrown and values aren't changed") { REQUIRE_THROWS(params.setAdaptiveThreshWinSizeMin(newAdaptiveThreshWinSizeMin)); @@ -85,10 +83,10 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("I set a maximum lower than the minimum") { - const int newAdaptiveThreshSizeMax = params.getAdaptiveThreshWinSizeMin() - 1; - const double newMaxMarkerPerimeter = params.getMinMarkerPerimeter() - 1; - const auto oldAdaptiveThreshWinSizeMax = params.getAdaptiveThreshWinSizeMax(); - const auto oldMaxMarkerPerimeter = params.getMaxMarkerPerimeter(); + const int newAdaptiveThreshSizeMax = params.getAdaptiveThreshWinSizeMin() - 1; + const double newMaxMarkerPerimeter = params.getMinMarkerPerimeter() - 1; + const auto oldAdaptiveThreshWinSizeMax = params.getAdaptiveThreshWinSizeMax(); + const auto oldMaxMarkerPerimeter = params.getMaxMarkerPerimeter(); THEN("An exception is thrown and values aren't changed") { REQUIRE_THROWS(params.setAdaptiveThreshWinSizeMax(newAdaptiveThreshSizeMax)); @@ -101,7 +99,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("A cornerRefinementWinSize less than 1") { constexpr int newCornerRefinementWinSize = -2; - const int oldCornerRefinementWinSize = params.getCornerRefinementWinSize(); + const int oldCornerRefinementWinSize = params.getCornerRefinementWinSize(); THEN("An Exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setCornerRefinementWinSize(newCornerRefinementWinSize)); @@ -112,7 +110,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("A cornerRefinementMaxIterations less than 1") { constexpr int newCornerRefinementMaxIterations = 0; - const int oldCornerRefinementMaxIterations = params.getCornerRefinementMaxIterations(); + const int oldCornerRefinementMaxIterations = params.getCornerRefinementMaxIterations(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setCornerRefinementMaxIterations(newCornerRefinementMaxIterations)); @@ -123,7 +121,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("A cornerRefinementMinAccuracy less than or equal to 0") { constexpr double newCornerRefinementMinAccuracy = -3; - const auto oldCornerRefinementMinAccuracy = params.getCornerRefinementMinAccuracy(); + const auto oldCornerRefinementMinAccuracy = params.getCornerRefinementMinAccuracy(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setCornerRefinementMinAccuracy(newCornerRefinementMinAccuracy)); @@ -134,7 +132,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("markerBorderBits less than 1") { constexpr int newBorderBits = 0; - const int oldBorderBits = params.getMarkerBorderBits(); + const int oldBorderBits = params.getMarkerBorderBits(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setMarkerBorderBits(newBorderBits)); @@ -145,7 +143,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("minStdDevOtsu less than or equal to 0") { constexpr double newMinOtsuStdDev = -2; - const auto oldMinOtsuStdDev = params.getMinOtsuStdDev(); + const auto oldMinOtsuStdDev = params.getMinOtsuStdDev(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setMinOtsuStdDev(newMinOtsuStdDev)); @@ -156,8 +154,9 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("adaptiveThreshSizeMin less than 3") { constexpr int newThreshSizeMin = 2; - const int oldThreshSizeMin = params.getAdaptiveThreshWinSizeMin(); - THEN("An exception is thrown and value isn't changed"){ + const int oldThreshSizeMin = params.getAdaptiveThreshWinSizeMin(); + THEN("An exception is thrown and value isn't changed") + { REQUIRE_THROWS(params.setAdaptiveThreshWinSizeMin(newThreshSizeMin)); REQUIRE(params.getAdaptiveThreshWinSizeMin() == oldThreshSizeMin); } @@ -166,7 +165,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("adaptiveThreshSizeMax less than 3") { constexpr int newThreshWinSizeMax = 2; - const int oldThreshWinSizeMax = params.getAdaptiveThreshWinSizeMax(); + const int oldThreshWinSizeMax = params.getAdaptiveThreshWinSizeMax(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setAdaptiveThreshWinSizeMax(newThreshWinSizeMax)); @@ -177,7 +176,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("adaptiveThreshWinSizeStep less than or equal to 0") { constexpr int newWinSizeStep = 0; - const int oldWinSizeStep = params.getAdaptiveThreshWinSizeStep(); + const int oldWinSizeStep = params.getAdaptiveThreshWinSizeStep(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setAdaptiveThreshWinSizeStep(newWinSizeStep)); @@ -188,7 +187,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("minMarkerPerimeter less than or equal to 0") { constexpr double newMinMarkerPerimeter = 0; - const auto oldMinMarkerPerimeter = params.getMinMarkerPerimeter(); + const auto oldMinMarkerPerimeter = params.getMinMarkerPerimeter(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setMinMarkerPerimeter(newMinMarkerPerimeter)); @@ -199,7 +198,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("maxMarkerPerimeter less than or equal to 0") { constexpr double newMaxMarkerPerimeter = 0; - const auto oldMaxMarkerPerimeter = params.getMaxMarkerPerimeter(); + const auto oldMaxMarkerPerimeter = params.getMaxMarkerPerimeter(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setMaxMarkerPerimeter(newMaxMarkerPerimeter)); @@ -210,7 +209,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("cornerRefinementMinAccuracy less than or equal to 0") { constexpr double newMinAccuracy = 0; - const auto oldMinAccuracy = params.getCornerRefinementMinAccuracy(); + const auto oldMinAccuracy = params.getCornerRefinementMinAccuracy(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setCornerRefinementMinAccuracy(newMinAccuracy)); @@ -221,7 +220,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("minCornerDistance less than 0") { constexpr double newMinCornerDistance = -1; - const auto oldMinCornerDistance = params.getMinMarkerDistance(); + const auto oldMinCornerDistance = params.getMinMarkerDistance(); THEN("An exception is thrown and value isn't changed") { REQUIRE_THROWS(params.setMinCornerDistance(newMinCornerDistance)); @@ -232,7 +231,7 @@ SCENARIO("I use the setter/getter of ArucoCodeParams") GIVEN("minDistanceToBorder less than 0") { constexpr int newMinDistToBorder = -2; - const int oldMinDistToBorder = params.getMinDistanceToBorder(); + const int oldMinDistToBorder = params.getMinDistanceToBorder(); THEN("An exception is thown and value isn't changed") { REQUIRE_THROWS(params.setMinDistanceToBorder(newMinDistToBorder));