/*********************************************************************** * This file is part of Scanned Image Extract. * * Scanned Image Extract is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Scanned Image Extract is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Scanned Image Extract. If not, see * * * Copyright (C) 2015, Dominik Rueß; info@dominik-ruess.de **********************************************************************/ #ifndef PRELOADSOURCE_H #define PRELOADSOURCE_H #include #include #include #include #include #include #include #include "sourcefile.h" #include #define MAX_AREA_OVERLAP 0.3 class PreloadSource : public QThread { Q_OBJECT public: explicit PreloadSource(QObject *parent = 0); ~PreloadSource(); static QMutex preloadMutex; static QWaitCondition waitFinished; void addLoadFiles(const SourceFilePtr& file, const int position, const bool highPriority=false, const bool onlyLoadImages = false); void clear(); void newTargets(SourceFilePtr& source, cv::Mat &alreadyLoaded, bool &locked); QString isCurrentlyLoading() const; void updateMinMax(const int, const int); void setThresh(const double thresh) { _threshold = thresh; } void setMaxAspect(const double maxAspect) { _maxAspect = maxAspect; } void setLevels(const int levels) { _levels = levels; } void setMaxOverlap(const double maxOverlap) { _maxOverlap = maxOverlap; } void setMinArea(const double minArea) { _minArea = minArea; } void setMinAreaWithinImage(const double minArea) { _minAreaWithinImage = minArea; } void setSplitMaxOffset(const double maxOffset) { _splitMaxOffsetFrac = maxOffset; } void setSplitMinCornerDist(const double minCornerDist) { _splitMinCornerDist = minCornerDist; } void setSplitMinLengthFrac(const double minLengthFrac) { _splitMinLengthFrac = minLengthFrac; } void setMaxHierarchyLevel(const int level) { _maxHierarchyLevel = level; } void setEnergyWeights(const float e1, // border energy const float e2, // area energy const float e3, // aspect energy const float e4) // frame content energy { _e1 =e1; _e2 = e2; _e3 = e3; _e4 = e4; } signals: void doneLoading(const SourceFilePtr&, const int position); public slots: void stop(); protected: void run(); private: void getSumOfRectangleSampling(const QVector pts, const cv::Mat &image, double &sumValues, long &numPixels); static void getSumOfRectangleSamplingF(const QVector pts, const cv::Mat &image, double &sumValues, long &numPixels); std::vector getThresholds(const cv::Mat &image, int &bestThresInd); void bestRectangles(const cv::Mat& imageOrig, const cv::Mat &boundaries, const cv::Vec3i &thresholds, const std::vector >& contours, const std::vector& hierarchy, const QVector& rects, const QVector >& points, QVector &energies, QVector& out); // max aspect ratio is x void rectangleOverlap(std::vector > &contours, QVector &rects, std::vector& hierarchy, QVector > &points, QVector > &sumOfContourLengths, QVector &valid) const; void computeContourLengths(const std::vector > &contours, const QVector& valid, QVector >& sumOfContourLengths); double distancePointLine(const cv::Point2f& LP1, const cv::Point2f& LP2, const cv::Point2f& p) const ; void removeFilaments(QVector > &sumOfContourLengths, const QVector &valid, std::vector >& contours ); double polyArea(const QVector& p) const; double polyAreaCV(const std::vector& p, const int from = 0, const int to = -1) const; std::vector extractRectangles(const std::vector& thresholds, const cv::Mat& image); std::vector extractLines(const std::vector &thresholds, const cv::Mat& image); /** * @brief findHistPeak find position'th peak from left or right * @param hist * @param fromRight * @param windowWidth * @param minPercentage * @param position * @return */ int findHistPeak(const cv::Mat& hist, const bool fromRight, const int windowWidth = 10, const float minPercentage = 0.3, const int position = 0) const; void preSelectFast(const cv::Mat &image, const std::vector >& contours, const std::vector& hierarchy, const QVector& rects, const QVector >& points, QVector& valid) const; void optimizeRectangle(const cv::Mat& edgeMask, cv::RotatedRect& rectangle); bool testAbort(SourceFilePtr sourceFile); static lbfgsfloatval_t evaluate( void *instance, const lbfgsfloatval_t *x, lbfgsfloatval_t *g, const int n, const lbfgsfloatval_t step ); cv::Mat loadAndShrink(const QString& filename); QVector > _filesToLoad; SourceFilePtr _current; QMutex _fileListMutex; QWaitCondition _condition; bool _stopped; bool _abortAndLoadNext; int _min; int _max; double _threshold; double _maxAspect; int _levels; float _maxOverlap; float _minArea; float _maxArea; float _minAreaWithinImage; float _splitMaxOffsetFrac; float _splitMinCornerDist; float _splitMinLengthFrac; int _maxHierarchyLevel; QString _currentFilename; int _imSize; int _histPositions; int _histWindowWidth; float _histMinPercentage; int _histSigma; int _cannyTr1; int _cannyTr2; int _medianBlurMask; int _houghRho; int _houghAngle; float _houghFactor; float _rectAngularThresh; float _rectMinLineDistFrac; float _rectMinDist; float _minFrameEnergy; double _maxAreaFractionEnergy; float _e1; float _e2; float _e3; float _e4; int _maxRectOptimizeIterations; int _minColorHeight; static cv::Mat _currentImageForRectOpt; const QImage::Format _qImageFmt; }; #endif // PRELOADSOURCE_H