From 88ec862f857a7790a07f7eaa5320f073be287a46 Mon Sep 17 00:00:00 2001 From: Max Breitenfeldt <git@mxbr.me> Date: Wed, 16 Jun 2021 15:47:20 +0200 Subject: [PATCH] Remove backgroundsubtraction code --- Src/BioTrackerPlugin.h | 1 + Src/CMakeLists.txt | 17 - Src/Controller/ControllerTrackingAlgorithm.h | 1 + Src/Model/BioTrackerTrackingAlgorithm.cpp | 12 - Src/Model/BioTrackerTrackingAlgorithm.h | 13 - Src/Model/Network/TcpListener.cpp | 69 -- Src/Model/Network/TcpListener.h | 31 - Src/Model/TrackedComponents/pose/FishPose.cpp | 10 +- Src/Model/TrackedComponents/pose/FishPose.h | 7 - Src/Model/TrackerParameter.h | 1 - Src/Model/TrackingAlgorithm/NN2dMapper.cpp | 326 ------- Src/Model/TrackingAlgorithm/NN2dMapper.h | 35 - Src/Model/TrackingAlgorithm/ParamNames.h | 86 -- .../imageProcessor/cvblobs/BlobContour.cpp | 260 ------ .../imageProcessor/cvblobs/BlobContour.h | 97 -- .../cvblobs/BlobLibraryConfiguration.h | 12 - .../imageProcessor/cvblobs/BlobOperators.cpp | 429 --------- .../imageProcessor/cvblobs/BlobOperators.h | 734 --------------- .../imageProcessor/cvblobs/BlobProperties.cpp | 81 -- .../imageProcessor/cvblobs/BlobProperties.h | 67 -- .../imageProcessor/cvblobs/BlobResult.cpp | 867 ------------------ .../imageProcessor/cvblobs/BlobResult.h | 161 ---- .../cvblobs/ComponentLabeling.cpp | 422 --------- .../cvblobs/ComponentLabeling.h | 30 - .../imageProcessor/cvblobs/blob.cpp | 709 -------------- .../imageProcessor/cvblobs/blob.h | 169 ---- .../imageProcessor/detector/IDetector.cpp | 26 - .../imageProcessor/detector/IDetector.h | 66 -- .../imageProcessor/detector/blob/BlobPose.cpp | 18 - .../imageProcessor/detector/blob/BlobPose.h | 86 -- .../detector/blob/cvBlob/BlobsDetector.cpp | 80 -- .../detector/blob/cvBlob/BlobsDetector.h | 54 -- .../blob/simpleBlob/SimpleBlobsDetector.cpp | 80 -- .../blob/simpleBlob/SimpleBlobsDetector.h | 49 - .../detector/contour/ContourPose.cpp | 18 - .../detector/contour/ContourPose.h | 72 -- .../detector/contour/ContoursDetector.cpp | 68 -- .../detector/contour/ContoursDetector.h | 36 - .../preprocessor/ImagePreProcessor.cpp | 216 ----- .../preprocessor/ImagePreProcessor.h | 111 --- Src/View/TrackedElementView.cpp | 1 - Src/helper/CvHelper.cpp | 405 -------- Src/helper/CvHelper.h | 197 ---- 43 files changed, 3 insertions(+), 6227 deletions(-) delete mode 100644 Src/Model/Network/TcpListener.cpp delete mode 100644 Src/Model/Network/TcpListener.h delete mode 100644 Src/Model/TrackingAlgorithm/NN2dMapper.cpp delete mode 100644 Src/Model/TrackingAlgorithm/NN2dMapper.h delete mode 100644 Src/Model/TrackingAlgorithm/ParamNames.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobLibraryConfiguration.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/IDetector.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/IDetector.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.h delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp delete mode 100644 Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h delete mode 100644 Src/helper/CvHelper.cpp delete mode 100644 Src/helper/CvHelper.h diff --git a/Src/BioTrackerPlugin.h b/Src/BioTrackerPlugin.h index 7544588..1faa2b6 100644 --- a/Src/BioTrackerPlugin.h +++ b/Src/BioTrackerPlugin.h @@ -6,6 +6,7 @@ #include "Interfaces/IBioTrackerPlugin.h" +#include <QDebug> #include "QPointer" #include "memory" #include "QPoint" diff --git a/Src/CMakeLists.txt b/Src/CMakeLists.txt index e498afe..541b25b 100644 --- a/Src/CMakeLists.txt +++ b/Src/CMakeLists.txt @@ -15,27 +15,10 @@ add_behavior_plugin(${target} "Model/null_Model.cpp" "Model/BioTrackerTrackingAlgorithm.cpp" "Model/TrackerParameter.cpp" - "Model/Network/TcpListener.cpp" "Model/TrackedComponents/TrackedComponentFactory.cpp" "Model/TrackedComponents/TrackedElement.cpp" "Model/TrackedComponents/TrackedTrajectory.cpp" "Model/TrackedComponents/pose/FishPose.cpp" - "Model/TrackingAlgorithm/NN2dMapper.cpp" - "Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp" - "Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.cpp" - "Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.cpp" - "Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.cpp" - "Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.cpp" - "Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp" - "Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.cpp" - "Model/TrackingAlgorithm/imageProcessor/detector/IDetector.cpp" - "Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.cpp" - "Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.cpp" - "Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.cpp" - "Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.cpp" - "Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.cpp" - "Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp" - "helper/CvHelper.cpp" "helper/StringHelper.cpp" "Controller/ControllerTrackedComponent.cpp" "Controller/ControllerTrackingAlgorithm.cpp" diff --git a/Src/Controller/ControllerTrackingAlgorithm.h b/Src/Controller/ControllerTrackingAlgorithm.h index 0435fa1..816ab53 100644 --- a/Src/Controller/ControllerTrackingAlgorithm.h +++ b/Src/Controller/ControllerTrackingAlgorithm.h @@ -4,6 +4,7 @@ #include "Interfaces/IController/IController.h" #include "../Model/BioTrackerTrackingAlgorithm.h" #include "Interfaces/IBioTrackerContext.h" +#include "Interfaces/IModel/IModelAreaDescriptor.h" #include "Interfaces/IModel/IModelDataExporter.h" #include "../Config.h" diff --git a/Src/Model/BioTrackerTrackingAlgorithm.cpp b/Src/Model/BioTrackerTrackingAlgorithm.cpp index 1f03fda..0cf053f 100644 --- a/Src/Model/BioTrackerTrackingAlgorithm.cpp +++ b/Src/Model/BioTrackerTrackingAlgorithm.cpp @@ -39,23 +39,13 @@ void* init_shm_mmap(const char *path, int len) { BioTrackerTrackingAlgorithm::BioTrackerTrackingAlgorithm(IController *parent, IModel* parameter, IModel* trajectory) : IModelTrackingAlgorithm(parent) -, _ipp((TrackerParameter*)parameter) { _cfg = static_cast<ControllerTrackingAlgorithm*>(parent)->getConfig(); _TrackingParameter = (TrackerParameter*)parameter; _TrackedTrajectoryMajor = (BST::TrackedTrajectory*)trajectory; - _nn2d = std::make_shared<NN2dMapper>(_TrackedTrajectoryMajor); - _bd = BlobsDetector(); _noFish = -1; - if (_cfg->DoNetwork) { - _listener = new TcpListener(this); - _listener->listen(QHostAddress::Any, _cfg->NetworkPort); - QObject::connect(_listener, SIGNAL(newConnection()), _listener, SLOT(acceptConnection())); - } - - _lastImage = nullptr; _lastFramenumber = -1; @@ -78,7 +68,6 @@ void BioTrackerTrackingAlgorithm::request_shared_memory() { void BioTrackerTrackingAlgorithm::receiveAreaDescriptorUpdate(IModelAreaDescriptor *areaDescr) { _AreaInfo = areaDescr; - _bd.setAreaInfo(_AreaInfo); } BioTrackerTrackingAlgorithm::~BioTrackerTrackingAlgorithm() @@ -93,7 +82,6 @@ void BioTrackerTrackingAlgorithm::receiveParametersChanged() { void BioTrackerTrackingAlgorithm::doTracking(std::shared_ptr<cv::Mat> p_image, uint framenumber) { - _ipp.m_TrackingParameter = _TrackingParameter; _lastImage = p_image; _lastFramenumber = framenumber; diff --git a/Src/Model/BioTrackerTrackingAlgorithm.h b/Src/Model/BioTrackerTrackingAlgorithm.h index a5d6736..583ebed 100644 --- a/Src/Model/BioTrackerTrackingAlgorithm.h +++ b/Src/Model/BioTrackerTrackingAlgorithm.h @@ -11,15 +11,11 @@ #include "Interfaces/IModel/IModelDataExporter.h" #include "TrackedComponents/TrackedElement.h" #include "TrackedComponents/TrackedTrajectory.h" -#include "TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.h" -#include "TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h" #include "../Controller/ControllerTrackingAlgorithm.h" -#include "TrackingAlgorithm/NN2dMapper.h" #include "Interfaces/IModel/IModelAreaDescriptor.h" #include <iostream> #include <zmq.hpp> -#include "Network/TcpListener.h" #include "../Config.h" class BioTrackerTrackingAlgorithm : public IModelTrackingAlgorithm @@ -47,15 +43,6 @@ private: TrackerParameter* _TrackingParameter; IModelAreaDescriptor* _AreaInfo; - TcpListener* _listener; - - ImagePreProcessor _ipp; - BlobsDetector _bd; - std::shared_ptr<NN2dMapper> _nn2d; - - // background subtraction - cv::Ptr<cv::BackgroundSubtractorMOG2> _pMOG; - int _noFish; //std::ofstream _ofs; diff --git a/Src/Model/Network/TcpListener.cpp b/Src/Model/Network/TcpListener.cpp deleted file mode 100644 index 4f76136..0000000 --- a/Src/Model/Network/TcpListener.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "TcpListener.h" - -#include <sstream> - -TcpListener::TcpListener(QObject *parent) : QTcpServer(parent) -{ -} - -void TcpListener::acceptConnection() -{ - while (this->hasPendingConnections()) - { - QTcpSocket *socket = this->nextPendingConnection(); - _sockets.insert(socket); - QObject::connect(socket, &QTcpSocket::disconnected, [this, socket](){ - _sockets.erase(socket); - }); - } -} - -void TcpListener::sendPositionsToSocket(std::string packet) -{ - for (auto const& socket : _sockets) { - socket->write(packet.c_str()); - } -} - -std::string TcpListener::sendPositions( - int frameNo, - const std::vector<FishPose>& poses, - const std::vector<cv::Point2f>& polygon, - std::chrono::system_clock::time_point ts) -{ - std::stringstream str; - str << "frame:" << frameNo << ";"; - - str << "polygon:" << polygon.size() << ";"; - for (auto vertex = polygon.cbegin(); vertex != polygon.cend(); ++vertex) - { - str << vertex->x << "x" << vertex->y << ";"; - } - - int fishCount = poses.size(); - int fi = 0; - str << "fishcount:" << fishCount << ";"; - - for (int i=0; i < poses.size(); i++) - { - - str << i+1 << "," // the id of the fish - << poses[i].position_cm().x << "," // real position in cm - x-coordinate - << poses[i].position_cm().y << "," // real position in cm - y-coordinate - << poses[i].orientation_rad() << "," // orientation in radian - << poses[i].orientation_deg() << "," // orientation in degree - << poses[i].width() << "," // size of the fish blob: width - << poses[i].height() << "," // size of the fish blob: height - << long(std::chrono::duration_cast<std::chrono::milliseconds>(ts.time_since_epoch()).count()) << "," // the time stamp - << "F" << (((i + 1) == poses.size()) ? ";" : "&"); // F: obsolete "isRobofish" flag (F: not a robofish) - } - str << "end\n"; - - std::cout << str.str() << std::endl; - -#ifdef SAVETRACKINGPACKAGES - _trackingInfoOutputFile4Simulation << str.str(); -#endif - sendPositionsToSocket(str.str()); - return str.str(); -} diff --git a/Src/Model/Network/TcpListener.h b/Src/Model/Network/TcpListener.h deleted file mode 100644 index d53d30f..0000000 --- a/Src/Model/Network/TcpListener.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include <unordered_set> -#include <chrono> - -#include <QThread> -#include <QDebug> -#include <QTcpServer> -#include <QTcpSocket> -#include <QNetworkInterface> - -#include "../TrackedComponents/pose/FishPose.h" - -class TcpListener : public QTcpServer -{ - Q_OBJECT - -public: - TcpListener(QObject *parent = 0); - -public slots: - void acceptConnection(); - void sendPositionsToSocket(std::string packet); - std::string sendPositions(int frameNo, - const std::vector<FishPose>& poses, - const std::vector<cv::Point2f>& polygon, - std::chrono::system_clock::time_point ts); - -private: - std::unordered_set<QTcpSocket *> _sockets; -}; diff --git a/Src/Model/TrackedComponents/pose/FishPose.cpp b/Src/Model/TrackedComponents/pose/FishPose.cpp index af0bfcc..6fd36b1 100644 --- a/Src/Model/TrackedComponents/pose/FishPose.cpp +++ b/Src/Model/TrackedComponents/pose/FishPose.cpp @@ -1,7 +1,6 @@ #include "FishPose.h" -#include "../../../helper/CvHelper.h" -FishPose::FishPose(cv::Point2f pos_cm , cv::Point pos_px, float rad, float deg, float width, float height, float score) : +FishPose::FishPose(cv::Point2f pos_cm , cv::Point pos_px, float rad, float deg, float width, float height, float score) : _position_cm(pos_cm), _position_px(pos_px), _radAngle(rad), @@ -24,10 +23,3 @@ std::string FishPose::toString(bool rectified) out << _position_cm.x << ";" << _position_cm.y << ";" << _degAngle << ";" << _radAngle; return out.str(); } - -float FishPose::calculateProbabilityOfIdentity(const FishPose &first, const FishPose &second, float angleImportance) -{ - //Preliminary method for calculating identity of entities. See Issue biotracker_core/issues/130 for a discussion of this topic. - float distance = CvHelper::getDistance(first.position_cm(), second.position_cm()); - return distance <= 0 ? std::numeric_limits<float>::max() : 1.0/distance; -} diff --git a/Src/Model/TrackedComponents/pose/FishPose.h b/Src/Model/TrackedComponents/pose/FishPose.h index 39778f8..b556be7 100644 --- a/Src/Model/TrackedComponents/pose/FishPose.h +++ b/Src/Model/TrackedComponents/pose/FishPose.h @@ -114,13 +114,6 @@ public: */ std::string toString(bool rectified = false); - /** - * Calculates the probability that two poses are the same. - * The influence of the angle can be set by the parameter angleImportance. - * @return probability between 0 and 1 - */ - static float calculateProbabilityOfIdentity(const FishPose &first, const FishPose &second, float angleImportance = 0.2f); - private: cv::Point2f _position_cm; cv::Point _position_px; diff --git a/Src/Model/TrackerParameter.h b/Src/Model/TrackerParameter.h index 5bc9736..17f874f 100644 --- a/Src/Model/TrackerParameter.h +++ b/Src/Model/TrackerParameter.h @@ -4,7 +4,6 @@ #include "Interfaces/IModel/IModel.h" #include "../Config.h" -#include "TrackingAlgorithm/ParamNames.h" class TrackerParameter : public IModel { diff --git a/Src/Model/TrackingAlgorithm/NN2dMapper.cpp b/Src/Model/TrackingAlgorithm/NN2dMapper.cpp deleted file mode 100644 index 447db50..0000000 --- a/Src/Model/TrackingAlgorithm/NN2dMapper.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include "NN2dMapper.h" - -#include "../../helper/CvHelper.h" -#include <limits> -#include <tuple> -#include <utility> - -float dif(float a, float b) { - return fmod((std::abs(b - a)), CV_PI); -} - -NN2dMapper::NN2dMapper(BST::TrackedTrajectory *tree) { - _tree = tree; - - //Looks kinda complicated but is a rather simple thing: - //For every true trajectory below the tree's root (which are in fact, fish trajectories in out case) - //we want to arr a last confident angle to the map. - int cid = 0; - for (int i = 0; i < _tree->size(); i++) - { - TrackedTrajectory *t = dynamic_cast<TrackedTrajectory *>(_tree->getChild(i)); - if (t && t->getValid()){ - _mapLastConfidentAngle.insert(std::pair<int, float>(cid, std::numeric_limits<float>::quiet_NaN())); - cid++; - } - } -} - -// Functor to compare by the Mth element, as per https://stackoverflow.com/questions/23030267/custom-sorting-a-vector-of-tuples -struct TupleCompare -{ - bool operator()(std::tuple<float, FishPose> a, std::tuple<float, FishPose> b) const { - return std::get<0>(a) > std::get<0>(b); - } - -}; - -FishPose getFishpose(BST::TrackedTrajectory* traj, uint frameid, uint id) { - IModelTrackedComponent* comp = traj->getValidChild(id); - BST::TrackedTrajectory* ct = dynamic_cast<BST::TrackedTrajectory*>(comp); - if (ct) { - BST::TrackedElement *el = dynamic_cast<BST::TrackedElement*>(ct->getChild(frameid-1)); - if (el) - return el->getFishPose(); - } - return FishPose(); -} - -std::tuple<std::vector<FishPose>, std::vector<float>> NN2dMapper::getNewPoses(BST::TrackedTrajectory* traj, uint frameid, std::vector<BlobPose> blobPoses) { - /* The algorithm seems kinda inefficient, as there is many fish*blobs and fish*fish loops. - * But as N is expected to be pretty small (<10 for fish, <20 for blobs) this seems feasible. - */ - std::vector<FishPose> blobs = convertBlobPosesToFishPoses(blobPoses); - - int sizeF = traj->validCount(); - int sizeB = blobs.size(); - std::vector<std::vector<std::tuple<float, FishPose>>> propMap; - - //Create propability matrix and sort it - for (int i = 0; i < sizeF ; i++) { - std::vector<std::tuple<float, FishPose>> currentFish; - FishPose cpose = getFishpose(traj, frameid, i); - for (int j = 0; j < sizeB ; j++) { - currentFish.push_back(std::tuple<float, FishPose>(FishPose::calculateProbabilityOfIdentity(cpose, blobs[j]), blobs[j])); - } - std::sort(begin(currentFish), end(currentFish), TupleCompare()); - propMap.push_back(currentFish); - } - - //I'm sorry for the goto/inefficient loop. But usually we will not have more than a - //hand full (<6) of blobs to walk through, so it's not worth the optimizing. - retry: - for (int i = 0; i < propMap.size(); i++) { - for (int j = 0; j < propMap.size(); j++) { - //Is this - if (!propMap[i].empty() && !propMap[j].empty() && i!=j) { - //Reads: If same blob, but i has higher props than j - bool samePose = std::get<1>(propMap[i][0]) == std::get<1>(propMap[j][0]); - bool propLess = std::get<0>(propMap[i][0]) <= std::get<0>(propMap[j][0]); - if (samePose && propLess) { - //...then remove the 0'th element from j and try again. - propMap[i].erase(propMap[i].begin()); - goto retry; - } - } - } - } - - - std::vector<float> bestMatchesProps; - std::vector<FishPose> bestMatchesPoses; - for (int i = 0; i < propMap.size(); i++) { - if (propMap[i].size() > 0) { - bestMatchesProps.push_back(std::get<0>(propMap[i][0])); - bestMatchesPoses.push_back(std::get<1>(propMap[i][0])); - } - else { - bestMatchesPoses.push_back(getFishpose(traj, frameid, i)); - bestMatchesProps.push_back(100); - } - } - - for (int i = 0; i < bestMatchesPoses.size(); i++) { - - //Look at what the fish did in the last 10 frames - double historyDir; - { - double lookBack = 10; - cv::Point2f p = getFishpose(traj, frameid - lookBack, i).position_cm(); - cv::Point2f pnow = bestMatchesPoses[i].position_cm(); - while (CvHelper::getDistance(p, pnow) < 0.1 && lookBack < 100) { - lookBack += 10; - cv::Point2f p = getFishpose(traj, frameid - lookBack, i).position_cm(); - cv::Point2f pnow = bestMatchesPoses[i].position_cm(); - } - double dir = CvHelper::getAngleToTarget(p, pnow); - //correct some weird angle definition - historyDir = dir + CV_PI / 2; - } - - //The blob detection will come up with an ellipse orientation, where front and back are ambigious. - //So check the history for movement direction. Use the history as an indicator where front and back are. - //This might be unstable iff the fish didn't move at all. - double dif = CvHelper::angleDifference(bestMatchesPoses[i].orientation_rad(), historyDir); - if (std::abs(dif) > CV_PI / 2) { - double dir = bestMatchesPoses[i].orientation_rad() + CV_PI; - while (dir > 2 * CV_PI) dir -= 2 * CV_PI; - while (dir < -2 * CV_PI) dir += 2 * CV_PI; - bestMatchesPoses[i].set_orientation_rad(dir); - bestMatchesPoses[i].set_orientation_deg(dir * 180.0f / CV_PI); - } - - - //TODO move this to algorithm because this does not really take user manipulation into consideration - //TODO include difference between estimated and current - //simple smoothing out big angle jumps - float lastConfidentAngle = _mapLastConfidentAngle.at(i); //this is mot really working if we jump some frmae back/fwd - double dir = bestMatchesPoses[i].orientation_rad(); - if(!std::isnan(lastConfidentAngle)){ - const float deviationFromLast = CvHelper::angleDifference(lastConfidentAngle, dir); - if (std::abs(deviationFromLast) > CV_PI * 0.2 ){ // 36° - dir += deviationFromLast * 0.5; //reduce big jumps - } - else{ - dir += deviationFromLast * 0.1;//smooth out small changes - } - while (dir > 2 * CV_PI) dir -= 2 * CV_PI; - while (dir < -2 * CV_PI) dir += 2 * CV_PI; - bestMatchesPoses[i].set_orientation_rad(dir); - bestMatchesPoses[i].set_orientation_deg(dir * 180.0f / CV_PI); - } - _mapLastConfidentAngle[i] = dir; - } - return std::tuple<std::vector<FishPose>, std::vector<float>>(bestMatchesPoses,bestMatchesProps); -} - -bool NN2dMapper::correctAngle(int trackid, FishPose &pose) -{ - // the current angle is a decent estimation of the direction; however, it might point into the wrong hemisphere - const float poseOrientation = pose.orientation_rad(); - - // start with the pose orientation for our estimate - float proposedAngle = poseOrientation; - - // we have more historical data to correct the new angle to at least be more plausible - float confidence = 0.0f; - const float historyAngle = estimateOrientationRad(trackid, &confidence); - //const float lastConfidentAngle = fish.getLastConfidentOrientationRad(); - float lastConfidentAngle = _mapLastConfidentAngle.at(trackid); //TODO Hauke check if this is an ok thing to do... - - // the current history orientation has a stronger meaning and is preferred - const float comparisonOrientation = std::isnan(historyAngle) ? lastConfidentAngle : historyAngle; - // can't correct the angle? - if (std::isnan(comparisonOrientation)) return false; - - // panic mode - what if nothing was measured? - if (std::isnan(poseOrientation)) - { - pose.set_orientation_rad(comparisonOrientation); - pose.set_orientation_deg(comparisonOrientation * 180.0f / CV_PI); - return false; - } - - const float angleDifference = CvHelper::angleDifference(proposedAngle, comparisonOrientation); - - // if the angles do not lie on the same hemisphere, mirror the proposed angle - if (!std::isnan(angleDifference) && std::abs(angleDifference) > 0.5f * CV_PI) - { - proposedAngle += CV_PI; - } - - // the angle is corrected into the correct hemisphere now; - // now smooth the angle to reduce the impact of outliers or directly remove a zero-measurement. - - if (std::isnan(lastConfidentAngle)) // nothing to smooth? Then simply assume the movement-angle to be a good first estimate - proposedAngle = historyAngle; - else - { - // smooth the change in the angle iff the new angle deviates too much from the last one - const float deviationFromLast = CvHelper::angleDifference(lastConfidentAngle, proposedAngle); - assert(!std::isnan(deviationFromLast)); - - if (std::abs(deviationFromLast) > 0.2f * CV_PI) - { - if (poseOrientation == 0.0f) // deviation AND zero-angle? Most likely not a decent estimation. - proposedAngle = lastConfidentAngle; - else // smooth outliers by a fixed margin - proposedAngle = lastConfidentAngle - 0.1f * deviationFromLast; - } - } - // angle should be between 0� and 360� - if (proposedAngle > 2.0f * CV_PI) proposedAngle -= 2.0f * CV_PI; - else if (proposedAngle < 0.0f) proposedAngle += 2.0f * CV_PI; - assert(!std::isnan(proposedAngle)); - - pose.set_orientation_rad(proposedAngle); - pose.set_orientation_deg(proposedAngle * 180.0f / CV_PI); - - // did we have ANY confident correction? - if (!std::isnan(lastConfidentAngle)) // if we simply adjusted the last position, assume to be confident - return true; - // otherwise, we need to intialize the confident angle. - // do that when we really are "confident" for the first time.. - const float differenceToHistoryAngle = std::abs(CvHelper::angleDifference(proposedAngle, historyAngle)); - assert(!std::isnan(differenceToHistoryAngle)); - if (differenceToHistoryAngle < 0.25f * CV_PI) - return true; - // neither updating nor a good initialization? - return false; -} - -BST::TrackedTrajectory* getChildOfType(BST::TrackedTrajectory* tree, int tid) { - int cid = 0; - for (int i = 0; i < tree->size(); i++) { - BST::TrackedTrajectory* t = dynamic_cast<BST::TrackedTrajectory*>(tree->getChild(i)); - if (t && cid==tid && t->getValid()) { - return t; - }else if (t && t->getValid()) - cid++; - } - return 0; -} - -float NN2dMapper::estimateOrientationRad(int trackid, float *confidence) -{ - //Get corresponding trajectory - BST::TrackedTrajectory* t = getChildOfType((BST::TrackedTrajectory*)_tree, trackid); - //return 0; - - // can't give estimate if not enough poses available - if (t->size() < 3) return std::numeric_limits<float>::quiet_NaN(); - - //std::deque<FishPose>::const_reverse_iterator iter = _histComponents.rbegin(); - int start = std::max(t->size()-20, 0); - BST::TrackedElement* e = (BST::TrackedElement*)t->getChild(start); - if (!e) - return std::numeric_limits<float>::quiet_NaN(); - cv::Point2f nextPoint = e->getFishPose().position_cm(); - cv::Point2f positionDerivative(0.0f, 0.0f); - - // weights the last poses with falloff^k * pose[end - k] until falloff^k < falloffMargin - int posesUsed = 0; - float currentWeight = 1.0f; - float weightSum = 0.0f; - const float falloff = 0.9f; - const float falloffMargin = 0.4f; - - for (int i=start+1; i<t->size(); i++) - { - BST::TrackedElement* ecur = (BST::TrackedElement*)t->getChild(i); - if (!ecur) - return std::numeric_limits<float>::quiet_NaN(); - cv::Point2f currentPoint = ecur->getFishPose().position_cm(); - const cv::Point2f oneStepDerivative = nextPoint - currentPoint; - - positionDerivative += currentWeight * oneStepDerivative; - weightSum += currentWeight; - - currentWeight *= falloff; - if (currentWeight < falloffMargin) break; - - nextPoint = currentPoint; - ++posesUsed; - } - // calculate average (weighted) movement of the fish - if (weightSum != 0.0f) - { - positionDerivative.x /= weightSum; - positionDerivative.y /= weightSum; - } - // use the euclidian distance in cm - const float distance = std::sqrt(std::pow(positionDerivative.x, 2.0f) + std::pow(positionDerivative.y, 2.0f)); - // Calculate cm/s. - const float distanceNormalized = 1000.0f * distance / 33.3; // TODO Hauke static_cast<float>(FishTrackerThread::instance()->getRealTimePerFrameMs()) - const float confidenceDistanceMinCm = 2.0f; - const float confidenceDistanceMaxCm = 6.0f; - // if we have either nearly no data or are very unsure (left movement offsets right movement f.e.), just return nothing - if (distanceNormalized < confidenceDistanceMinCm) - return std::numeric_limits<float>::quiet_NaN(); - *confidence = std::min(distanceNormalized / confidenceDistanceMaxCm, 1.0f); - - // negative y coordinate to offset open cv coordinate system - return std::atan2(-positionDerivative.y, positionDerivative.x); -} - -std::vector<FishPose> NN2dMapper::convertBlobPosesToFishPoses(std::vector<BlobPose> blobPoses) -{ - std::vector<FishPose> fishPoses; - fishPoses.reserve(blobPoses.size()); - - for (BlobPose & blobPose : blobPoses) - { - fishPoses.push_back( - FishPose( - blobPose.posCm(), - blobPose.posPx(), - CvHelper::degToRad(blobPose.angleDegree()), - blobPose.angleDegree(), - blobPose.width(), - blobPose.height() - ) - ); - } - - return fishPoses; -} diff --git a/Src/Model/TrackingAlgorithm/NN2dMapper.h b/Src/Model/TrackingAlgorithm/NN2dMapper.h deleted file mode 100644 index 9851c63..0000000 --- a/Src/Model/TrackingAlgorithm/NN2dMapper.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <chrono> - -#include <opencv2/opencv.hpp> -#include <opencv2/highgui.hpp> - -#include "../TrackedComponents/pose/FishPose.h" -#include "../TrackedComponents/TrackedElement.h" -#include "../TrackedComponents/TrackedTrajectory.h" -#include "imageProcessor/detector/blob/cvBlob/BlobsDetector.h" - -class NN2dMapper -{ -public: - - /** - * The contructor with parameters. - */ - NN2dMapper(BST::TrackedTrajectory *tree); - - ~NN2dMapper(void) {}; - - std::tuple<std::vector<FishPose>, std::vector<float>> getNewPoses(BST::TrackedTrajectory* traj, uint frameid, std::vector<BlobPose> blobPoses); - std::vector<FishPose> convertBlobPosesToFishPoses(std::vector<BlobPose> blobPoses); - float estimateOrientationRad(int trackid, float *confidence); - bool correctAngle(int trackid, FishPose &pose); - - std::map<int, float> _mapLastConfidentAngle; - BST::TrackedTrajectory *_tree; - -protected: - -}; - diff --git a/Src/Model/TrackingAlgorithm/ParamNames.h b/Src/Model/TrackingAlgorithm/ParamNames.h deleted file mode 100644 index 7e7a587..0000000 --- a/Src/Model/TrackingAlgorithm/ParamNames.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#include <iostream> -#include <vector> - - -namespace CONFIGPARAM -{ - // System config - const std::string CONFIG_INI_FILE = "./BSTrackerConfig.ini"; -} - -namespace APPLICATIONPARAM -{ - // System config - const std::string APP_VERSION = "APPLICATIONPARAM/APP_VERSION"; -} - -namespace TRACKERPARAM -{ - - // Parameter for the opencv BackgroundSubtractorMOG2 class - const std::string BG_MOG2_HISTORY = "TRACKERPARAM/BG_MOG2_HISTORY"; - const std::string BG_MOG2_VAR_THRESHOLD = "TRACKERPARAM/BG_MOG2_VAR_THRESHOLD"; - const std::string BG_MOG2_BACKGROUND_RATIO = "TRACKERPARAM/BG_MOG2_BACKGROUND_RATIO"; - - // Blob dectection issue - const std::string MAX_BLOB_SIZE = "TRACKERPARAM/MAX_BLOB_SIZE"; - const std::string MIN_BLOB_SIZE = "TRACKERPARAM/MIN_BLOB_SIZE"; - - // Parameters for image pre-processing step - const std::string SIZE_ERODE = "TRACKERPARAM/SIZE_ERODE"; - const std::string SIZE_DILATE = "TRACKERPARAM/SIZE_DILATE"; - const std::string THRESHOLD_BINARIZING = "TRACKERPARAM/THRESHOLD_BINARIZING"; - //const std::string GAUSSIAN_BLUR_SIZE = "TRACKERPARAM/GAUSSIAN_BLUR_SIZE"; -} - -namespace GUIPARAM -{ - // FPS label - const std::string ENABLE_LABEL_FPS = "GUIPARAM/ENABLE_LABEL_FPS"; - // Fish id label - const std::string ENABLE_LABEL_FISH_ID = "GUIPARAM/ENABLE_LABEL_FISH_ID"; - // Replica marker - const std::string ENABLE_LABEL_REPLICA = "GUIPARAM/ENABLE_LABEL_REPLICA"; - // Fish position - const std::string ENABLE_LABEL_FISH_POS = "GUIPARAM/ENABLE_LABEL_FISH_POS"; - // Fish orientation - const std::string ENABLE_LABEL_FISH_ORI = "GUIPARAM/ENABLE_LABEL_FISH_ORI"; - // Fish history - const std::string ENABLE_LABEL_FISH_HISTORY = "GUIPARAM/ENABLE_LABEL_FISH_HISTORY"; - // Blobs - const std::string ENABLE_SHOW_BLOBS = "GUIPARAM/ENABLE_SHOW_BLOBS"; - // Swap fish id - const std::string ENABLE_SWAP_FISH_ID = "GUIPARAM/ENABLE_SWAP_FISH_ID"; - - - - // Core view of tracked components - const std::string ENABLE_CORE_COMPONENT_VIEW = "GUIPARAM/ENABLE_CORE_COMPONENT_VIEW"; - // Move components in core view - const std::string ENABLE_CORE_COMPONENT_MOVE = "GUIPARAM/ENABLE_CORE_COMPONENT_MOVE"; - // Remove components in core view - const std::string ENABLE_CORE_COMPONENT_REMOVE = "GUIPARAM/ENABLE_CORE_COMPONENT_REMOVE"; - // Swap component id in core view - const std::string ENABLE_CORE_COMPONENT_ID_SWAP = "GUIPARAM/ENABLE_CORE_COMPONENT_ID_SWAP"; - // Add component in core view - const std::string ENABLE_CORE_COMPONENT_ADD = "GUIPARAM/ENABLE_CORE_COMPONENT_ADD"; - // Rotate component in core view - const std::string ENABLE_CORE_COMPONENT_ROTATE = "GUIPARAM/ENABLE_CORE_COMPONENT_ROTATE"; -} - -namespace FISHTANKPARAM -{ - // Tank area - const std::string FISHTANK_AREA_WIDTH = "FISHTANKPARAM/FISHTANK_AREA_WIDTH"; - const std::string FISHTANK_AREA_HEIGHT = "FISHTANKPARAM/FISHTANK_AREA_HEIGHT"; - const std::string FISHTANK_FISH_AMOUNT = "FISHTANKPARAM/FISHTANK_FISH_AMOUNT"; - const std::string FISHTANK_AREA_CORNER1 = "FISHTANKPARAM/FISHTANK_AREA_CORNER1"; - const std::string FISHTANK_AREA_CORNER2 = "FISHTANKPARAM/FISHTANK_AREA_CORNER2"; - const std::string FISHTANK_AREA_CORNER3 = "FISHTANKPARAM/FISHTANK_AREA_CORNER3"; - const std::string FISHTANK_AREA_CORNER4 = "FISHTANKPARAM/FISHTANK_AREA_CORNER4"; - const std::string FISHTANK_ENABLE_NETWORKING = "FISHTANKPARAM/FISHTANK_ENABLE_NETWORKING"; - const std::string FISHTANK_NETWORKING_PORT = "FISHTANKPARAM/FISHTANK_NETWORKING_PORT"; -} - diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.cpp deleted file mode 100644 index c2a0cbc..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.cpp +++ /dev/null @@ -1,260 +0,0 @@ -#include "BlobContour.h" - -#include <opencv2/imgproc/imgproc_c.h> - -CBlobContour::CBlobContour() -{ - m_startPoint.x = 0; - m_startPoint.y = 0; - m_area = -1; - m_perimeter = -1; - m_contourPoints = NULL; - m_moments.m00 = -1; - m_contour = NULL; - m_parentStorage = NULL; -} - -CBlobContour::CBlobContour(cv::Point startPoint, CvMemStorage *storage ) -{ - m_startPoint.x = startPoint.x; - m_startPoint.y = startPoint.y; - m_area = -1; - m_perimeter = -1; - m_moments.m00 = -1; - - m_parentStorage = storage; - - m_contourPoints = NULL; - - // contour sequence: must be compatible with opencv functions - m_contour = cvCreateSeq( CV_SEQ_ELTYPE_CODE | CV_SEQ_KIND_CURVE | CV_SEQ_FLAG_CLOSED, - sizeof(CvContour), - sizeof(t_chainCode),m_parentStorage); - -} - - -//! Copy constructor -CBlobContour::CBlobContour( CBlobContour *source ) -{ - if (source != NULL ) - { - *this = *source; - } -} - -CBlobContour::~CBlobContour() -{ - // let parent blob deallocate all contour and contour point memory - m_contour = NULL; - m_contourPoints = NULL; -} - - -//! Copy operator -CBlobContour& CBlobContour::operator=( const CBlobContour &source ) -{ - if( this != &source ) - { - m_startPoint = source.m_startPoint; - - m_parentStorage = source.m_parentStorage; - - if (m_contour) - { - cvClearSeq( m_contour ); - } - - if (source.m_contour) - { - m_contour = cvCloneSeq( source.m_contour, m_parentStorage); - } - - if( source.m_contourPoints ) - { - if( m_contourPoints ) - cvClearSeq( m_contourPoints ); - m_contourPoints = cvCloneSeq( source.m_contourPoints, m_parentStorage); - } - - m_area = source.m_area; - m_perimeter = source.m_area; - m_moments = source.m_moments; - } - return *this; -} - - -/** -- FUNCI�: AddChainCode -- FUNCIONALITAT: Add chain code to contour -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/05/06 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -void CBlobContour::AddChainCode(t_chainCode chaincode) -{ - cvSeqPush(m_contour, &chaincode); -} - -//! Clears chain code contour and points -void CBlobContour::ResetChainCode() -{ - if( m_contour ) - { - cvClearSeq( m_contour ); - m_contour = NULL; - } - if( m_contourPoints ) - { - cvClearSeq( m_contourPoints ); - m_contourPoints = NULL; - } -} - -/** -- FUNCI�: GetPerimeter -- FUNCIONALITAT: Get perimeter from chain code. Diagonals sum sqrt(2) and horizontal and vertical codes 1 -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/30 -- MODIFICACI�: Data. Autor. Descripci�. -- NOTA: Algorithm derived from "Methods to estimate area and perimeters of blob-like objects: A comparison", L.Yang -*/ -double CBlobContour::GetPerimeter() -{ - // is calculated? - if (m_perimeter != -1) - { - return m_perimeter; - } - - if( IsEmpty() ) - return 0; - - m_perimeter = cvContourPerimeter( GetContourPoints() ); - - return m_perimeter; -} - -/** -- FUNCI�: GetArea -- FUNCIONALITAT: Computes area from chain code -- PAR�METRES: - - -- RESULTAT: - - May give negative areas for clock wise contours -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/30 -- MODIFICACI�: Data. Autor. Descripci�. -- NOTA: Algorithm derived from "Properties of contour codes", G.R. Wilson -*/ -double CBlobContour::GetArea() -{ - // is calculated? - if (m_area != -1) - { - return m_area; - } - - if( IsEmpty() ) - return 0; - - m_area = fabs( cvContourArea( GetContourPoints() )); - - return m_area; -} - -//! Get contour moment (p,q up to MAX_CALCULATED_MOMENTS) -double CBlobContour::GetMoment(int p, int q) -{ - // is a valid moment? - if ( p < 0 || q < 0 || p > MAX_MOMENTS_ORDER || q > MAX_MOMENTS_ORDER ) - { - return -1; - } - - if( IsEmpty() ) - return 0; - - // it is calculated? - if( m_moments.m00 == -1) - { - cvMoments( GetContourPoints(), &m_moments ); - } - - return cvGetSpatialMoment( &m_moments, p, q ); - - -} - -//! Calculate contour points from crack codes -t_PointList CBlobContour::GetContourPoints() -{ - // it is calculated? - if( m_contourPoints != NULL ) - return m_contourPoints; - - if ( m_contour == NULL || m_contour->total <= 0 ) - { - return NULL; - } - - CvSeq *tmpPoints; - CvSeqReader reader; - CvSeqWriter writer; - cv::Point actualPoint; - CvRect boundingBox; - - // if aproximation is different than simple extern perimeter will not work - tmpPoints = cvApproxChains( m_contour, m_parentStorage, CV_CHAIN_APPROX_NONE); - - - // apply an offset to contour points to recover real coordinates - - cvStartReadSeq( tmpPoints, &reader); - - m_contourPoints = cvCreateSeq( tmpPoints->flags, tmpPoints->header_size, tmpPoints->elem_size, m_parentStorage ); - cvStartAppendToSeq(m_contourPoints, &writer ); - - // also calculate bounding box of the contour to allow cvPointPolygonTest - // work correctly on the generated polygon - boundingBox.x = boundingBox.y = 10000; - boundingBox.width = boundingBox.height = 0; - - for( int i=0; i< tmpPoints->total; i++) - { - CV_READ_SEQ_ELEM( actualPoint, reader); - - actualPoint.x += m_startPoint.x; - actualPoint.y += m_startPoint.y; - - boundingBox.x = MIN( boundingBox.x, actualPoint.x ); - boundingBox.y = MIN( boundingBox.y, actualPoint.y ); - boundingBox.width = MAX( boundingBox.width, actualPoint.x ); - boundingBox.height = MAX( boundingBox.height, actualPoint.y ); - - CV_WRITE_SEQ_ELEM( actualPoint, writer ); - } - cvEndWriteSeq( &writer ); - cvClearSeq( tmpPoints ); - - // assign calculated bounding box - ((CvContour*)m_contourPoints)->rect = boundingBox; - - - return m_contourPoints; -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.h b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.h deleted file mode 100644 index 83d2eb9..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef BLOBCONTOUR_H_INCLUDED -#define BLOBCONTOUR_H_INCLUDED - -#include <opencv2/opencv.hpp> -#include <opencv2/core/types_c.h> -#include <opencv2/imgproc/types_c.h> - -//! Type of chain codes -typedef unsigned char t_chainCode; -//! Type of list of chain codes -typedef CvSeq* t_chainCodeList; -//! Type of list of points -typedef CvSeq* t_PointList; - - -//! Max order of calculated moments -#define MAX_MOMENTS_ORDER 3 - - -//! Blob contour class (in crack code) -class CBlobContour -{ - friend class CBlob; - friend class CBlobProperties; //AO - -public: - //! Constructors - CBlobContour(); - CBlobContour(cv::Point startPoint, CvMemStorage *storage ); - //! Copy constructor - CBlobContour( CBlobContour *source ); - - ~CBlobContour(); - //! Assigment operator - CBlobContour& operator=( const CBlobContour &source ); - - //! Add chain code to contour - void AddChainCode(t_chainCode code); - - //! Return freeman chain coded contour - t_chainCodeList GetChainCode() - { - return m_contour; - } - - bool IsEmpty() - { - return m_contour == NULL || m_contour->total == 0; - } - - //! Return all contour points - t_chainCodeList GetContourPoints(); - -protected: - - cv::Point GetStartPoint() const - { - return m_startPoint; - } - - //! Clears chain code contour - void ResetChainCode(); - - - - //! Computes area from contour - double GetArea(); - //! Computes perimeter from contour - double GetPerimeter(); - //! Get contour moment (p,q up to MAX_CALCULATED_MOMENTS) - double GetMoment(int p, int q); - - //! Crack code list - t_chainCodeList m_contour; - -private: - //! Starting point of the contour - cv::Point m_startPoint; - //! All points from the contour - t_PointList m_contourPoints; - - - - //! Computed area from contour - double m_area; - //! Computed perimeter from contour - double m_perimeter; - //! Computed moments from contour - CvMoments m_moments; - - //! Pointer to storage - CvMemStorage *m_parentStorage; -}; - -#endif //!BLOBCONTOUR_H_INCLUDED - - diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobLibraryConfiguration.h b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobLibraryConfiguration.h deleted file mode 100644 index f1a02a7..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobLibraryConfiguration.h +++ /dev/null @@ -1,12 +0,0 @@ -/************************************************************************ - BlobLibraryConfiguration.h - -FUNCIONALITAT: Configuraci� del comportament global de la llibreria -AUTOR: Inspecta S.L. -MODIFICACIONS (Modificaci�, Autor, Data): - -FUNCTIONALITY: Global configuration of the library -AUTHOR: Inspecta S.L. -MODIFICATIONS (Modification, Author, Date): - -**************************************************************************/ diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.cpp deleted file mode 100644 index cfdae2d..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.cpp +++ /dev/null @@ -1,429 +0,0 @@ -#include <limits.h> - -#include "BlobOperators.h" - -#include <opencv2/imgproc/imgproc_c.h> - -/*************************************************************************** - Implementaci� de les classes per al c�lcul de caracter�stiques sobre el blob - - Implementation of the helper classes to perform operations on blobs -/**************************************************************************/ - -/** -- FUNCTION: Moment -- FUNCTIONALITY: Calculates the pq moment of the blob -- PARAMETERS: -- RESULT: - - returns the pq moment or 0 if the moment it is not implemented -- RESTRICTIONS: - - Currently, implemented moments up to 3 -- AUTHOR: Ricard Borr�s -- CREATION DATE: 20-07-2004. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetMoment::operator()(CBlob &blob) -{ - return blob.Moment(m_p, m_q); -} - -/** -- FUNCI�: HullPerimeter -- FUNCIONALITAT: Calcula la longitud del perimetre convex del blob. - Fa servir la funci� d'OpenCV cvConvexHull2 per a - calcular el perimetre convex. - -- PAR�METRES: -- RESULTAT: - - retorna la longitud del per�metre convex del blob. Si el blob no t� coordenades - associades retorna el per�metre normal del blob. -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 20-07-2004. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: CBlobGetHullPerimeter -- FUNCTIONALITY: Calculates the convex hull perimeter of the blob -- PARAMETERS: -- RESULT: - - returns the convex hull perimeter of the blob or the perimeter if the - blob edges could not be retrieved -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetHullPerimeter::operator()(CBlob &blob) -{ - CvSeq *convexHull; - double perimeter; - - convexHull = blob.GetConvexHull(); - - if( convexHull ) - perimeter = fabs(cvArcLength(convexHull,CV_WHOLE_SEQ,1)); - else - return 0; - - cvClearSeq(convexHull); - - return perimeter; -} - -double CBlobGetHullArea::operator()(CBlob &blob) -{ - CvSeq *convexHull; - double area; - - convexHull = blob.GetConvexHull(); - - if( convexHull ) - area = fabs(cvContourArea(convexHull)); - else - return 0; - - cvClearSeq(convexHull); - - return area; -} - -/** -- FUNCTION: CBlobGetMinXatMinY -- FUNCTIONALITY: Calculates the minimum X on the minimum Y -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetMinXatMinY::operator()(CBlob &blob) -{ - double result = LONG_MAX; - - CvSeqReader reader; - cv::Point actualPoint; - t_PointList externContour; - - externContour = blob.GetExternalContour()->GetContourPoints(); - if( !externContour ) return result; - cvStartReadSeq( externContour, &reader); - - for( int i=0; i< externContour->total; i++) - { - CV_READ_SEQ_ELEM( actualPoint, reader); - - if( (actualPoint.y == blob.MinY()) && (actualPoint.x < result) ) - { - result = actualPoint.x; - } - } - - return result; -} - -/** -- FUNCTION: CBlobGetMinXatMinY -- FUNCTIONALITY: Calculates the minimum Y on the maximum X -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetMinYatMaxX::operator()(CBlob &blob) -{ - double result = LONG_MAX; - - CvSeqReader reader; - cv::Point actualPoint; - t_PointList externContour; - - externContour = blob.GetExternalContour()->GetContourPoints(); - if( !externContour ) return result; - cvStartReadSeq( externContour, &reader); - - for( int i=0; i< externContour->total; i++) - { - CV_READ_SEQ_ELEM( actualPoint, reader); - - if( (actualPoint.x == blob.MaxX()) && (actualPoint.y < result) ) - { - result = actualPoint.y; - } - } - - return result; -} - -/** -- FUNCTION: CBlobGetMaxXatMaxY -- FUNCTIONALITY: Calculates the maximum X on the maximum Y -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetMaxXatMaxY::operator()(CBlob &blob) -{ - double result = LONG_MIN; - - CvSeqReader reader; - cv::Point actualPoint; - t_PointList externContour; - - externContour = blob.GetExternalContour()->GetContourPoints(); - if( !externContour ) return result; - - cvStartReadSeq( externContour, &reader); - - for( int i=0; i< externContour->total; i++) - { - CV_READ_SEQ_ELEM( actualPoint, reader); - - if( (actualPoint.y == blob.MaxY()) && (actualPoint.x > result) ) - { - result = actualPoint.x; - } - } - - return result; -} - -/** -- FUNCTION: CBlobGetMaxYatMinX -- FUNCTIONALITY: Calculates the maximum Y on the minimum X -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetMaxYatMinX::operator()(CBlob &blob) -{ - double result = LONG_MIN; - - CvSeqReader reader; - cv::Point actualPoint; - t_PointList externContour; - - externContour = blob.GetExternalContour()->GetContourPoints(); - if( !externContour ) return result; - - cvStartReadSeq( externContour, &reader); - - - for( int i=0; i< externContour->total; i++) - { - CV_READ_SEQ_ELEM( actualPoint, reader); - - if( (actualPoint.x == blob.MinX()) && (actualPoint.y > result) ) - { - result = actualPoint.y; - } - } - - return result; -} - - -/** -- FUNCTION: CBlobGetElongation -- FUNCTIONALITY: Calculates the elongation of the blob ( length/breadth ) -- PARAMETERS: -- RESULT: -- RESTRICTIONS: - - See below to see how the lenght and the breadth are aproximated -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetElongation::operator()(CBlob &blob) -{ - double ampladaC,longitudC,amplada,longitud; - - double tmp; - - tmp = blob.Perimeter()*blob.Perimeter() - 16*blob.Area(); - - if( tmp > 0.0 ) - ampladaC = (double) (blob.Perimeter()+sqrt(tmp))/4; - // error intr�nsec en els c�lculs de l'�rea i el per�metre - else - ampladaC = (double) (blob.Perimeter())/4; - - if(ampladaC<=0.0) return 0; - longitudC=(double) blob.Area()/ampladaC; - - longitud=MAX( longitudC , ampladaC ); - amplada=MIN( longitudC , ampladaC ); - - return (double) longitud/amplada; -} - -/** - Retorna la compacitat del blob -*/ -/** -- FUNCTION: CBlobGetCompactness -- FUNCTIONALITY: Calculates the compactness of the blob - ( maximum for circle shaped blobs, minimum for the rest) -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetCompactness::operator()(CBlob &blob) -{ - if( blob.Area() != 0.0 ) - return (double) pow(blob.Perimeter(),2)/(4*CV_PI*blob.Area()); - else - return 0.0; -} - -/** - Retorna la rugositat del blob -*/ -/** -- FUNCTION: CBlobGetRoughness -- FUNCTIONALITY: Calculates the roughness of the blob - ( ratio between perimeter and convex hull perimeter) -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetRoughness::operator()(CBlob &blob) -{ - CBlobGetHullPerimeter getHullPerimeter = CBlobGetHullPerimeter(); - - double hullPerimeter = getHullPerimeter(blob); - - if( hullPerimeter != 0.0 ) - return blob.Perimeter() / hullPerimeter;//HullPerimeter(); - - return 0.0; -} - -/** - Retorna la longitud del blob -*/ -/** -- FUNCTION: CBlobGetLength -- FUNCTIONALITY: Calculates the lenght of the blob (the biggest axis of the blob) -- PARAMETERS: -- RESULT: -- RESTRICTIONS: - - The lenght is an aproximation to the real lenght -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetLength::operator()(CBlob &blob) -{ - double ampladaC,longitudC; - double tmp; - - tmp = blob.Perimeter()*blob.Perimeter() - 16*blob.Area(); - - if( tmp > 0.0 ) - ampladaC = (double) (blob.Perimeter()+sqrt(tmp))/4; - // error intr�nsec en els c�lculs de l'�rea i el per�metre - else - ampladaC = (double) (blob.Perimeter())/4; - - if(ampladaC<=0.0) return 0; - longitudC=(double) blob.Area()/ampladaC; - - return MAX( longitudC , ampladaC ); -} - -/** - Retorna l'amplada del blob -*/ -/** -- FUNCTION: CBlobGetBreadth -- FUNCTIONALITY: Calculates the breadth of the blob (the smallest axis of the blob) -- PARAMETERS: -- RESULT: -- RESTRICTIONS: - - The breadth is an aproximation to the real breadth -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetBreadth::operator()(CBlob &blob) -{ - double ampladaC,longitudC; - double tmp; - - tmp = blob.Perimeter()*blob.Perimeter() - 16*blob.Area(); - - if( tmp > 0.0 ) - ampladaC = (double) (blob.Perimeter()+sqrt(tmp))/4; - // error intr�nsec en els c�lculs de l'�rea i el per�metre - else - ampladaC = (double) (blob.Perimeter())/4; - - if(ampladaC<=0.0) return 0; - longitudC = (double) blob.Area()/ampladaC; - - return MIN( longitudC , ampladaC ); -} - -/** - Calcula la dist�ncia entre un punt i el centre del blob -*/ -/** -- FUNCTION: CBlobGetDistanceFromPoint -- FUNCTIONALITY: Calculates the euclidean distance between the blob center and - the point specified in the constructor -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetDistanceFromPoint::operator()(CBlob &blob) -{ - double xmitjana, ymitjana; - CBlobGetXCenter getXCenter; - CBlobGetYCenter getYCenter; - - xmitjana = m_x - getXCenter( blob ); - ymitjana = m_y - getYCenter( blob ); - - return sqrt((xmitjana*xmitjana)+(ymitjana*ymitjana)); -} - -/** -- FUNCTION: BlobGetXYInside -- FUNCTIONALITY: Calculates whether a point is inside the - rectangular bounding box of a blob -- PARAMETERS: -- RESULT: - - returns 1 if it is inside; o if not -- RESTRICTIONS: -- AUTHOR: Francesc Pinyol Margalef -- CREATION DATE: 16-01-2006. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobGetXYInside::operator()(CBlob &blob) -{ - if( blob.GetExternalContour()->GetContourPoints() ) - { - return cvPointPolygonTest( blob.GetExternalContour()->GetContourPoints(), m_p,0) >= 0; - } - - return 0; -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.h b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.h deleted file mode 100644 index fbe233f..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobOperators.h +++ /dev/null @@ -1,734 +0,0 @@ -#ifndef BLOB_OPERATORS_H_INCLUDED -#define BLOB_OPERATORS_H_INCLUDED - -#include "blob.h" - -/************************************************************************** - Definici� de les classes per a fer operacions sobre els blobs - - Helper classes to perform operations on blobs -**************************************************************************/ - -//! Factor de conversi� de graus a radians -#define DEGREE2RAD (CV_PI / 180.0) - - -//! Classe d'on derivarem totes les operacions sobre els blobs -//! Interface to derive all blob operations -class COperadorBlob -{ -public: - virtual ~COperadorBlob(){}; - - //! Aply operator to blob - virtual double operator()(CBlob &blob) = 0; - //! Get operator name - virtual const char *GetNom() = 0; - - operator COperadorBlob*() - { - return (COperadorBlob*)this; - } -}; - -typedef COperadorBlob funcio_calculBlob; - - -//! Classe per calcular l'etiqueta d'un blob -//! Class to get ID of a blob -class CBlobGetID : public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.GetID(); - } - const char *GetNom() - { - return "CBlobGetID"; - } -}; - - -//! Classe per calcular l'�rea d'un blob -//! Class to get the area of a blob -class CBlobGetArea : public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.Area(); - } - const char *GetNom() - { - return "CBlobGetArea"; - } -}; - -//! Classe per calcular el perimetre d'un blob -//! Class to get the perimeter of a blob -class CBlobGetPerimeter: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.Perimeter(); - } - const char *GetNom() - { - return "CBlobGetPerimeter"; - } -}; - -//! Classe que diu si un blob �s extern o no -//! Class to get the extern flag of a blob -class CBlobGetExterior: public COperadorBlob -{ -public: - CBlobGetExterior() - { - m_mask = NULL; - m_xBorder = false; - m_yBorder = false; - } - CBlobGetExterior(IplImage *mask, bool xBorder = true, bool yBorder = true) - { - m_mask = mask; - m_xBorder = xBorder; - m_yBorder = yBorder; - } - double operator()(CBlob &blob) - { - return blob.Exterior(m_mask, m_xBorder, m_yBorder); - } - const char *GetNom() - { - return "CBlobGetExterior"; - } -private: - IplImage *m_mask; - bool m_xBorder, m_yBorder; -}; - -//! Classe per calcular la mitjana de nivells de gris d'un blob -//! Class to get the mean grey level of a blob -class CBlobGetMean: public COperadorBlob -{ -public: - CBlobGetMean() - { - m_image = NULL; - } - CBlobGetMean( IplImage *image ) - { - m_image = image; - }; - - double operator()(CBlob &blob) - { - return blob.Mean(m_image); - } - const char *GetNom() - { - return "CBlobGetMean"; - } -private: - - IplImage *m_image; -}; - -//! Classe per calcular la desviaci� est�ndard dels nivells de gris d'un blob -//! Class to get the standard deviation of the grey level values of a blob -class CBlobGetStdDev: public COperadorBlob -{ -public: - CBlobGetStdDev() - { - m_image = NULL; - } - CBlobGetStdDev( IplImage *image ) - { - m_image = image; - }; - double operator()(CBlob &blob) - { - return blob.StdDev(m_image); - } - const char *GetNom() - { - return "CBlobGetStdDev"; - } -private: - - IplImage *m_image; - -}; - -//! Classe per calcular la compacitat d'un blob -//! Class to calculate the compactness of a blob -class CBlobGetCompactness: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetCompactness"; - } -}; - -//! Classe per calcular la longitud d'un blob -//! Class to calculate the length of a blob -class CBlobGetLength: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetLength"; - } -}; - -//! Classe per calcular l'amplada d'un blob -//! Class to calculate the breadth of a blob -class CBlobGetBreadth: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetBreadth"; - } -}; - -//! Classe per calcular la difer�ncia en X del blob -class CBlobGetDiffX: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.GetBoundingBox().width; - } - const char *GetNom() - { - return "CBlobGetDiffX"; - } -}; - -//! Classe per calcular la difer�ncia en X del blob -class CBlobGetDiffY: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.GetBoundingBox().height; - } - const char *GetNom() - { - return "CBlobGetDiffY"; - } -}; - -//! Classe per calcular el moment PQ del blob -//! Class to calculate the P,Q moment of a blob -class CBlobGetMoment: public COperadorBlob -{ -public: - //! Constructor est�ndard - //! Standard constructor (gets the 00 moment) - CBlobGetMoment() - { - m_p = m_q = 0; - } - //! Constructor: indiquem el moment p,q a calcular - //! Constructor: gets the PQ moment - CBlobGetMoment( int p, int q ) - { - m_p = p; - m_q = q; - }; - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetMoment"; - } - -private: - //! moment que volem calcular - int m_p, m_q; -}; - -//! Classe per calcular el perimetre del poligon convex d'un blob -//! Class to calculate the convex hull perimeter of a blob -class CBlobGetHullPerimeter: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetHullPerimeter"; - } -}; - -//! Classe per calcular l'�rea del poligon convex d'un blob -//! Class to calculate the convex hull area of a blob -class CBlobGetHullArea: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetHullArea"; - } -}; - -//! Classe per calcular la x minima en la y minima -//! Class to calculate the minimum x on the minimum y -class CBlobGetMinXatMinY: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetMinXatMinY"; - } -}; - -//! Classe per calcular la y minima en la x maxima -//! Class to calculate the minimum y on the maximum x -class CBlobGetMinYatMaxX: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetMinYatMaxX"; - } -}; - -//! Classe per calcular la x maxima en la y maxima -//! Class to calculate the maximum x on the maximum y -class CBlobGetMaxXatMaxY: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetMaxXatMaxY"; - } -}; - -//! Classe per calcular la y maxima en la x minima -//! Class to calculate the maximum y on the minimum y -class CBlobGetMaxYatMinX: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetMaxYatMinX"; - } -}; - -//! Classe per a calcular la x m�nima -//! Class to get the minimum x -class CBlobGetMinX: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.MinX(); - } - const char *GetNom() - { - return "CBlobGetMinX"; - } -}; - -//! Classe per a calcular la x m�xima -//! Class to get the maximum x -class CBlobGetMaxX: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.MaxX(); - } - const char *GetNom() - { - return "CBlobGetMaxX"; - } -}; - -//! Classe per a calcular la y m�nima -//! Class to get the minimum y -class CBlobGetMinY: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.MinY(); - } - const char *GetNom() - { - return "CBlobGetMinY"; - } -}; - -//! Classe per a calcular la y m�xima -//! Class to get the maximum y -class CBlobGetMaxY: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.MaxY(); - } - const char *GetNom() - { - return "CBlobGetMaxY"; - } -}; - - -//! Classe per calcular l'elongacio d'un blob -//! Class to calculate the elongation of the blob -class CBlobGetElongation: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetElongation"; - } -}; - -//! Classe per calcular la rugositat d'un blob -//! Class to calculate the roughness of the blob -class CBlobGetRoughness: public COperadorBlob -{ -public: - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetRoughness"; - } -}; - -//! Classe per calcular la dist�ncia entre el centre del blob i un punt donat -//! Class to calculate the euclidean distance between the center of a blob and a given point -class CBlobGetDistanceFromPoint: public COperadorBlob -{ -public: - //! Standard constructor (distance to point 0,0) - CBlobGetDistanceFromPoint() - { - m_x = m_y = 0.0; - } - //! Constructor (distance to point x,y) - CBlobGetDistanceFromPoint( const double x, const double y ) - { - m_x = x; - m_y = y; - } - - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetDistanceFromPoint"; - } - -private: - // coordenades del punt on volem calcular la dist�ncia - double m_x, m_y; -}; - -//! Classe per calcular el nombre de pixels externs d'un blob -//! Class to get the number of extern pixels of a blob -class CBlobGetExternPerimeter: public COperadorBlob -{ -public: - CBlobGetExternPerimeter() - { - m_mask = NULL; - m_xBorder = false; - m_yBorder = false; - } - CBlobGetExternPerimeter( IplImage *mask, bool xBorder = true, bool yBorder = true ) - { - m_mask = mask; - m_xBorder = xBorder; - m_yBorder = yBorder; - } - double operator()(CBlob &blob) - { - return blob.ExternPerimeter(m_mask, m_xBorder, m_yBorder); - } - const char *GetNom() - { - return "CBlobGetExternPerimeter"; - } -private: - IplImage *m_mask; - bool m_xBorder, m_yBorder; -}; - -//! Classe per calcular el ratio entre el perimetre i nombre pixels externs -//! valors propers a 0 indiquen que la majoria del blob �s intern -//! valors propers a 1 indiquen que la majoria del blob �s extern -//! Class to calculate the ratio between the perimeter and the number of extern pixels -class CBlobGetExternPerimeterRatio: public COperadorBlob -{ -public: - CBlobGetExternPerimeterRatio() - { - m_mask = NULL; - m_xBorder = false; - m_yBorder = false; - } - CBlobGetExternPerimeterRatio( IplImage *mask, bool xBorder = true, bool yBorder = true ) - { - m_mask = mask; - m_xBorder = xBorder; - m_yBorder = yBorder; - } - double operator()(CBlob &blob) - { - if( blob.Perimeter() != 0 ) - return blob.ExternPerimeter(m_mask, m_xBorder, m_yBorder) / blob.Perimeter(); - else - return blob.ExternPerimeter(m_mask, m_xBorder, m_yBorder); - } - const char *GetNom() - { - return "CBlobGetExternPerimeterRatio"; - } -private: - IplImage *m_mask; - bool m_xBorder, m_yBorder; -}; - -//! Classe per calcular el ratio entre el perimetre convex i nombre pixels externs -//! valors propers a 0 indiquen que la majoria del blob �s intern -//! valors propers a 1 indiquen que la majoria del blob �s extern -//! Class to calculate the ratio between the perimeter and the number of extern pixels -class CBlobGetExternHullPerimeterRatio: public COperadorBlob -{ -public: - CBlobGetExternHullPerimeterRatio() - { - m_mask = NULL; - m_xBorder = false; - m_yBorder = false; - } - CBlobGetExternHullPerimeterRatio( IplImage *mask, bool xBorder = true, bool yBorder = true ) - { - m_mask = mask; - m_xBorder = xBorder; - m_yBorder = yBorder; - } - double operator()(CBlob &blob) - { - CBlobGetHullPerimeter getHullPerimeter; - double hullPerimeter; - - if( (hullPerimeter = getHullPerimeter( blob ) ) != 0 ) - return blob.ExternPerimeter(m_mask, m_xBorder, m_yBorder) / hullPerimeter; - else - return blob.ExternPerimeter(m_mask, m_xBorder, m_yBorder); - } - const char *GetNom() - { - return "CBlobGetExternHullPerimeterRatio"; - } -private: - IplImage *m_mask; - bool m_xBorder, m_yBorder; - -}; - -//! Classe per calcular el centre en el eix X d'un blob -//! Class to calculate the center in the X direction -class CBlobGetXCenter: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.MinX() + (( blob.MaxX() - blob.MinX() ) / 2.0); - } - const char *GetNom() - { - return "CBlobGetXCenter"; - } -}; - -//! Classe per calcular el centre en el eix Y d'un blob -//! Class to calculate the center in the Y direction -class CBlobGetYCenter: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - return blob.MinY() + (( blob.MaxY() - blob.MinY() ) / 2.0); - } - const char *GetNom() - { - return "CBlobGetYCenter"; - } -}; - -//! Classe per calcular la longitud de l'eix major d'un blob -//! Class to calculate the length of the major axis of the ellipse that fits the blob edges -class CBlobGetMajorAxisLength: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - CvBox2D elipse = blob.GetEllipse(); - - return elipse.size.width; - } - const char *GetNom() - { - return "CBlobGetMajorAxisLength"; - } -}; - -//! Classe per calcular el ratio entre l'area de la elipse i la de la taca -//! Class -class CBlobGetAreaElipseRatio: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - if( blob.Area()==0.0 ) return 0.0; - - CvBox2D elipse = blob.GetEllipse(); - double ratioAreaElipseAreaTaca = ( (elipse.size.width/2.0) - * - (elipse.size.height/2.0) - *CV_PI - ) - / - blob.Area(); - - return ratioAreaElipseAreaTaca; - } - const char *GetNom() - { - return "CBlobGetAreaElipseRatio"; - } -}; - -//! Classe per calcular la longitud de l'eix menor d'un blob -//! Class to calculate the length of the minor axis of the ellipse that fits the blob edges -class CBlobGetMinorAxisLength: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - CvBox2D elipse = blob.GetEllipse(); - - return elipse.size.height; - } - const char *GetNom() - { - return "CBlobGetMinorAxisLength"; - } -}; - -//! Classe per calcular l'orientaci� de l'ellipse del blob en radians -//! Class to calculate the orientation of the ellipse that fits the blob edges in radians -class CBlobGetOrientation: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - CvBox2D elipse = blob.GetEllipse(); -/* - if( elipse.angle > 180.0 ) - return (( elipse.angle - 180.0 )* DEGREE2RAD); - else - return ( elipse.angle * DEGREE2RAD); -*/ - return elipse.angle; - } - const char *GetNom() - { - return "CBlobGetOrientation"; - } -}; - -//! Classe per calcular el cosinus de l'orientaci� de l'ellipse del blob -//! Class to calculate the cosinus of the orientation of the ellipse that fits the blob edges -class CBlobGetOrientationCos: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - CBlobGetOrientation getOrientation; - return fabs( cos( getOrientation(blob)*DEGREE2RAD )); - } - const char *GetNom() - { - return "CBlobGetOrientationCos"; - } -}; - - -//! Classe per calcular el ratio entre l'eix major i menor de la el�lipse -//! Class to calculate the ratio between both axes of the ellipse -class CBlobGetAxisRatio: public COperadorBlob -{ -public: - double operator()(CBlob &blob) - { - double major,minor; - CBlobGetMajorAxisLength getMajor; - CBlobGetMinorAxisLength getMinor; - - major = getMajor(blob); - minor = getMinor(blob); - - if( major != 0 ) - return minor / major; - else - return 0; - } - const char *GetNom() - { - return "CBlobGetAxisRatio"; - } -}; - - -//! Classe per calcular si un punt cau dins del blob -//! Class to calculate whether a point is inside a blob -class CBlobGetXYInside: public COperadorBlob -{ -public: - //! Constructor est�ndard - //! Standard constructor - CBlobGetXYInside() - { - m_p.x = 0; - m_p.y = 0; - } - //! Constructor: indiquem el punt - //! Constructor: sets the point - CBlobGetXYInside( CvPoint2D32f p ) - { - m_p = p; - }; - double operator()(CBlob &blob); - const char *GetNom() - { - return "CBlobGetXYInside"; - } - -private: - //! punt que considerem - //! point to be considered - CvPoint2D32f m_p; -}; - -#endif //!BLOB_OPERATORS_H_INCLUDED diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.cpp deleted file mode 100644 index 64b7265..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "BlobProperties.h" - - -/** -- FUNCI�: GetPerimeter -- FUNCIONALITAT: Get perimeter from chain code. Diagonals sum sqrt(2) and horizontal and vertical codes 1 -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/30 -- MODIFICACI�: Data. Autor. Descripci�. -- NOTA: Algorithm derived from "Methods to estimate area and perimeters of blob-like objects: A comparison", L.Yang -*/ -#define SQRT2 1.414213562 - -/** -- FUNCI�: GetPerimeter -- FUNCIONALITAT: Get blob area, ie. external contour area minus internal contours area -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/30 -- MODIFICACI�: Data. Autor. Descripci�. -*/ - -double CBlobProperties::GetArea() -{ - double area; - t_contourList::iterator itContour; - - area = m_externalContour.GetArea(); - - itContour = m_internalContours.begin(); - - while (itContour != m_internalContours.end() ) - { - area += (*itContour).GetArea(); - itContour++; - } - return area; -} - -/** -- FUNCI�: GetPerimeter -- FUNCIONALITAT: Get blob perimeter, ie. sum of the lenght of all the contours -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/30 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -double CBlobProperties::GetPerimeter() -{ - double perimeter; - t_contourList::iterator itContour; - - perimeter = m_externalContour.GetPerimeter(); - - itContour = m_internalContours.begin(); - - while (itContour != m_internalContours.end() ) - { - perimeter += (*itContour).GetPerimeter(); - itContour++; - } - return perimeter; -} - - diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.h b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.h deleted file mode 100644 index 97d028a..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobProperties.h +++ /dev/null @@ -1,67 +0,0 @@ - -//! Disable warnings referred to 255 character truncation for the std:map -#pragma warning( disable : 4786 ) - -#ifndef BLOB_PROPERTIES_H_INCLUDED -#define BLOB_PROPERTIES_H_INCLUDED - -#include <list> - -#include <opencv2/opencv.hpp> - -#include "BlobLibraryConfiguration.h" -#include "BlobContour.h" - - -//! Type of labelled images -typedef unsigned int t_labelType; - -//! Max order of calculated moments -#define MAX_MOMENTS_ORDER 3 - - -//! Blob class -class CBlobProperties -{ - typedef std::list<CBlobContour> t_contourList; - -public: - - CBlobProperties(); - virtual ~CBlobProperties(); - - //! Get blob area - double GetArea(); - - //! Get blob perimeter - double GetPerimeter(); - - //! Get contour moment (p,q up to MAX_CALCULATED_MOMENTS) - double GetMoment(int p, int q); - - - ////////////////////////////////////////////////////////////////////////// - // Blob contours - ////////////////////////////////////////////////////////////////////////// - - - //! Contour storage memory - CvMemStorage *m_storage; - //! External contour of the blob (crack codes) - CBlobContour m_externalContour; - //! Internal contours (crack codes) - t_contourList m_internalContours; - -private: - - //! Computed area from blob - double m_area; - //! Computed perimeter from blob - double m_perimeter; - // Computed moment from the blob - double m_moment[MAX_MOMENTS_ORDER*MAX_MOMENTS_ORDER]; - -}; - -#endif //!BLOB_PROPERTIES_H_INCLUDED - diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp deleted file mode 100644 index 7e84c53..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp +++ /dev/null @@ -1,867 +0,0 @@ -/************************************************************************ - BlobResult.cpp - -FUNCIONALITAT: Implementaci� de la classe CBlobResult -AUTOR: Inspecta S.L. -MODIFICACIONS (Modificaci�, Autor, Data): - -**************************************************************************/ - -#include <limits.h> -#include <stdio.h> -#include <functional> -#include <algorithm> -#include "BlobResult.h" - -/************************************************************************** - Constructors / Destructors -**************************************************************************/ - - -/** -- FUNCI�: CBlobResult -- FUNCIONALITAT: Constructor estandard. -- PAR�METRES: -- RESULTAT: -- Crea un CBlobResult sense cap blob -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 20-07-2004. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: CBlobResult -- FUNCTIONALITY: Standard constructor -- PARAMETERS: -- RESULT: - - creates an empty set of blobs -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -CBlobResult::CBlobResult() -{ - m_blobs = Blob_vector(); -} - -/** -- FUNCI�: CBlobResult -- FUNCIONALITAT: Constructor a partir d'una imatge. Inicialitza la seq��ncia de blobs - amb els blobs resultants de l'an�lisi de blobs de la imatge. -- PAR�METRES: - - source: imatge d'on s'extreuran els blobs - - mask: m�scara a aplicar. Nom�s es calcularan els blobs on la m�scara sigui - diferent de 0. Els blobs que toquin a un pixel 0 de la m�scara seran - considerats exteriors. - - threshold: llindar que s'aplicar� a la imatge source abans de calcular els blobs - - findmoments: indica si s'han de calcular els moments de cada blob - - blackBlobs: true per buscar blobs negres a la binaritzazi� (it will join all extern white blobs). - false per buscar blobs negres a la binaritzazi� (it will join all extern black blobs). - -- RESULTAT: - - objecte CBlobResult amb els blobs de la imatge source -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: CBlob -- FUNCTIONALITY: Constructor from an image. Fills an object with all the blobs in - the image -- PARAMETERS: - - source: image to extract the blobs from - - mask: optional mask to apply. The blobs will be extracted where the mask is - not 0. All the neighboring blobs where the mask is 0 will be extern blobs - - threshold: threshold level to apply to the image before computing blobs - - findmoments: true to calculate the blob moments (slower) (needed to calculate elipses!) - - blackBlobs: true to search for black blobs in the binarization (it will join all extern white blobs). - false to search for white blobs in the binarization (it will join all extern black blobs). -- RESULT: - - object with all the blobs in the image. It throws an EXCEPCIO_CALCUL_BLOBS - if some error appears in the BlobAnalysis function -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -CBlobResult::CBlobResult(cv::Mat source, cv::Mat* mask, uchar backgroundColor ) -{ - bool success; - - try - { - success = ComponentLabeling( source, mask, backgroundColor, m_blobs ); - } - catch(...) - { - success = false; - } - - if( !success ) throw EXCEPCIO_CALCUL_BLOBS; -} - -/** -- FUNCI�: CBlobResult -- FUNCIONALITAT: Constructor de c�pia. Inicialitza la seq��ncia de blobs - amb els blobs del par�metre. -- PAR�METRES: - - source: objecte que es copiar� -- RESULTAT: - - objecte CBlobResult amb els blobs de l'objecte source -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: CBlobResult -- FUNCTIONALITY: Copy constructor -- PARAMETERS: - - source: object to copy -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -CBlobResult::CBlobResult( const CBlobResult &source ) -{ - m_blobs = Blob_vector( source.GetNumBlobs() ); - - // creem el nou a partir del passat com a par�metre - m_blobs = Blob_vector( source.GetNumBlobs() ); - // copiem els blobs de l'origen a l'actual - Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin(); - Blob_vector::iterator pBlobsDst = m_blobs.begin(); - - while( pBlobsSrc != source.m_blobs.end() ) - { - // no podem cridar a l'operador = ja que Blob_vector �s un - // vector de CBlob*. Per tant, creem un blob nou a partir del - // blob original - *pBlobsDst = new CBlob(**pBlobsSrc); - pBlobsSrc++; - pBlobsDst++; - } -} - - - -/** -- FUNCI�: ~CBlobResult -- FUNCIONALITAT: Destructor estandard. -- PAR�METRES: -- RESULTAT: - - Allibera la mem�ria reservada de cadascun dels blobs de la classe -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: ~CBlobResult -- FUNCTIONALITY: Destructor -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -CBlobResult::~CBlobResult() -{ - ClearBlobs(); -} - -/************************************************************************** - Operadors / Operators -**************************************************************************/ - - -/** -- FUNCI�: operador = -- FUNCIONALITAT: Assigna un objecte source a l'actual -- PAR�METRES: - - source: objecte a assignar -- RESULTAT: - - Substitueix els blobs actuals per els de l'objecte source -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: Assigment operator -- FUNCTIONALITY: -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -CBlobResult& CBlobResult::operator=(const CBlobResult& source) -{ - // si ja s�n el mateix, no cal fer res - if (this != &source) - { - // alliberem el conjunt de blobs antic - for( int i = 0; i < GetNumBlobs(); i++ ) - { - delete m_blobs[i]; - } - m_blobs.clear(); - // creem el nou a partir del passat com a par�metre - m_blobs = Blob_vector( source.GetNumBlobs() ); - // copiem els blobs de l'origen a l'actual - Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin(); - Blob_vector::iterator pBlobsDst = m_blobs.begin(); - - while( pBlobsSrc != source.m_blobs.end() ) - { - // no podem cridar a l'operador = ja que Blob_vector �s un - // vector de CBlob*. Per tant, creem un blob nou a partir del - // blob original - *pBlobsDst = new CBlob(**pBlobsSrc); - pBlobsSrc++; - pBlobsDst++; - } - } - return *this; -} - - -/** -- FUNCI�: operador + -- FUNCIONALITAT: Concatena els blobs de dos CBlobResult -- PAR�METRES: - - source: d'on s'agafaran els blobs afegits a l'actual -- RESULTAT: - - retorna un nou CBlobResult amb els dos CBlobResult concatenats -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- NOTA: per la implementaci�, els blobs del par�metre es posen en ordre invers -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: + operator -- FUNCTIONALITY: Joins the blobs in source with the current ones -- PARAMETERS: - - source: object to copy the blobs -- RESULT: - - object with the actual blobs and the source blobs -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -CBlobResult CBlobResult::operator+( const CBlobResult& source ) const -{ - //creem el resultat a partir dels blobs actuals - CBlobResult resultat( *this ); - - // reservem mem�ria per als nous blobs - resultat.m_blobs.resize( resultat.GetNumBlobs() + source.GetNumBlobs() ); - - // declarem els iterador per rec�rrer els blobs d'origen i desti - Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin(); - Blob_vector::iterator pBlobsDst = resultat.m_blobs.end(); - - // insertem els blobs de l'origen a l'actual - while( pBlobsSrc != source.m_blobs.end() ) - { - pBlobsDst--; - *pBlobsDst = new CBlob(**pBlobsSrc); - pBlobsSrc++; - } - - return resultat; -} - -/************************************************************************** - Operacions / Operations -**************************************************************************/ - -/** -- FUNCI�: AddBlob -- FUNCIONALITAT: Afegeix un blob al conjunt -- PAR�METRES: - - blob: blob a afegir -- RESULTAT: - - modifica el conjunt de blobs actual -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 2006/03/01 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -void CBlobResult::AddBlob( CBlob *blob ) -{ - if( blob != NULL ) - m_blobs.push_back( new CBlob( blob ) ); -} - - -/** -- FUNCI�: GetSTLResult -- FUNCIONALITAT: Calcula el resultat especificat sobre tots els blobs de la classe -- PAR�METRES: - - evaluador: Qualsevol objecte derivat de COperadorBlob -- RESULTAT: - - Retorna un array de double's STL amb el resultat per cada blob -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: GetResult -- FUNCTIONALITY: Computes the function evaluador on all the blobs of the class - and returns a vector with the result -- PARAMETERS: - - evaluador: function to apply to each blob (any object derived from the - COperadorBlob class ) -- RESULT: - - vector with all the results in the same order as the blobs -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double_stl_vector CBlobResult::GetSTLResult( funcio_calculBlob *evaluador ) const -{ - if( GetNumBlobs() <= 0 ) - { - return double_stl_vector(); - } - - // definim el resultat - double_stl_vector result = double_stl_vector( GetNumBlobs() ); - // i iteradors sobre els blobs i el resultat - double_stl_vector::iterator itResult = result.begin(); - Blob_vector::const_iterator itBlobs = m_blobs.begin(); - - // avaluem la funci� en tots els blobs - while( itBlobs != m_blobs.end() ) - { - *itResult = (*evaluador)(**itBlobs); - itBlobs++; - itResult++; - } - return result; -} - -/** -- FUNCI�: GetNumber -- FUNCIONALITAT: Calcula el resultat especificat sobre un �nic blob de la classe -- PAR�METRES: - - evaluador: Qualsevol objecte derivat de COperadorBlob - - indexblob: n�mero de blob del que volem calcular el resultat. -- RESULTAT: - - Retorna un double amb el resultat -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: GetNumber -- FUNCTIONALITY: Computes the function evaluador on a blob of the class -- PARAMETERS: - - indexBlob: index of the blob to compute the function - - evaluador: function to apply to each blob (any object derived from the - COperadorBlob class ) -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -double CBlobResult::GetNumber( int indexBlob, funcio_calculBlob *evaluador ) const -{ - if( indexBlob < 0 || indexBlob >= GetNumBlobs() ) - RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS ); - return (*evaluador)( *m_blobs[indexBlob] ); -} - -/////////////////////////// FILTRAT DE BLOBS //////////////////////////////////// - -/** -- FUNCI�: Filter -- FUNCIONALITAT: Filtra els blobs de la classe i deixa el resultat amb nom�s - els blobs que han passat el filtre. - El filtrat es basa en especificar condicions sobre un resultat dels blobs - i seleccionar (o excloure) aquells blobs que no compleixen una determinada - condicio -- PAR�METRES: - - dst: variable per deixar els blobs filtrats - - filterAction: acci� de filtrat. Incloure els blobs trobats (B_INCLUDE), - o excloure els blobs trobats (B_EXCLUDE) - - evaluador: Funci� per evaluar els blobs (qualsevol objecte derivat de COperadorBlob - - Condition: tipus de condici� que ha de superar la mesura (FilterType) - sobre cada blob per a ser considerat. - B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL, - B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE - - LowLimit: valor num�ric per a la comparaci� (Condition) de la mesura (FilterType) - - HighLimit: valor num�ric per a la comparaci� (Condition) de la mesura (FilterType) - (nom�s t� sentit per a aquelles condicions que tenen dos valors - (B_INSIDE, per exemple). -- RESULTAT: - - Deixa els blobs resultants del filtrat a destination -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: Filter -- FUNCTIONALITY: Get some blobs from the class based on conditions on measures - of the blobs. -- PARAMETERS: - - dst: where to store the selected blobs - - filterAction: B_INCLUDE: include the blobs which pass the filter in the result - B_EXCLUDE: exclude the blobs which pass the filter in the result - - evaluador: Object to evaluate the blob - - Condition: How to decide if the result returned by evaluador on each blob - is included or not. It can be: - B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL, - B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE - - LowLimit: numerical value to evaluate the Condition on evaluador(blob) - - HighLimit: numerical value to evaluate the Condition on evaluador(blob). - Only useful for B_INSIDE and B_OUTSIDE -- RESULT: - - It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE) - the Condition on the result returned by evaluador on each blob -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -void CBlobResult::Filter(CBlobResult &dst, - int filterAction, - funcio_calculBlob *evaluador, - int condition, - double lowLimit, double highLimit /*=0*/) const - -{ - // do the job - DoFilter(dst, filterAction, evaluador, condition, lowLimit, highLimit ); -} - -/** -- FUNCI�: Filter (const version) -- FUNCIONALITAT: Filtra els blobs de la classe i deixa el resultat amb nom�s - els blobs que han passat el filtre. - El filtrat es basa en especificar condicions sobre un resultat dels blobs - i seleccionar (o excloure) aquells blobs que no compleixen una determinada - condicio -- PAR�METRES: - - dst: variable per deixar els blobs filtrats - - filterAction: acci� de filtrat. Incloure els blobs trobats (B_INCLUDE), - o excloure els blobs trobats (B_EXCLUDE) - - evaluador: Funci� per evaluar els blobs (qualsevol objecte derivat de COperadorBlob - - Condition: tipus de condici� que ha de superar la mesura (FilterType) - sobre cada blob per a ser considerat. - B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL, - B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE - - LowLimit: valor num�ric per a la comparaci� (Condition) de la mesura (FilterType) - - HighLimit: valor num�ric per a la comparaci� (Condition) de la mesura (FilterType) - (nom�s t� sentit per a aquelles condicions que tenen dos valors - (B_INSIDE, per exemple). -- RESULTAT: - - Deixa els blobs resultants del filtrat a destination -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/** -- FUNCTION: Filter (const version) -- FUNCTIONALITY: Get some blobs from the class based on conditions on measures - of the blobs. -- PARAMETERS: - - dst: where to store the selected blobs - - filterAction: B_INCLUDE: include the blobs which pass the filter in the result - B_EXCLUDE: exclude the blobs which pass the filter in the result - - evaluador: Object to evaluate the blob - - Condition: How to decide if the result returned by evaluador on each blob - is included or not. It can be: - B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL, - B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE - - LowLimit: numerical value to evaluate the Condition on evaluador(blob) - - HighLimit: numerical value to evaluate the Condition on evaluador(blob). - Only useful for B_INSIDE and B_OUTSIDE -- RESULT: - - It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE) - the Condition on the result returned by evaluador on each blob -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -void CBlobResult::Filter(CBlobResult &dst, - int filterAction, - funcio_calculBlob *evaluador, - int condition, - double lowLimit, double highLimit /*=0*/) - -{ - int numBlobs = GetNumBlobs(); - - // do the job - DoFilter(dst, filterAction, evaluador, condition, lowLimit, highLimit ); - - // inline operation: remove previous blobs - if( &dst == this ) - { - // esborrem els primers blobs ( que s�n els originals ) - // ja que els tindrem replicats al final si passen el filtre - Blob_vector::iterator itBlobs = m_blobs.begin(); - for( int i = 0; i < numBlobs; i++ ) - { - delete *itBlobs; - itBlobs++; - } - m_blobs.erase( m_blobs.begin(), itBlobs ); - } -} - - -//! Does the Filter method job -void CBlobResult::DoFilter(CBlobResult &dst, int filterAction, funcio_calculBlob *evaluador, - int condition, double lowLimit, double highLimit/* = 0*/) const -{ - int i, numBlobs; - bool resultavaluacio; - double_stl_vector avaluacioBlobs; - double_stl_vector::iterator itavaluacioBlobs; - - if( GetNumBlobs() <= 0 ) return; - if( !evaluador ) return; - //avaluem els blobs amb la funci� pertinent - avaluacioBlobs = GetSTLResult(evaluador); - itavaluacioBlobs = avaluacioBlobs.begin(); - numBlobs = GetNumBlobs(); - switch(condition) - { - case B_EQUAL: - for(i=0;i<numBlobs;i++, itavaluacioBlobs++) - { - resultavaluacio= *itavaluacioBlobs == lowLimit; - if( ( resultavaluacio && filterAction == B_INCLUDE ) || - ( !resultavaluacio && filterAction == B_EXCLUDE )) - { - dst.m_blobs.push_back( new CBlob( GetBlob( i ) )); - } - } - break; - case B_NOT_EQUAL: - for(i=0;i<numBlobs;i++, itavaluacioBlobs++) - { - resultavaluacio = *itavaluacioBlobs != lowLimit; - if( ( resultavaluacio && filterAction == B_INCLUDE ) || - ( !resultavaluacio && filterAction == B_EXCLUDE )) - { - dst.m_blobs.push_back( new CBlob( GetBlob( i ) )); - } - } - break; - case B_GREATER: - for(i=0;i<numBlobs;i++, itavaluacioBlobs++) - { - resultavaluacio= *itavaluacioBlobs > lowLimit; - if( ( resultavaluacio && filterAction == B_INCLUDE ) || - ( !resultavaluacio && filterAction == B_EXCLUDE )) - { - dst.m_blobs.push_back( new CBlob( GetBlob( i ) )); - } - } - break; - case B_LESS: - for(i=0;i<numBlobs;i++, itavaluacioBlobs++) - { - resultavaluacio= *itavaluacioBlobs < lowLimit; - if( ( resultavaluacio && filterAction == B_INCLUDE ) || - ( !resultavaluacio && filterAction == B_EXCLUDE )) - { - dst.m_blobs.push_back( new CBlob( GetBlob( i ) )); - } - } - break; - case B_GREATER_OR_EQUAL: - for(i=0;i<numBlobs;i++, itavaluacioBlobs++) - { - resultavaluacio= *itavaluacioBlobs>= lowLimit; - if( ( resultavaluacio && filterAction == B_INCLUDE ) || - ( !resultavaluacio && filterAction == B_EXCLUDE )) - { - dst.m_blobs.push_back( new CBlob( GetBlob( i ) )); - } - } - break; - case B_LESS_OR_EQUAL: - for(i=0;i<numBlobs;i++, itavaluacioBlobs++) - { - resultavaluacio= *itavaluacioBlobs <= lowLimit; - if( ( resultavaluacio && filterAction == B_INCLUDE ) || - ( !resultavaluacio && filterAction == B_EXCLUDE )) - { - dst.m_blobs.push_back( new CBlob( GetBlob( i ) )); - } - } - break; - case B_INSIDE: - for(i=0;i<numBlobs;i++, itavaluacioBlobs++) - { - resultavaluacio=( *itavaluacioBlobs >= lowLimit) && ( *itavaluacioBlobs <= highLimit); - if( ( resultavaluacio && filterAction == B_INCLUDE ) || - ( !resultavaluacio && filterAction == B_EXCLUDE )) - { - dst.m_blobs.push_back( new CBlob( GetBlob( i ) )); - } - } - break; - case B_OUTSIDE: - for(i=0;i<numBlobs;i++, itavaluacioBlobs++) - { - resultavaluacio=( *itavaluacioBlobs < lowLimit) || ( *itavaluacioBlobs > highLimit); - if( ( resultavaluacio && filterAction == B_INCLUDE ) || - ( !resultavaluacio && filterAction == B_EXCLUDE )) - { - dst.m_blobs.push_back( new CBlob( GetBlob( i ) )); - } - } - break; - } -} -/** -- FUNCI�: GetBlob -- FUNCIONALITAT: Retorna un blob si aquest existeix (index != -1) -- PAR�METRES: - - indexblob: index del blob a retornar -- RESULTAT: -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/* -- FUNCTION: GetBlob -- FUNCTIONALITY: Gets the n-th blob (without ordering the blobs) -- PARAMETERS: - - indexblob: index in the blob array -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -CBlob CBlobResult::GetBlob(int indexblob) const -{ - if( indexblob < 0 || indexblob >= GetNumBlobs() ) - RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS ); - - return *m_blobs[indexblob]; -} -CBlob *CBlobResult::GetBlob(int indexblob) -{ - if( indexblob < 0 || indexblob >= GetNumBlobs() ) - RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS ); - - return m_blobs[indexblob]; -} - -/** -- FUNCI�: GetNthBlob -- FUNCIONALITAT: Retorna l'en�ssim blob segons un determinat criteri -- PAR�METRES: - - criteri: criteri per ordenar els blobs (objectes derivats de COperadorBlob) - - nBlob: index del blob a retornar - - dst: on es retorna el resultat -- RESULTAT: - - retorna el blob nBlob a dst ordenant els blobs de la classe segons el criteri - en ordre DESCENDENT. Per exemple, per obtenir el blob major: - GetNthBlob( CBlobGetArea(), 0, blobMajor ); - GetNthBlob( CBlobGetArea(), 1, blobMajor ); (segon blob m�s gran) -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/* -- FUNCTION: GetNthBlob -- FUNCTIONALITY: Gets the n-th blob ordering first the blobs with some criteria -- PARAMETERS: - - criteri: criteria to order the blob array - - nBlob: index of the returned blob in the ordered blob array - - dst: where to store the result -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -void CBlobResult::GetNthBlob( funcio_calculBlob *criteri, int nBlob, CBlob &dst ) const -{ - // verifiquem que no estem accedint fora el vector de blobs - if( nBlob < 0 || nBlob >= GetNumBlobs() ) - { - //RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS ); - dst = CBlob(); - return; - } - - double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat; - double valorEnessim; - - //avaluem els blobs amb la funci� pertinent - avaluacioBlobs = GetSTLResult(criteri); - - avaluacioBlobsOrdenat = double_stl_vector( GetNumBlobs() ); - - // obtenim els nBlob primers resultats (en ordre descendent) - std::partial_sort_copy( avaluacioBlobs.begin(), - avaluacioBlobs.end(), - avaluacioBlobsOrdenat.begin(), - avaluacioBlobsOrdenat.end(), - std::greater<double>() ); - - valorEnessim = avaluacioBlobsOrdenat[nBlob]; - - // busquem el primer blob que t� el valor n-ssim - double_stl_vector::const_iterator itAvaluacio = avaluacioBlobs.begin(); - - bool trobatBlob = false; - int indexBlob = 0; - while( itAvaluacio != avaluacioBlobs.end() && !trobatBlob ) - { - if( *itAvaluacio == valorEnessim ) - { - trobatBlob = true; - dst = CBlob( GetBlob(indexBlob)); - } - itAvaluacio++; - indexBlob++; - } -} - -/** -- FUNCI�: ClearBlobs -- FUNCIONALITAT: Elimina tots els blobs de l'objecte -- PAR�METRES: -- RESULTAT: - - Allibera tota la mem�ria dels blobs -- RESTRICCIONS: -- AUTOR: Ricard Borr�s Navarra -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/* -- FUNCTION: ClearBlobs -- FUNCTIONALITY: Clears all the blobs from the object and releases all its memory -- PARAMETERS: -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -void CBlobResult::ClearBlobs() -{ - Blob_vector::iterator itBlobs = m_blobs.begin(); - while( itBlobs != m_blobs.end() ) - { - delete *itBlobs; - itBlobs++; - } - - m_blobs.clear(); -} - -/** -- FUNCI�: RaiseError -- FUNCIONALITAT: Funci� per a notificar errors al l'usuari (en debug) i llen�a - les excepcions -- PAR�METRES: - - errorCode: codi d'error -- RESULTAT: - - Ensenya un missatge a l'usuari (en debug) i llen�a una excepci� -- RESTRICCIONS: -- AUTOR: Ricard Borr�s Navarra -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/* -- FUNCTION: RaiseError -- FUNCTIONALITY: Error handling function -- PARAMETERS: - - errorCode: reason of the error -- RESULT: - - Throws an exception with the error. -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -void CBlobResult::RaiseError(const int errorCode) const -{ - throw errorCode; -} - - - -/************************************************************************** - Auxiliars / Auxiliary functions -**************************************************************************/ - - -/** -- FUNCI�: PrintBlobs -- FUNCIONALITAT: Escriu els par�metres (�rea, per�metre, exterior, mitjana) - de tots els blobs a un fitxer. -- PAR�METRES: - - nom_fitxer: path complet del fitxer amb el resultat -- RESULTAT: -- RESTRICCIONS: -- AUTOR: Ricard Borr�s -- DATA DE CREACI�: 25-05-2005. -- MODIFICACI�: Data. Autor. Descripci�. -*/ -/* -- FUNCTION: PrintBlobs -- FUNCTIONALITY: Prints some blob features in an ASCII file -- PARAMETERS: - - nom_fitxer: full path + filename to generate -- RESULT: -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -void CBlobResult::PrintBlobs( char *nom_fitxer ) const -{ - double_stl_vector area, /*perimetre,*/ exterior, compacitat, longitud, - externPerimeter, perimetreConvex, perimetre; - int i; - FILE *fitxer_sortida; - - area = GetSTLResult( CBlobGetArea()); - perimetre = GetSTLResult( CBlobGetPerimeter()); - exterior = GetSTLResult( CBlobGetExterior()); - compacitat = GetSTLResult(CBlobGetCompactness()); - longitud = GetSTLResult( CBlobGetLength()); - externPerimeter = GetSTLResult( CBlobGetExternPerimeter()); - perimetreConvex = GetSTLResult( CBlobGetHullPerimeter()); - - fitxer_sortida = fopen( nom_fitxer, "w" ); - - for(i=0; i<GetNumBlobs(); i++) - { -// fprintf( fitxer_sortida, "blob %d ->\t a=%7.0f\t p=%8.2f (%8.2f extern)\t pconvex=%8.2f\t ext=%.0f\t m=%7.2f\t c=%3.2f\t l=%8.2f\n", -// i, area[i], perimetre[i], externPerimeter[i], perimetreConvex[i], exterior[i], compacitat[i], longitud[i] ); - } - fclose( fitxer_sortida ); - -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.h b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.h deleted file mode 100644 index cf5c182..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.h +++ /dev/null @@ -1,161 +0,0 @@ -/************************************************************************ - BlobResult.h - -FUNCIONALITAT: Definici� de la classe CBlobResult -AUTOR: Inspecta S.L. -MODIFICACIONS (Modificaci�, Autor, Data): - -FUNCTIONALITY: Definition of the CBlobResult class -AUTHOR: Inspecta S.L. -MODIFICATIONS (Modification, Author, Date): - -**************************************************************************/ - - -#if !defined(_CLASSE_BLOBRESULT_INCLUDED) -#define _CLASSE_BLOBRESULT_INCLUDED - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "BlobLibraryConfiguration.h" -#include <math.h> -#include <opencv2/opencv.hpp> - -#include <vector> // vectors de la STL -#include <functional> -#include "blob.h" -#include "BlobOperators.h" -#include "ComponentLabeling.h" - -//! Vector de doubles -typedef std::vector<double> double_stl_vector; - -/************************************************************************** - Filtres / Filters -**************************************************************************/ - -//! accions que es poden fer amb els filtres -//! Actions performed by a filter (include or exclude blobs) -#define B_INCLUDE 1L -#define B_EXCLUDE 2L - -//! condicions sobre els filtres -//! Conditions to apply the filters -#define B_EQUAL 3L -#define B_NOT_EQUAL 4L -#define B_GREATER 5L -#define B_LESS 6L -#define B_GREATER_OR_EQUAL 7L -#define B_LESS_OR_EQUAL 8L -#define B_INSIDE 9L -#define B_OUTSIDE 10L - - -/************************************************************************** - Excepcions / Exceptions -**************************************************************************/ - -//! Excepcions llen�ades per les funcions: -#define EXCEPTION_BLOB_OUT_OF_BOUNDS 1000 -#define EXCEPCIO_CALCUL_BLOBS 1001 - -/** - Classe que cont� un conjunt de blobs i permet extreure'n propietats - o filtrar-los segons determinats criteris. - Class to calculate the blobs of an image and calculate some properties - on them. Also, the class provides functions to filter the blobs using - some criteria. -*/ -class CBlobResult -{ -public: - - //! constructor estandard, crea un conjunt buit de blobs - //! Standard constructor, it creates an empty set of blobs - CBlobResult(); - //! constructor a partir d'una imatge - //! Image constructor, it creates an object with the blobs of the image - CBlobResult(cv::Mat source, cv::Mat* mask, uchar backgroundColor); - //! constructor de c�pia - //! Copy constructor - CBlobResult( const CBlobResult &source ); - //! Destructor - virtual ~CBlobResult(); - - //! operador = per a fer assignacions entre CBlobResult - //! Assigment operator - CBlobResult& operator=(const CBlobResult& source); - //! operador + per concatenar dos CBlobResult - //! Addition operator to concatenate two sets of blobs - CBlobResult operator+( const CBlobResult& source ) const; - - //! Afegeix un blob al conjunt - //! Adds a blob to the set of blobs - void AddBlob( CBlob *blob ); - - //! Calcula un valor sobre tots els blobs de la classe retornant un std::vector<double> - //! Computes some property on all the blobs of the class - double_stl_vector GetSTLResult( funcio_calculBlob *evaluador ) const; - - //! Calcula un valor sobre un blob de la classe - //! Computes some property on one blob of the class - double GetNumber( int indexblob, funcio_calculBlob *evaluador ) const; - - //! Retorna aquells blobs que compleixen les condicions del filtre en el destination - //! Filters the blobs of the class using some property - void Filter(CBlobResult &dst, - int filterAction, funcio_calculBlob *evaluador, - int condition, double lowLimit, double highLimit = 0 ); - void Filter(CBlobResult &dst, - int filterAction, funcio_calculBlob *evaluador, - int condition, double lowLimit, double highLimit = 0 ) const; - - //! Retorna l'en�ssim blob segons un determinat criteri - //! Sorts the blobs of the class acording to some criteria and returns the n-th blob - void GetNthBlob( funcio_calculBlob *criteri, int nBlob, CBlob &dst ) const; - - //! Retorna el blob en�ssim - //! Gets the n-th blob of the class ( without sorting ) - CBlob GetBlob(int indexblob) const; - CBlob *GetBlob(int indexblob); - - //! Elimina tots els blobs de l'objecte - //! Clears all the blobs of the class - void ClearBlobs(); - - //! Escriu els blobs a un fitxer - //! Prints some features of all the blobs in a file - void PrintBlobs( char *nom_fitxer ) const; - - -//Metodes GET/SET - - //! Retorna el total de blobs - //! Gets the total number of blobs - int GetNumBlobs() const - { - return(m_blobs.size()); - } - - -private: - - //! Funci� per gestionar els errors - //! Function to manage the errors - void RaiseError(const int errorCode) const; - - //! Does the Filter method job - void DoFilter(CBlobResult &dst, - int filterAction, funcio_calculBlob *evaluador, - int condition, double lowLimit, double highLimit = 0) const; - -protected: - - //! Vector amb els blobs - //! Vector with all the blobs - Blob_vector m_blobs; -}; - -#endif // !defined(_CLASSE_BLOBRESULT_INCLUDED) diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.cpp deleted file mode 100644 index 6bfaa09..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.cpp +++ /dev/null @@ -1,422 +0,0 @@ - -#include "ComponentLabeling.h" - -#include <thread> -#include <mutex> -#include <future> - -//! Conversion from freeman code to coordinate increments (counterclockwise) -static const cv::Point freemanCodeIncrement[8] = - { {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} }; - - -inline unsigned char GET_IMAGE_PIXEL( cv::Mat image, cv::Point p ) -{ - return image.at<unsigned char>(p); -} - -inline bool GET_IMAGEMASK_PIXEL( cv::Mat* mask, cv::Point p ) -{ - if(mask) - return mask->at<unsigned char>(p) > 0; - else - return true; -} - -inline bool GET_BELOW_VISITEDPIXEL( bool *currentPixel, int imageWidth ) -{ - return *( currentPixel + imageWidth ); -} - -/** -- FUNCI�: ASSIGN_LABEL -- FUNCIONALITAT: Assigns label value to label image -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/29 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -inline void ASSIGN_LABEL( cv::Point p, t_labelType *labels, int imageWidth, int newLabel ) -{ - *(labels + p.y * imageWidth + p.x) = newLabel; -} - - -inline void ASSIGN_VISITED( cv::Point p, bool *visitedPoints, int imageWidth ) -{ - *(visitedPoints + p.y * imageWidth + p.x) = true; -} - -/** -- FUNCI�: ComponentLabeling -- FUNCIONALITAT: Calcula els components binaris (blobs) d'una imatge amb connectivitat a 8 -- PAR�METRES: - - inputImage: image to segment (pixel values different than blobColor are treated as background) - - maskImage: if not NULL, all the pixels equal to 0 in mask are skipped in input image - - backgroundColor: color of background (ignored pixels) - - blobs: blob vector destination -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/21 -- MODIFICACI�: Data. Autor. Descripci�. -- NOTA: Algorithm based on "A linear-time component labeling algorithm using contour tracing technique", - F.Chang et al -*/ -bool ComponentLabeling(cv::Mat inputImage, - cv::Mat* maskImage, - unsigned char backgroundColor, - Blob_vector &blobs ) -{ - // row major vector with visited points - bool internalContour, externalContour; - int imageWidth, imageHeight, currentLabel, contourLabel; - //! current blob pointer - CBlob *currentBlob; - cv::Size imageSizes; - cv::Point currentPoint; - - // verify input image - if (!inputImage.empty()) - return false; - - // verify that input image and mask image has same size - if (maskImage) - { - if (inputImage.size() != maskImage->size()) - return false; - } - - imageSizes = inputImage.size(); - - imageWidth = imageSizes.width; - imageHeight = imageSizes.height; - - // create auxiliary buffers that are initialized to 0 - t_labelType *labelledImage = (t_labelType*) calloc(imageWidth * imageHeight, sizeof(t_labelType)); - bool *visitedPoints = (bool*) calloc(imageWidth * imageHeight, sizeof(bool)); - - // Execute the POI detection parallel. - // This basically just filters out the background (which is the majority of points). - // The result will be an ordered list of non-background points for the blob-detector to work on. - std::vector<cv::Point2d> foregroundPoints; - - const int totalRegionsX = 4; - const int totalRegionsY = 4; - const int totalRegions = totalRegionsX * totalRegionsY; - const int regionWidth = imageWidth / totalRegionsX; - const int regionHeight = imageHeight / totalRegionsY; - - // get the pixel data from an image at a certain position - auto getImageData = [](cv::Mat image, const int row, const int column) - { - return image.data + row * image.step + column; - }; - - // to allow each thread to acces the main list directly (saves us some merging later) - std::mutex foregroundPointAccessMutex; - - auto workOnRegion = [&](int x, int y) { - const int startingX = x * regionWidth; - const int startingY = y * regionHeight; - - for (int j = 0; j < regionHeight; ++j) - for (int i = 0; i < regionWidth; ++i) - { - const int pointX = startingX + i; - const int pointY = startingY + j; - // ignore background pixels or 0 pixels in mask - const unsigned char * pInputImage = getImageData(inputImage, pointY, pointX); - if ((*pInputImage == backgroundColor) || (maskImage && *getImageData(*maskImage, pointY, pointX) == 0)) - { - continue; - } - else // remember all non-background pixels - { - std::lock_guard<std::mutex> lock(foregroundPointAccessMutex); - foregroundPoints.emplace_back(pointX, pointY); - } - } - }; - - // start one parallel thread for each region - std::vector<std::future<void>> merger; - merger.reserve(totalRegions); - - for (int y = 0; y < totalRegionsY; ++y) - { - for (int x = 0; x < totalRegionsX; ++x) - { - merger.push_back(std::async([&, x, y] { workOnRegion(x, y); })); - } - } - - // and wait until all have completed; the results are alrady in the main list - for (const auto & asyncResult : merger) - { - asyncResult.wait(); - } - - // need to sort for coordinate as the loop below is written in a way that depends on the order - std::sort(foregroundPoints.begin(), foregroundPoints.end(), - [](const cv::Point2d & a, const cv::Point2d & b) -> bool - { - return (a.y < b.y) || (a.y == b.y && a.x < b.x); - } - ); - - // initialize pointers and label counter - currentLabel = 1; - - auto getImageDataVisited = [&](const int &row, const int &column) - { - return visitedPoints + row * inputImage.step + column; - }; - - auto getImageDataLabelled = [&](const int &row, const int &column) - { - return labelledImage + row * inputImage.step + column; - }; - - for (const cv::Point2d & point : foregroundPoints) - { - const int i = point.x; - const int j = point.y; - - t_labelType * pLabels = getImageDataLabelled(j, i); - bool * pVisitedPoints = getImageDataVisited(j, i); - - // new external contour: current label == 0 and above pixel is background - if( j > 0 ) - { - const unsigned char * pAboveInputImage = getImageData(inputImage, j - 1, i); - - externalContour = ((*pAboveInputImage == backgroundColor) || - (maskImage && *getImageData(*maskImage, j - 1, i) == 0)) && - (*pLabels == 0); - } - else - externalContour = (*pLabels == 0); - - // new internal contour: below pixel is background and not visited - if( !externalContour && j < imageHeight - 1 ) - { - const unsigned char * pBelowInputImage = getImageData(inputImage, j + 1, i); - internalContour = *pBelowInputImage == backgroundColor && - !GET_BELOW_VISITEDPIXEL( pVisitedPoints, imageWidth); - } - else - { - internalContour = false; - } - - - if( externalContour ) - { - currentPoint = cv::Point(i,j); - // assign label to labelled image - *pLabels = currentLabel; - - // create new blob - currentBlob = new CBlob(currentLabel, currentPoint, imageSizes ); - - // contour tracing with currentLabel - contourTracing( inputImage, maskImage, currentPoint, - labelledImage, visitedPoints, - currentLabel, false, backgroundColor, currentBlob->GetExternalContour() ); - - // add new created blob - blobs.push_back(currentBlob); - - currentLabel++; - } - else - { - if( internalContour ) - { - currentPoint = cv::Point(i,j); - - if( *pLabels == 0 ) - { - // take left neightbour value as current - if( i > 0 ) - contourLabel = *(pLabels - 1); - } - else - { - contourLabel = *pLabels; - } - - if(contourLabel>0) - { - currentBlob = blobs[contourLabel-1]; - CBlobContour newContour(currentPoint, currentBlob->GetStorage()); - - - // contour tracing with contourLabel - contourTracing( inputImage, maskImage, currentPoint, labelledImage, visitedPoints, - contourLabel, true, backgroundColor, &newContour ); - - currentBlob->AddInternalContour( newContour ); - } - } - // neither internal nor external contour - else - { - // take left neightbour value as current if it is not labelled - if( i > 0 && *pLabels == 0 ) - *pLabels = *(pLabels - 1); - } - - } - } - - - // free auxiliary buffers - free( labelledImage ); - free( visitedPoints ); - - return true; -} - -/** -- FUNCI�: -- FUNCIONALITAT: -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/29 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -void contourTracing( cv::Mat image, - cv::Mat* maskImage, - cv::Point contourStart, t_labelType *labels, bool *visitedPoints, t_labelType label, - bool internalContour, unsigned char backgroundColor, CBlobContour *currentBlobcontour ) -{ - cv::Point t, tnext, tsecond; - short initialMovement, movement; - - if( internalContour ) - { - initialMovement = 7;//3; - } - else - { - initialMovement = 3;//7; - } - - tsecond = tracer( image, maskImage, contourStart, visitedPoints, initialMovement, - backgroundColor, movement ); - - // assign current label to tnext - ASSIGN_LABEL( contourStart, labels, image.size().width, label ); - - - // contour corresponds to isolated pixel? - if( tsecond.x == contourStart.x && tsecond.y == contourStart.y ) - { - // we are finished with the contour - return; - } - - // add chain code to current contour - currentBlobcontour->AddChainCode(movement); - - // assign label to next point - ASSIGN_LABEL( tsecond, labels, image.size().width, label ); - - tnext.x = tsecond.x; - tnext.y = tsecond.y; - t.x = tnext.x; - t.y = tnext.y; - - // while T is different than contourStart and Tnext is different than T - // follow contour until start point is reached again - while (!(t.x == contourStart.x && t.y == contourStart.y) - || !(tsecond.x == tnext.x && tsecond.y == tnext.y)) - { - - t.x = tnext.x; - t.y = tnext.y; - initialMovement = (movement + 5) % 8; - - // search for next contour point - tnext = tracer( image, maskImage, t, visitedPoints, initialMovement, - backgroundColor, movement ); - - // assign label to contour point - ASSIGN_LABEL( tnext, labels, image.size().width, label ); - - // add chain code to current contour - currentBlobcontour->AddChainCode(movement); - } - -} - -/** -- FUNCI�: tracer -- FUNCIONALITAT: Searches for next point of a contour -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/30 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -cv::Point tracer( cv::Mat image, cv::Mat* maskImage, cv::Point P, bool *visitedPoints, - short initialMovement, - unsigned char backgroundColor, short &movement ) -{ - int d; - cv::Point pNext; - - for (d = 0; d <= 7; d++ ) - { - movement = (initialMovement + d) % 8; - - pNext.x = P.x + freemanCodeIncrement[movement].x; - pNext.y = P.y + freemanCodeIncrement[movement].y; - - // the point is inside image ? - if( pNext.x < 0 || pNext.x >= image.size().width || - pNext.y < 0 || pNext.y >= image.size().height ) - { - // try other movement - continue; - } - - // image has blobColor value in the new point? - if( (GET_IMAGE_PIXEL( image, pNext ) != backgroundColor ) && GET_IMAGEMASK_PIXEL(maskImage, pNext ) ) - { - return pNext; - } - else - { - // mark point as visited - ASSIGN_VISITED( pNext, visitedPoints, image.size().width ); - } - } - - // no possible movement was found - movement = -1; - pNext.x = P.x; - pNext.y = P.y; - - return pNext; -} - - diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.h b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.h deleted file mode 100644 index 5aa8ee5..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/ComponentLabeling.h +++ /dev/null @@ -1,30 +0,0 @@ -#if !defined(_COMPONENT_LABELING_H_INCLUDED) -#define _CLASSE_BLOBRESULT_INCLUDED - -#include "vector" -#include "BlobContour.h" -#include "blob.h" - - -//! definici� de que es un vector de blobs -typedef std::vector<CBlob*> Blob_vector; - - - -bool ComponentLabeling(cv::Mat inputImage, - cv::Mat* maskImage, - unsigned char backgroundColor, - Blob_vector &blobs ); - - -void contourTracing( cv::Mat image, cv::Mat* mask, cv::Point contourStart, t_labelType *labels, - bool *visitedPoints, t_labelType label, - bool internalContour, unsigned char backgroundColor, - CBlobContour *currentBlobContour ); - -cv::Point tracer( cv::Mat image, cv::Mat* mask, cv::Point P, bool *visitedPoints, - short initialMovement, - unsigned char backgroundColor, short &movement ); - - -#endif //!_CLASSE_BLOBRESULT_INCLUDED diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.cpp deleted file mode 100644 index 8842c5f..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.cpp +++ /dev/null @@ -1,709 +0,0 @@ -/************************************************************************ - Blob.cpp - -- FUNCIONALITAT: Implementaci� de la classe CBlob -- AUTOR: Inspecta S.L. -MODIFICACIONS (Modificaci�, Autor, Data): - - -FUNCTIONALITY: Implementation of the CBlob class and some helper classes to perform - some calculations on it -AUTHOR: Inspecta S.L. -MODIFICATIONS (Modification, Author, Date): - -**************************************************************************/ - - -#include "blob.h" - -#include <opencv2/opencv.hpp> -#include <opencv2/imgproc/imgproc_c.h> - - -CBlob::CBlob() -{ - m_area = m_perimeter = -1; - m_externPerimeter = m_meanGray = m_stdDevGray = -1; - m_boundingBox.width = -1; - m_ellipse.size.width = -1; - m_storage = NULL; - m_id = -1; -} -CBlob::CBlob( t_labelType id, cv::Point startPoint, cv::Size originalImageSize ) -{ - m_id = id; - m_area = m_perimeter = -1; - m_externPerimeter = m_meanGray = m_stdDevGray = -1; - m_boundingBox.width = -1; - m_ellipse.size.width = -1; - m_storage = cvCreateMemStorage(); - m_externalContour = CBlobContour(startPoint, m_storage); - m_originalImageSize = originalImageSize; -} -//! Copy constructor -CBlob::CBlob( const CBlob &src ) -{ - m_storage = NULL; - *this = src; -} - -CBlob::CBlob( const CBlob *src ) -{ - if (src != NULL ) - { - m_storage = NULL; - *this = *src; - } -} - -CBlob& CBlob::operator=(const CBlob &src ) -{ - if( this != &src ) - { - m_id = src.m_id; - m_area = src.m_area; - m_perimeter = src.m_perimeter; - m_externPerimeter = src.m_externPerimeter; - m_meanGray = src.m_meanGray; - m_stdDevGray = src.m_stdDevGray; - m_boundingBox = src.m_boundingBox; - m_ellipse = src.m_ellipse; - m_originalImageSize = src.m_originalImageSize; - - // clear all current blob contours - ClearContours(); - - if( m_storage ) - cvReleaseMemStorage( &m_storage ); - - m_storage = cvCreateMemStorage(); - - m_externalContour = CBlobContour(src.m_externalContour.GetStartPoint(), m_storage ); - if( src.m_externalContour.m_contour ) - m_externalContour.m_contour = cvCloneSeq( src.m_externalContour.m_contour, m_storage); - m_internalContours.clear(); - - // copy all internal contours - if( src.m_internalContours.size() ) - { - m_internalContours = t_contourList( src.m_internalContours.size() ); - t_contourList::const_iterator itSrc; - t_contourList::iterator it; - - itSrc = src.m_internalContours.begin(); - it = m_internalContours.begin(); - - while (itSrc != src.m_internalContours.end()) - { - *it = CBlobContour((*itSrc).GetStartPoint(), m_storage); - if( (*itSrc).m_contour ) - (*it).m_contour = cvCloneSeq( (*itSrc).m_contour, m_storage); - - it++; - itSrc++; - } - } - } - - return *this; -} - -CBlob::~CBlob() -{ - ClearContours(); - - if( m_storage ) - cvReleaseMemStorage( &m_storage ); -} - -void CBlob::ClearContours() -{ - t_contourList::iterator it; - - it = m_internalContours.begin(); - - while (it != m_internalContours.end()) - { - (*it).ResetChainCode(); - it++; - } - m_internalContours.clear(); - - m_externalContour.ResetChainCode(); - -} -void CBlob::AddInternalContour( const CBlobContour &newContour ) -{ - m_internalContours.push_back(newContour); -} - -//! Indica si el blob est� buit ( no t� cap info associada ) -//! Shows if the blob has associated information -bool CBlob::IsEmpty() -{ - return GetExternalContour()->m_contour == NULL; -} - -/** -- FUNCI�: Area -- FUNCIONALITAT: Get blob area, ie. external contour area minus internal contours area -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/30 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -double CBlob::Area() -{ - double area; - t_contourList::iterator itContour; - - area = m_externalContour.GetArea(); - - itContour = m_internalContours.begin(); - - while (itContour != m_internalContours.end() ) - { - area -= (*itContour).GetArea(); - itContour++; - } - return area; -} - -/** -- FUNCI�: Perimeter -- FUNCIONALITAT: Get blob perimeter, ie. sum of the lenght of all the contours -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/04/30 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -double CBlob::Perimeter() -{ - double perimeter; - t_contourList::iterator itContour; - - perimeter = m_externalContour.GetPerimeter(); - - itContour = m_internalContours.begin(); - - while (itContour != m_internalContours.end() ) - { - perimeter += (*itContour).GetPerimeter(); - itContour++; - } - return perimeter; - -} - -/** -- FUNCI�: Exterior -- FUNCIONALITAT: Return true for extern blobs -- PAR�METRES: - - xBorder: true to consider blobs touching horizontal borders as extern - - yBorder: true to consider blobs touching vertical borders as extern -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/05/06 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -int CBlob::Exterior(IplImage *mask, bool xBorder /* = true */, bool yBorder /* = true */) -{ - if (ExternPerimeter(mask, xBorder, yBorder ) > 0 ) - { - return 1; - } - - return 0; -} -/** -- FUNCI�: ExternPerimeter -- FUNCIONALITAT: Get extern perimeter (perimeter touching image borders) -- PAR�METRES: - - maskImage: if != NULL, counts maskImage black pixels as external pixels and contour points touching - them are counted as external contour points. - - xBorder: true to consider blobs touching horizontal borders as extern - - yBorder: true to consider blobs touching vertical borders as extern -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/05/05 -- MODIFICACI�: Data. Autor. Descripci�. -- NOTA: If CBlobContour::GetContourPoints aproximates contours with a method different that NONE, - this function will not give correct results -*/ -double CBlob::ExternPerimeter( IplImage *maskImage, bool xBorder /* = true */, bool yBorder /* = true */) -{ - t_PointList externContour, externalPoints; - CvSeqReader reader; - CvSeqWriter writer; - cv::Point actualPoint, previousPoint; - bool find = false; - int i,j; - int delta = 0; - - // it is calculated? - if( m_externPerimeter != -1 ) - { - return m_externPerimeter; - } - - // get contour pixels - externContour = m_externalContour.GetContourPoints(); - - m_externPerimeter = 0; - - // there are contour pixels? - if( externContour == NULL ) - { - return m_externPerimeter; - } - - cvStartReadSeq( externContour, &reader); - - // create a sequence with the external points of the blob - externalPoints = cvCreateSeq( externContour->flags, externContour->header_size, externContour->elem_size, - m_storage ); - cvStartAppendToSeq( externalPoints, &writer ); - previousPoint.x = -1; - - // which contour pixels touch border? - for( j=0; j< externContour->total; j++) - { - CV_READ_SEQ_ELEM( actualPoint, reader); - - find = false; - - // pixel is touching border? - if ( xBorder & ((actualPoint.x == 0) || (actualPoint.x == m_originalImageSize.width - 1 )) || - yBorder & ((actualPoint.y == 0) || (actualPoint.y == m_originalImageSize.height - 1 ))) - { - find = true; - } - else - { - if( maskImage != NULL ) - { - // verify if some of 8-connected neighbors is black in mask - char *pMask; - - pMask = (maskImage->imageData + actualPoint.x - 1 + (actualPoint.y - 1) * maskImage->widthStep); - - for ( i = 0; i < 3; i++, pMask++ ) - { - if(*pMask == 0 && !find ) - { - find = true; - break; - } - } - - if(!find) - { - pMask = (maskImage->imageData + actualPoint.x - 1 + (actualPoint.y ) * maskImage->widthStep); - - for ( i = 0; i < 3; i++, pMask++ ) - { - if(*pMask == 0 && !find ) - { - find = true; - break; - } - } - } - - if(!find) - { - pMask = (maskImage->imageData + actualPoint.x - 1 + (actualPoint.y + 1) * maskImage->widthStep); - - for ( i = 0; i < 3; i++, pMask++ ) - { - if(*pMask == 0 && !find ) - { - find = true; - break; - } - } - } - } - } - - if( find ) - { - if( previousPoint.x > 0 ) - delta = abs(previousPoint.x - actualPoint.x) + abs(previousPoint.y - actualPoint.y); - - // calculate separately each external contour segment - if( delta > 2 ) - { - cvEndWriteSeq( &writer ); - m_externPerimeter += cvArcLength( externalPoints, CV_WHOLE_SEQ, 0 ); - - cvClearSeq( externalPoints ); - cvStartAppendToSeq( externalPoints, &writer ); - delta = 0; - previousPoint.x = -1; - } - - CV_WRITE_SEQ_ELEM( actualPoint, writer ); - previousPoint = actualPoint; - } - - } - - cvEndWriteSeq( &writer ); - - m_externPerimeter += cvArcLength( externalPoints, CV_WHOLE_SEQ, 0 ); - - cvClearSeq( externalPoints ); - - // divide by two because external points have one side inside the blob and the other outside - // Perimeter of external points counts both sides, so it must be divided - m_externPerimeter /= 2.0; - - return m_externPerimeter; -} - -//! Compute blob's moment (p,q up to MAX_CALCULATED_MOMENTS) -double CBlob::Moment(int p, int q) -{ - double moment; - t_contourList::iterator itContour; - - moment = m_externalContour.GetMoment(p,q); - - itContour = m_internalContours.begin(); - - while (itContour != m_internalContours.end() ) - { - moment -= (*itContour).GetMoment(p,q); - itContour++; - } - return moment; -} - -/** -- FUNCI�: Mean -- FUNCIONALITAT: Get blob mean color in input image -- PAR�METRES: - - image: image from gray color are extracted -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/05/06 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -double CBlob::Mean( IplImage *image ) -{ - // it is calculated? -/* if( m_meanGray != -1 ) - { - return m_meanGray; - } -*/ - // Create a mask with same size as blob bounding box - IplImage *mask; - CvScalar mean, std; - cv::Point offset; - - GetBoundingBox(); - - if (m_boundingBox.height == 0 ||m_boundingBox.width == 0 || !CV_IS_IMAGE( image )) - { - m_meanGray = 0; - return m_meanGray; - } - - // apply ROI and mask to input image to compute mean gray and standard deviation - mask = cvCreateImage( cvSize(m_boundingBox.width, m_boundingBox.height), IPL_DEPTH_8U, 1); - cvSetZero(mask); - - offset.x = -m_boundingBox.x; - offset.y = -m_boundingBox.y; - - // draw contours on mask - cvDrawContours( mask, m_externalContour.GetContourPoints(), cvScalar(CV_RGB(255,255,255)), cvScalar(CV_RGB(255,255,255)),0, CV_FILLED, 8, - cvPoint(offset) ); - - // draw internal contours - t_contourList::iterator it = m_internalContours.begin(); - while(it != m_internalContours.end() ) - { - cvDrawContours( mask, (*it).GetContourPoints(), cvScalar(CV_RGB(0,0,0)), cvScalar(CV_RGB(0,0,0)),0, CV_FILLED, 8, - cvPoint(offset) ); - it++; - } - - cvSetImageROI( image, m_boundingBox ); - cvAvgSdv( image, &mean, &std, mask ); - - m_meanGray = mean.val[0]; - m_stdDevGray = std.val[0]; - - cvReleaseImage( &mask ); - cvResetImageROI( image ); - - return m_meanGray; -} - -double CBlob::StdDev( IplImage *image ) -{ - // it is calculated? -/* if( m_stdDevGray != -1 ) - { - return m_stdDevGray; - } -*/ - // call mean calculation (where also standard deviation is calculated) - Mean( image ); - - return m_stdDevGray; -} -/** -- FUNCI�: GetBoundingBox -- FUNCIONALITAT: Get bounding box (without rotation) of a blob -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/05/06 -- MODIFICACI�: Data. Autor. Descripci�. -*/ -CvRect CBlob::GetBoundingBox() -{ - // it is calculated? - if( m_boundingBox.width != -1 ) - { - return m_boundingBox; - } - - t_PointList externContour; - CvSeqReader reader; - cv::Point actualPoint; - - // get contour pixels - externContour = m_externalContour.GetContourPoints(); - - // it is an empty blob? - if( !externContour ) - { - m_boundingBox.x = 0; - m_boundingBox.y = 0; - m_boundingBox.width = 0; - m_boundingBox.height = 0; - - return m_boundingBox; - } - - cvStartReadSeq( externContour, &reader); - - m_boundingBox.x = m_originalImageSize.width; - m_boundingBox.y = m_originalImageSize.height; - m_boundingBox.width = 0; - m_boundingBox.height = 0; - - for( int i=0; i< externContour->total; i++) - { - CV_READ_SEQ_ELEM( actualPoint, reader); - - m_boundingBox.x = MIN( actualPoint.x, m_boundingBox.x ); - m_boundingBox.y = MIN( actualPoint.y, m_boundingBox.y ); - - m_boundingBox.width = MAX( actualPoint.x, m_boundingBox.width ); - m_boundingBox.height = MAX( actualPoint.y, m_boundingBox.height ); - } - - //m_boundingBox.x = max( m_boundingBox.x , 0 ); - //m_boundingBox.y = max( m_boundingBox.y , 0 ); - - m_boundingBox.width -= m_boundingBox.x; - m_boundingBox.height -= m_boundingBox.y; - - return m_boundingBox; -} - -/** -- FUNCI�: GetEllipse -- FUNCIONALITAT: Calculates bounding ellipse of external contour points -- PAR�METRES: - - -- RESULTAT: - - -- RESTRICCIONS: - - -- AUTOR: rborras -- DATA DE CREACI�: 2008/05/06 -- MODIFICACI�: Data. Autor. Descripci�. -- NOTA: Calculation is made using second order moment aproximation -*/ -CvBox2D CBlob::GetEllipse() -{ - // it is calculated? - if( m_ellipse.size.width != -1 ) - return m_ellipse; - - double u00,u11,u01,u10,u20,u02, delta, num, den, temp; - - // central moments calculation - u00 = Moment(0,0); - - // empty blob? - if ( u00 <= 0 ) - { - m_ellipse.size.width = 0; - m_ellipse.size.height = 0; - m_ellipse.center.x = 0; - m_ellipse.center.y = 0; - m_ellipse.angle = 0; - return m_ellipse; - } - u10 = Moment(1,0) / u00; - u01 = Moment(0,1) / u00; - - u11 = -(Moment(1,1) - Moment(1,0) * Moment(0,1) / u00 ) / u00; - u20 = (Moment(2,0) - Moment(1,0) * Moment(1,0) / u00 ) / u00; - u02 = (Moment(0,2) - Moment(0,1) * Moment(0,1) / u00 ) / u00; - - - // elipse calculation - delta = sqrt( 4*u11*u11 + (u20-u02)*(u20-u02) ); - m_ellipse.center.x = float(u10); - m_ellipse.center.y = float(u01); - - temp = u20 + u02 + delta; - if( temp > 0 ) - { - m_ellipse.size.width = sqrt(float( 2*(u20 + u02 + delta ))); - } - else - { - m_ellipse.size.width = 0; - return m_ellipse; - } - - temp = u20 + u02 - delta; - if( temp > 0 ) - { - m_ellipse.size.height = sqrt(float( 2*(u20 + u02 - delta ) )); - } - else - { - m_ellipse.size.height = 0; - return m_ellipse; - } - - // elipse orientation - if (u20 > u02) - { - num = u02 - u20 + sqrt((u02 - u20)*(u02 - u20) + 4*u11*u11); - den = 2*u11; - } - else - { - num = 2*u11; - den = u20 - u02 + sqrt((u20 - u02)*(u20 - u02) + 4*u11*u11); - } - if( num != 0 && den != 00 ) - { - m_ellipse.angle = float( 180.0 + (180.0 / CV_PI) * atan( num / den ) ); - } - else - { - m_ellipse.angle = 0; - } - - return m_ellipse; - -} - -/** -- FUNCTION: FillBlob -- FUNCTIONALITY: - - Fills the blob with a specified colour -- PARAMETERS: - - imatge: where to paint - - color: colour to paint the blob -- RESULT: - - modifies input image and returns the seed point used to fill the blob -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -void CBlob::FillBlob( IplImage *imatge, CvScalar color, int offsetX /*=0*/, int offsetY /*=0*/) -{ - cvDrawContours( imatge, m_externalContour.GetContourPoints(), color, color,0, CV_FILLED, 8 ); -} - - -/** -- FUNCTION: GetConvexHull -- FUNCTIONALITY: Calculates the convex hull polygon of the blob -- PARAMETERS: - - dst: where to store the result -- RESULT: - - true if no error ocurred -- RESTRICTIONS: -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -t_PointList CBlob::GetConvexHull() -{ - CvSeq *convexHull = NULL; - - if( m_externalContour.GetContourPoints() ) - convexHull = cvConvexHull2( m_externalContour.GetContourPoints(), m_storage, - CV_COUNTER_CLOCKWISE, 1 ); - - return convexHull; -} - -/** -- FUNCTION: JoinBlob -- FUNCTIONALITY: Add's external contour to current external contour -- PARAMETERS: - - blob: blob from which extract the added external contour -- RESULT: - - true if no error ocurred -- RESTRICTIONS: Only external contours are added -- AUTHOR: Ricard Borr�s -- CREATION DATE: 25-05-2005. -- MODIFICATION: Date. Author. Description. -*/ -void CBlob::JoinBlob( CBlob *blob ) -{ - CvSeqWriter writer; - CvSeqReader reader; - t_chainCode chainCode; - - cvStartAppendToSeq( m_externalContour.GetChainCode(), &writer ); - cvStartReadSeq( blob->GetExternalContour()->GetChainCode(), &reader ); - - for (int i = 0; i < blob->GetExternalContour()->GetChainCode()->total; i++ ) - { - CV_READ_SEQ_ELEM( chainCode, reader ); - CV_WRITE_SEQ_ELEM( chainCode, writer ); - } - cvEndWriteSeq( &writer ); - -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.h b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.h deleted file mode 100644 index 2d30a4d..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.h +++ /dev/null @@ -1,169 +0,0 @@ -/************************************************************************ - Blob.h - -FUNCIONALITAT: Definici� de la classe CBlob -AUTOR: Inspecta S.L. -MODIFICACIONS (Modificaci�, Autor, Data): - -FUNCTIONALITY: Definition of the CBlob class and some helper classes to perform - some calculations on it -AUTHOR: Inspecta S.L. -MODIFICATIONS (Modification, Author, Date): - -**************************************************************************/ - -//! Disable warnings referred to 255 character truncation for the std:map -#pragma warning( disable : 4786 ) - -#ifndef CBLOB_INSPECTA_INCLUDED -#define CBLOB_INSPECTA_INCLUDED - -#include <list> - -#include <opencv2/opencv.hpp> - -#include "BlobLibraryConfiguration.h" -#include "BlobContour.h" - - -//! Type of labelled images -typedef unsigned int t_labelType; - - -//! Blob class -class CBlob -{ - typedef std::list<CBlobContour> t_contourList; - -public: - CBlob(); - CBlob( t_labelType id, cv::Point startPoint, cv::Size originalImageSize ); - ~CBlob(); - - //! Copy constructor - CBlob( const CBlob &src ); - CBlob( const CBlob *src ); - - //! Operador d'assignaci� - //! Assigment operator - CBlob& operator=(const CBlob &src ); - - //! Adds a new internal contour to the blob - void AddInternalContour( const CBlobContour &newContour ); - - //! Retrieves contour in Freeman's chain code - CBlobContour *GetExternalContour() - { - return &m_externalContour; - } - - //! Retrieves blob storage - CvMemStorage *GetStorage() - { - return m_storage; - } - - //! Get label ID - t_labelType GetID() - { - return m_id; - } - //! > 0 for extern blobs, 0 if not - int Exterior( IplImage *mask, bool xBorder = true, bool yBorder = true ); - //! Compute blob's area - double Area(); - //! Compute blob's perimeter - double Perimeter(); - //! Compute blob's moment (p,q up to MAX_CALCULATED_MOMENTS) - double Moment(int p, int q); - - //! Compute extern perimeter - double ExternPerimeter( IplImage *mask, bool xBorder = true, bool yBorder = true ); - - //! Get mean grey color - double Mean( IplImage *image ); - - //! Get standard deviation grey color - double StdDev( IplImage *image ); - - //! Indica si el blob est� buit ( no t� cap info associada ) - //! Shows if the blob has associated information - bool IsEmpty(); - - //! Retorna el poligon convex del blob - //! Calculates the convex hull of the blob - t_PointList GetConvexHull(); - - //! Pinta l'interior d'un blob d'un color determinat - //! Paints the blob in an image - void FillBlob( IplImage *imatge, CvScalar color, int offsetX = 0, int offsetY = 0 ); - - //! Join a blob to current one (add's contour - void JoinBlob( CBlob *blob ); - - //! Get bounding box - CvRect GetBoundingBox(); - //! Get bounding ellipse - CvBox2D GetEllipse(); - - //! Minimun X - double MinX() - { - return GetBoundingBox().x; - } - //! Minimun Y - double MinY() - { - return GetBoundingBox().y; - } - //! Maximun X - double MaxX() - { - return GetBoundingBox().x + GetBoundingBox().width; - } - //! Maximun Y - double MaxY() - { - return GetBoundingBox().y + GetBoundingBox().height; - } -private: - - //! Deallocates all contours - void ClearContours(); - ////////////////////////////////////////////////////////////////////////// - // Blob contours - ////////////////////////////////////////////////////////////////////////// - - - //! Contour storage memory - CvMemStorage *m_storage; - //! External contour of the blob (crack codes) - CBlobContour m_externalContour; - //! Internal contours (crack codes) - t_contourList m_internalContours; - - ////////////////////////////////////////////////////////////////////////// - // Blob features - ////////////////////////////////////////////////////////////////////////// - - //! Label number - t_labelType m_id; - //! Area - double m_area; - //! Perimeter - double m_perimeter; - //! Extern perimeter from blob - double m_externPerimeter; - //! Mean gray color - double m_meanGray; - //! Standard deviation from gray color blob distribution - double m_stdDevGray; - //! Bounding box - CvRect m_boundingBox; - //! Bounding ellipse - CvBox2D m_ellipse; - //! Sizes from image where blob is extracted - cv::Size m_originalImageSize; -}; - -#endif //CBLOB_INSPECTA_INCLUDED diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/IDetector.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/detector/IDetector.cpp deleted file mode 100644 index 15fc6f1..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/IDetector.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "IDetector.h" - -#include "../../../../helper/CvHelper.h" -template <typename T> - -std::vector<FishPose> IDetector<T>::convertBlobPosesToFishPoses(std::vector<BlobPose> blobPoses) -{ - std::vector<FishPose> fishPoses; - fishPoses.reserve(blobPoses.size()); - - for (BlobPose & blobPose : blobPoses) - { - fishPoses.push_back( - FishPose( - blobPose.posCm(), - blobPose.posPx(), - CvHelper::degToRad(blobPose.angleDegree()), - blobPose.angleDegree(), - blobPose.width(), - blobPose.height() - ) - ); - } - - return fishPoses; -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/IDetector.h b/Src/Model/TrackingAlgorithm/imageProcessor/detector/IDetector.h deleted file mode 100644 index 8aa5db6..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/IDetector.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include "../../../TrackedComponents/pose/FishPose.h" -#include "Interfaces/IModel/IModelAreaDescriptor.h" -#include "blob/BlobPose.h" - -template <typename T> -class IDetector -{ -public: - - /** - * The contructor with parameters. - * @param: rectification, the rectification object for calculation the real world coordinate. - * @param: systemProperty, the set of parameters for tracking property. - */ - IDetector(void) {} - - /** - * The standard abtract destructor. - */ - ~IDetector(void) {} - - /** - * Interface function to get the fish poses from a binarzied image. - * @param: binarized_image_mat, binarized image. - * @return: a list of fish poses. - */ - virtual std::vector<T> getPoses(cv::Mat& binImage, cv::Mat& oriImage) = 0; - - - /** - * Convert vector of blob poses to fishes poses. - * @param: blobPoses, vector of blob poses, - * @return: vector of fish poses. - */ - static std::vector<FishPose> convertBlobPosesToFishPoses(std::vector<BlobPose> blobPoses); - - /** - * Sets specified parameter with a double value. - * @param: spec_param, the specified parameter to set, - * @param: value, the value double to set, - * @return: void. - */ - virtual void setDouble(std::string spec_param, double value) = 0; - - /** - * Gets the specified parameter. - * @param: spec_param, the specified parameter to set, - * @return: the double value of the specifed paramter. - */ - //virtual void getDouble(std::string spec_param) = 0; - - /** - * - */ - void setAreaInfo(IModelAreaDescriptor* ai) { - _areaInfo = ai; - } - -private: - virtual std::vector<T> findBlobs(const cv::Mat& binImage, const cv::Mat& oriImage) = 0; - -protected: - IModelAreaDescriptor* _areaInfo; -}; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.cpp deleted file mode 100644 index aa7d449..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "BlobPose.h" - -BlobPose::BlobPose(void) -{ -} - -BlobPose::BlobPose(cv::Point2f center_cm, cv::Point center_px, float angle_degree, float width, float height, bool use) : - _center_cm(center_cm), - _center_px(center_px), - _angle_degree(angle_degree), - _width(width), - _height(height), - _used(use) -{} - -BlobPose::~BlobPose(void) -{ -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.h b/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.h deleted file mode 100644 index 4ebaf7b..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/BlobPose.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#include <opencv2/opencv.hpp> - -class BlobPose -{ -public: - /** - * The standard contructor. - */ - BlobPose(void); - - /** - * The contructor with parameters. - * @param: pos_cm, position in real world coordinate. - * @param: pos_px, position in pixel coordinate. - * @param: angle_degree, orientation angle in degree. - * @param: width, width in px. - * @param: height, height in px. - * @param: used, check if this blob pose is currently in use. - */ - BlobPose(cv::Point2f pos_cm, cv::Point pos_px, float angle_degree, float width, float height, bool use = false); - - /** - * The standard destructor. - */ - ~BlobPose(void); - - /** - * Gets the pixel position of the pose. - * @return pixel position. - */ - cv::Point posPx() { return _center_px; } - - /** - * Gets the real world position of the pose. - * @return real world position. - */ - cv::Point2f posCm() { return _center_cm; } - - /** - * Gets the orientation angle as degree of the pose. - * @return degree angle. - */ - float angleDegree() { return _angle_degree; } - - /** - * Gets the width of the blob pose. - * @return width in px. - */ - float width() { return _width; } - - /** - * Gets the height of the blob pose. - * @return height in px. - */ - float height() { return _height; } - - /** - * Gets the flag whether this pose blob is already in use. - * @return true if is used, false otherwise. - */ - bool isUsed() { return _used; } - - /** - * Sets the pixel position of the pose. - * @param int x, int y - * @return void. - */ - void setposPx(int x, int y) { cv::Point point(x,y); _center_px = point; } - - /** - * Sets the angle in degree. - * @param float angleDegree - * @return void. - */ - void setAngle(float angleDegree) { _angle_degree = angleDegree; } - -private: - bool _used; - cv::Point2f _center_cm; - cv::Point _center_px; - float _angle_degree; - float _width; - float _height; -}; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.cpp deleted file mode 100644 index cfd62a6..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "BlobsDetector.h" -#include "../../../../../../helper/CvHelper.h" - -#include <assert.h> -BlobsDetector::BlobsDetector(void) : - _mask(nullptr), - _minBlobSize(1), //TODO Min blob size - _maxBlobSize(99999) //TODO Max blob size -{} - - -void BlobsDetector::filterBlobsBySize(CBlobResult& blobs) -{ - // blobs smaller than the provided blob size - blobs.Filter( blobs, B_INCLUDE, CBlobGetArea(), B_GREATER_OR_EQUAL, minBlobSize()); - - // blobs bigger than the provided blob size - blobs.Filter( blobs, B_INCLUDE, CBlobGetArea(), B_LESS_OR_EQUAL, maxBlobSize()); -} - -bool isLeft(cv::Point a, cv::Point b, cv::Point c) { - return ((b.x - a.x)*(c.y - a.y) - (b.y - a.y)*(c.x - a.x)) > 0; -} - -std::vector<BlobPose> BlobsDetector::findBlobs(const cv::Mat& processedImage, const cv::Mat& oriImage) -{ - std::vector<BlobPose> blobPoses; - - CBlob *currentBlob; - CBlobResult blobs(processedImage, _mask, 0); - - // filter the blobs by size criteria - filterBlobsBySize(blobs); - - for (int i = 0; i < blobs.GetNumBlobs(); i++) - { - currentBlob = blobs.GetBlob(i); - - // gets blob center - int x = currentBlob->GetEllipse().center.x; - int y = currentBlob->GetEllipse().center.y; - cv::Point blobPose_px = cv::Point(x, y); - - // apply homography - cv::Point2f blobPose_cm =_areaInfo->pxToCm(blobPose_px); - - // ignore blobs outside the tracking area - if (!_areaInfo->inTrackingArea(blobPose_px)) - continue; - - float blobPose_angle_deg = currentBlob->GetEllipse().angle; - float blobPose_angle_rad = currentBlob->GetEllipse().angle * CV_PI / float(180.0); - assert(blobPose_angle_deg >= 0.0f && blobPose_angle_deg <= 360.0f); - - float blobPose_width = currentBlob->GetEllipse().size.width; - float blobPose_height = currentBlob->GetEllipse().size.height; - - blobPoses.push_back(BlobPose(blobPose_cm, blobPose_px, blobPose_angle_deg, blobPose_angle_rad, blobPose_width, blobPose_height)); - } - - return blobPoses; -} - -std::vector<BlobPose> BlobsDetector::getPoses(cv::Mat& processedImage, cv::Mat& oriImage) -{ - return findBlobs(processedImage, oriImage); -} - -void BlobsDetector::setDouble(std::string spec_param, double value) -{ - if(spec_param.compare("1") == 0) { - this->setMinBlobSize(value); - } - else if (spec_param.compare("999999") == 0) { - this->setMaxBlobSize(value); - } - else { - std::cout << "BlobsDetector::Warning - Parameter: " << spec_param << " not found!" << std::endl; - } -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.h b/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.h deleted file mode 100644 index e6e339f..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/cvBlob/BlobsDetector.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "../../IDetector.h" -#include "../BlobPose.h" -#include "../../../cvblobs/BlobResult.h" - -class BlobsDetector : public IDetector<BlobPose> -{ -public: - - /** - * The contructor with parameters. - * @param: rectification, the rectification object for calculation the real world coordinate. - * @param: systemProperty, the set of parameters for tracking property. - */ - BlobsDetector(void); - - virtual ~BlobsDetector(void) {} - - void setMask(cv::Mat *mask) { _mask = mask; } - - std::vector<BlobPose> getPoses(cv::Mat& binImage, cv::Mat& oriImage); - - - void setDouble(std::string spec_param, double value); - - double minBlobSize() { return _minBlobSize; }; - double maxBlobSize() { return _maxBlobSize; }; - void setMinBlobSize(double x) { _minBlobSize = x; }; - void setMaxBlobSize(double x) { _maxBlobSize = x; }; - -private: - - /** - * Removes blobs, which are too big for the further hanlding. - * @param: blobs, all possible blobs with all possible size. - * @return: void. - */ - void filterBlobsBySize(CBlobResult& blobs); - - /** - * Find all blobs within an image. - * @param: binarized_image_mat, image contains blobs and is already binarized, - * @return: all found blobs within the image. - */ - - // TODO: can we make binImage a reference?? - std::vector<BlobPose> findBlobs(const cv::Mat& binImage, const cv::Mat& oriImage); - - double _minBlobSize; - double _maxBlobSize; - - cv::Mat *_mask; -}; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.cpp deleted file mode 100644 index 4c5ae92..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "SimpleBlobsDetector.h" -#include "../../../../../../helper/CvHelper.h" -#include <limits> - -SimpleBlobsDetector::SimpleBlobsDetector(void) : _mask(nullptr) -{ - initParams(); -} - -void SimpleBlobsDetector::initParams() -{ - _params.minThreshold = 15; - _params.maxThreshold = 50; - _params.thresholdStep = 5; - _params.filterByArea = true; - _params.minArea = 1; - _params.maxArea = 999999; - _params.filterByInertia = false; - _params.filterByColor = true; - _params.blobColor = 255; - _params.filterByCircularity = false; - _params.minDistBetweenBlobs = 0; -} - - -std::vector<BlobPose> SimpleBlobsDetector::findBlobs(const cv::Mat& binImage, const cv::Mat& oriImage) -{ - std::vector<BlobPose> blobPoses; - - std::vector<cv::KeyPoint> keyPoints; - - cv::Ptr<cv::SimpleBlobDetector> blobDetector = cv::SimpleBlobDetector::create(_params); - - blobDetector->detect( binImage, keyPoints); - - for (int i = 0; i < keyPoints.size(); i++) - { - // gets blob center - int x = keyPoints.at(i).pt.x; - int y = keyPoints.at(i).pt.y; - cv::Point blobPose_px = cv::Point(x, y); - - // apply homography - cv::Point2f blobPose_cm = _areaInfo->pxToCm(blobPose_px); - - if (!_areaInfo->inTrackingArea(blobPose_px)) - continue; - - float blobPose_angleDegree = keyPoints.at(i).angle; // as degree (0..360) - float blobPose_angleRadian = keyPoints.at(i).angle * float(CV_PI) / float(180.0); - float blobPose_width = keyPoints.at(i).size; - float blobPose_height = keyPoints.at(i).size; - - blobPoses.push_back(BlobPose(blobPose_cm, blobPose_px, blobPose_angleDegree, blobPose_angleRadian, blobPose_width, blobPose_height)); - } - - - return blobPoses; -} - - -std::vector<BlobPose> SimpleBlobsDetector::getPoses(cv::Mat& binarized_image_mat, cv::Mat& original_image_mat) -{ - return findBlobs(binarized_image_mat,original_image_mat); -} - -void SimpleBlobsDetector::setDouble(std::string spec_param, double value) -{ - if(spec_param.compare("1") == 0) { //TRACKERPARAM::MIN_BLOB_SIZE - _params.minArea = value; - } else { - std::cout << "SimpleBlobsDetector::Warning - Parameter: " << spec_param << " not found!" << std::endl; - } - - if(spec_param.compare("999999") == 0) { //TRACKERPARAM::MAX_BLOB_SIZE - _params.maxArea = value; - } else { - std::cout << "SimpleBlobsDetector::Warning - Parameter: " << spec_param << " not found!" << std::endl; - } -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.h b/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.h deleted file mode 100644 index e5b3be4..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/blob/simpleBlob/SimpleBlobsDetector.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "../../IDetector.h" - -#include "../BlobPose.h" -#include "../../../cvblobs/BlobResult.h" - -#include "opencv2/features2d/features2d.hpp" -#include "opencv2/objdetect/objdetect.hpp" - -class SimpleBlobsDetector : public IDetector<BlobPose> -{ -public: - - /** - * The contructor with parameters. - */ - SimpleBlobsDetector(void); - - virtual ~SimpleBlobsDetector(void) {} - - void setMask(cv::Mat *mask) { _mask = mask; } - - std::vector<BlobPose> getPoses(cv::Mat& binImage, cv::Mat& oriImage); - - void setDouble(std::string spec_param, double value); - -private: - - cv::Mat *_mask; - cv::SimpleBlobDetector::Params _params; - - /** - * Initialized the parameter for setting up the blob detector. - * @return: void. - */ - void initParams(); - - /** - * Find all blobs within an image. - * @param: binarized_image_mat, image contains blobs and is already binarized, - * @return: all found blobs within the image. - */ - - // TODO: can we make binImage a reference?? - std::vector<BlobPose> findBlobs(const cv::Mat& binImage, const cv::Mat& oriImage); - - -}; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.cpp deleted file mode 100644 index cd65b94..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "ContourPose.h" - -ContourPose::ContourPose(void) -{ -} - -ContourPose::ContourPose(cv::Point2f center_cm, cv::Point center_px, float angle_degree, float width, float height, bool use) : - _center_cm(center_cm), - _center_px(center_px), - _angle_degree(angle_degree), - _width(width), - _height(height), - _used(use) -{} - -ContourPose::~ContourPose(void) -{ -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.h b/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.h deleted file mode 100644 index 4e7e3da..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContourPose.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -#include <opencv2/opencv.hpp> - -class ContourPose -{ -public: - /** - * The standard contructor. - */ - ContourPose(void); - - /** - * The contructor with parameters. - * @param: pos_cm, position in real world coordinate. - * @param: pos_px, position in pixel coordinate. - * @param: angle_degree, orientation angle in degree. - * @param: width, width in px. - * @param: height, height in px. - * @param: used, check if this blob pose is currently in use. - */ - ContourPose(cv::Point2f pos_cm, cv::Point pos_px, float angle_degree, float width, float height, bool use = false); - - /** - * The standard destructor. - */ - ~ContourPose(void); - - /** - * Gets the pixel position of the pose. - * @return pixel position. - */ - cv::Point posPx() { return _center_px; } - - /** - * Gets the real world position of the pose. - * @return real world position. - */ - cv::Point2f posCm() { return _center_cm; } - - /** - * Gets the orientation angle as degree of the pose. - * @return degree angle. - */ - float angleDegree() { return _angle_degree; } - - /** - * Gets the width of the blob pose. - * @return width in px. - */ - float width() { return _width; } - - /** - * Gets the height of the blob pose. - * @return height in px. - */ - float height() { return _height; } - - /** - * Gets the flag whether this pose blob is already in use. - * @return true if is used, false otherwise. - */ - bool isUsed() { return _used; } - - -private: - bool _used; - cv::Point2f _center_cm; - cv::Point _center_px; - float _angle_degree; - float _width; - float _height; -}; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp deleted file mode 100644 index 59e7a93..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "ContoursDetector.h" -#include "../../../../../helper/CvHelper.h" - -std::vector<ContourPose> ContoursDetector::findBlobs(const cv::Mat& binImage, const cv::Mat& oriImage) -{ - std::vector<ContourPose> contourPoses; - - return contourPoses; -} - -std::vector<ContourPose> ContoursDetector::findContours(const cv::Mat& binImage, const cv::Mat& oriImage) -{ - return findBlobs(binImage,oriImage); -} - -void ContoursDetector::createMask(std::vector<cv::Point> points) -{} -// if (_xRes == 0 || _yRes == 0) -// return; -// -// mask = cvCreateImage(cvSize(_xRes, _yRes), IPL_DEPTH_8U,1);//erstellt schwarzwei� bild -// -// //folgender Block setzt die Pixel schwarz -// for( int y=0; y<mask->height; y++ ) { -// uchar* ptr = (uchar*) ( mask->imageData + y * mask->widthStep ); -// for( int x=0; x<mask->width; x++ ) { -// ptr[x+2] = 0; -// } -// } -// -// cv::Point maskPoints[4]; -// -// for(int z=0;z<4;z++) -// { -// maskPoints[z] = points[z]; -// } -// -// //Array im Array von Polygonen. Hier Gr��e eins, da nur eins erzeugt wird -// cv::Point* contours[1]={ -// maskPoints, -// }; -// -// //Anzahl der Punkte der Polygone. Anzahl wie oben -// int contours_n[1]={ -// 4, -// }; -// -// //opencv Funktion zum erstellen und ausf�llen eines polygons in weiss -// cvFillPoly(mask, contours, contours_n, 1, cvScalar(255)); -// -// //Visualisierung zum Debuggen -// //cvNamedWindow("MyWindow",CV_WINDOW_AUTOSIZE); -// //cvShowImage("MyWindow", mask); -// //cvWaitKey(0); -// //cvReleaseImage(&mask); -// //cvDestroyWindow("MyWindow"); -//} - - -std::vector<ContourPose> ContoursDetector::getPoses(cv::Mat& image_mat, cv::Mat& image_ori) -{ - return findContours(image_mat,image_ori); -} - -void ContoursDetector::setDouble(std::string spec_param, double value) -{ - std::cout << "ContoursDetector::Warning - Parameter: " << spec_param << " not found!" << std::endl; -} \ No newline at end of file diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.h b/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.h deleted file mode 100644 index 71fd301..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "../IDetector.h" - -#include "ContourPose.h" - -class ContoursDetector : public IDetector<ContourPose> -{ -public: - - /** - * The contructor with parameters. - */ - ContoursDetector(void) {} - - ~ContoursDetector(void) {} - - std::vector<ContourPose> getPoses(cv::Mat& binImage, cv::Mat& oriImage); - - void setDouble(std::string spec_param, double value); - -private: - - /** - * Find all cntours within an image. - * @param: binarized_image_mat, image contains blobs and is already binarized, - * @return: all found blobs within the image. - */ - std::vector<ContourPose> findBlobs(const cv::Mat& binImage, const cv::Mat& oriImage); - - std::vector<ContourPose> findContours(const cv::Mat& binImage, const cv::Mat& oriImage); - - void createMask(std::vector<cv::Point> points); - - cv::Mat _mask; -}; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp deleted file mode 100644 index e0ae07b..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include "ImagePreProcessor.h" - -#include <opencv2/highgui.hpp> - -#include <future> -#include <QMutex> - -QMutex bgsMutex; -QMutex oriImageMutex; -QMutex initBgkFrameNumMutex; -QMutex mog2Mutex; - -ImagePreProcessor::ImagePreProcessor(TrackerParameter* p_TrackingParameter) : - _maxBackgroundImageInitTime(0), //BG_MOG2_INIT_FRAME_NUMBER TODO - _bkgSubMethodMog2(false) -{ - _TrackingParameter = p_TrackingParameter; - init(); -} - -ImagePreProcessor::~ImagePreProcessor(void) -{ -} - -void ImagePreProcessor::setBkgFrameNum(int frameNum) -{ - QMutexLocker locker(&initBgkFrameNumMutex); - _maxBackgroundImageInitTime = frameNum; -} - -int ImagePreProcessor::getBkgFrameNum() -{ - QMutexLocker locker(&initBgkFrameNumMutex); - return _maxBackgroundImageInitTime; -} - - -void ImagePreProcessor::init() -{ - QMutexLocker locker(&bgsMutex); - - m_backgroundImage = std::make_shared<cv::Mat>(); - m_foregroundImage = std::make_shared<cv::Mat>(); - - _pMOG = cv::createBackgroundSubtractorMOG2( - _TrackingParameter->getmog2History(), - _TrackingParameter->getmog2VarThresh(), - true); //Shadow detection - - _backgroundSubtractionEnabled = true; - _backgroundEnabled = true; - _erodeEnabled = true; - _dilateEnabled = true; - _gaussianBlurEnabled = false; - _binarizeEnabled = true; - _resetBackgroundImageEnabled = false; -} - -cv::Mat ImagePreProcessor::binarize(cv::Mat& image) -{ - cv::Mat binarizedImage; - - if (image.channels() >= 3) - cv::cvtColor(image, binarizedImage, cv::COLOR_BGR2GRAY); - else - image.copyTo(binarizedImage); - - if (binarizedImage.data) - cv::threshold(binarizedImage, binarizedImage, m_TrackingParameter->getBinarizationThreshold(), 255, cv::THRESH_BINARY); - - return binarizedImage; -} - -cv::Mat ImagePreProcessor::erode(cv::Mat& image) -{ - cv::Mat erodedImage; - cv::Mat erodeKernel; - int sizeErode = m_TrackingParameter->getSizeErode(); - if (sizeErode > 0) - { - erodeKernel = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(sizeErode, sizeErode)); - } - else { - return image; - } - if (image.data) - cv::erode(image, erodedImage, erodeKernel); - return erodedImage; -} - -cv::Mat ImagePreProcessor::dilate(cv::Mat& image) -{ - cv::Mat dilatedImage; - cv::Mat dilateKernel; - int sizeDilate = m_TrackingParameter->getSizeDilate(); - if (sizeDilate > 0) - { - dilateKernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(sizeDilate, sizeDilate)); - } - else { - return image; - } - if (image.data) - cv::dilate(image, dilatedImage, dilateKernel); - return dilatedImage; -} - -cv::Mat ImagePreProcessor::backgroundSubtraction(cv::Mat& image) -{ - if (false)//(isEnabledMog2()) - { - //QMutexLocker locker(&bgsMutex); - cv::Mat fgMaskMOG; - _pMOG->setBackgroundRatio(m_TrackingParameter->getmog2BackgroundRatio()); - - _pMOG->apply(image, fgMaskMOG); //fg mask generated by MOG method - _pMOG->getBackgroundImage(*m_backgroundImage); - return fgMaskMOG; - } - - // otherwise, custom background subtraction - - if (!m_backgroundImage->data) - image.copyTo(*m_backgroundImage); - - // calculate the image difference - const double alpha = m_TrackingParameter->getmog2BackgroundRatio(); - - const int &imageWidth = m_backgroundImage->cols; - const int &imageHeight = m_backgroundImage->rows; - const int totalRegionsX = 4; - const int totalRegionsY = 4; - const int totalRegions = totalRegionsX * totalRegionsY; - const int regionWidth = imageWidth / totalRegionsX; - const int regionHeight = imageHeight / totalRegionsY; - - cv::Mat results(imageHeight, imageWidth, image.type()); - - auto workOnRegion = [&](int x, int y) { - const int startingX = x * regionWidth; - const int startingY = y * regionHeight; - const cv::Rect subArea = cv::Rect(startingX, startingY, regionWidth, regionHeight); - cv::Mat subBackground = (*m_backgroundImage)(subArea); - cv::Mat subImage = image(subArea); - cv::Mat subResults = results(subArea); - - subResults = (subBackground - subImage); - subBackground = (1.0 - alpha) * subBackground + alpha * subImage; - }; - - std::vector<std::future<void>> merger; - merger.reserve(totalRegions); - - for (int x = 0; x < totalRegionsX; ++x) - { - for (int y = 0; y < totalRegionsY; ++y) - { - merger.push_back(std::async([&, x, y] { workOnRegion(x, y); })); - } - } - - for (const auto & asyncResult : merger) - asyncResult.wait(); - - return results; -} - -std::map<std::string, std::shared_ptr<cv::Mat>> ImagePreProcessor::preProcess(std::shared_ptr<cv::Mat> p_image) -{ - std::shared_ptr<cv::Mat> greyMat = std::make_shared<cv::Mat>(); - std::shared_ptr<cv::Mat> binarizedImage = std::make_shared<cv::Mat>(); - std::shared_ptr<cv::Mat> erodedImage = std::make_shared<cv::Mat>(); - std::shared_ptr<cv::Mat> dilatedImage = std::make_shared<cv::Mat>(); - //cv::Mat test; - - cv::cvtColor(*p_image, *greyMat, cv::COLOR_BGR2GRAY); - - // 1. step: do the background subtraction - *m_foregroundImage = backgroundSubtraction(*greyMat); - - // 2. step: binarize the image - *binarizedImage = binarize(*m_foregroundImage); - - // 3. step: erode the image - *erodedImage = erode(*binarizedImage); - - // 4. step: dilate the image - *dilatedImage = dilate(*erodedImage); - - std::map<std::string, std::shared_ptr<cv::Mat>> all; - all.insert(std::pair<std::string, std::shared_ptr<cv::Mat>>(std::string("Greyscale"), greyMat)); - all.insert(std::pair<std::string, std::shared_ptr<cv::Mat>>(std::string("Background"), m_backgroundImage)); - all.insert(std::pair<std::string, std::shared_ptr<cv::Mat>>(std::string("Difference"), m_foregroundImage)); - all.insert(std::pair<std::string, std::shared_ptr<cv::Mat>>(std::string("Binarized"), binarizedImage)); - all.insert(std::pair<std::string, std::shared_ptr<cv::Mat>>(std::string("Eroded"), erodedImage)); - all.insert(std::pair<std::string, std::shared_ptr<cv::Mat>>(std::string("Dilated"), dilatedImage)); - - return all; -} - -void ImagePreProcessor::resetBackgroundImage() -{ - // this will reset the background at the next opportunity - init(); -} - -bool ImagePreProcessor::isEnabledMog2() -{ - return _bkgSubMethodMog2; -} - -void ImagePreProcessor::setEnabledMog2(bool enable) -{ - QMutexLocker locker(&mog2Mutex); - _bkgSubMethodMog2 = enable; -} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h deleted file mode 100644 index 7a8d55e..0000000 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include <QSettings> - -#include <opencv2/opencv.hpp> - -#include "../../../../helper/StringHelper.h" -#include "../../../TrackerParameter.h" - - -class ImagePreProcessor -{ -public: - - /** - * The standard constructor. - */ - ImagePreProcessor(TrackerParameter* p_TrackingParameter); - - /** - * The standard destructor. - */ - ~ImagePreProcessor(void); - - /** - * Init function. Sets the property for the imge pre-processing. - * @return void. - */ - void init(); - - /** - * A computer vision method to binarize an image. - * @param: image, image to binarize, - * @return: a binarized image. - */ - cv::Mat binarize(cv::Mat& image); - - /** - * A mathematical morphology operation using in computer vision to erode an image. - * Erode image with 3x3 4-connectivity. - * @param: image, image to erode, - * @return: an eroded image. - */ - cv::Mat erode(cv::Mat& image); - - /** - * A mathematical morphology operation using in computer vision to dilate an image. - * Dilate image with 6x6 8-connectivity. - * @param: image, image to dilate, - * @return: a dilated image. - */ - cv::Mat dilate(cv::Mat& image); - - /** - * A computer vision methode to calculate the image difference. - * Background image subtracts the foreground image. - * @param: image, image to background subtract, - * @return: the background subtracted image. - */ - cv::Mat backgroundSubtraction(cv::Mat& image); - - /** - * Pre-process an image, if all methods enabled, this function: - * - does the background subtraction - * - erodes the image - * - dilates the image - * @param: image, image to process, - * @return: a pre-process image. - */ - std::map<std::string, std::shared_ptr<cv::Mat>> preProcess(std::shared_ptr<cv::Mat> p_image); - - /** - * The method updates the image background. - * @return: void. - */ - void resetBackgroundImage(); - TrackerParameter* m_TrackingParameter; - -private: - - - cv::Mat _outputImage; - - int m_Mog2ShadowDetection = true; - std::shared_ptr<cv::Mat> m_backgroundImage; - std::shared_ptr<cv::Mat> m_foregroundImage; - - // background subtraction - cv::Ptr<cv::BackgroundSubtractorMOG2> _pMOG; - - //parameters for image pre-processing - bool _backgroundSubtractionEnabled; - bool _backgroundEnabled; - bool _binarizeEnabled; - bool _erodeEnabled; - bool _dilateEnabled; - bool _gaussianBlurEnabled; - bool _resetBackgroundImageEnabled; - - int _maxBackgroundImageInitTime; - bool _bkgSubMethodMog2; - - TrackerParameter* _TrackingParameter; - - // functions - void setBkgFrameNum(int); - int getBkgFrameNum(); - - void setEnabledMog2(bool); - bool isEnabledMog2(); -}; diff --git a/Src/View/TrackedElementView.cpp b/Src/View/TrackedElementView.cpp index f9cdea1..8b29f6a 100644 --- a/Src/View/TrackedElementView.cpp +++ b/Src/View/TrackedElementView.cpp @@ -1,7 +1,6 @@ #include "TrackedElementView.h" #include "../Model/TrackedComponents/TrackedElement.h" #include "../Model/TrackedComponents/TrackedTrajectory.h" -#include "../Model/TrackingAlgorithm/ParamNames.h" #include "QBrush" #include "QPainter" #include "QGraphicsScene" diff --git a/Src/helper/CvHelper.cpp b/Src/helper/CvHelper.cpp deleted file mode 100644 index 5cf0a91..0000000 --- a/Src/helper/CvHelper.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include "CvHelper.h" - -#include "StringHelper.h" - -cv::Point CvHelper::subtractTwoCvPoints(cv::Point a, cv::Point b) -{ - return cv::Point(a.x - b.x, a.y - b.y); -} - -cv::Point CvHelper::addTwoCvPoints(cv::Point a, cv::Point b) -{ - return cv::Point(a.x + b.x, a.y + b.y); -} - -cv::Point CvHelper::multCvPoint(double scalar, cv::Point p) -{ - return cv::Point(scalar * p.x, scalar * p.y); -} - -QPointF CvHelper::norm(double x, double y) -{ - double distance = qSqrt(x * x + y * y); - - if (distance == 0) { - return QPointF(0, 0); - } - return QPointF(x / distance, y / distance); -} - -QPointF CvHelper::norm(QPoint p) -{ - return CvHelper::norm((double) p.x(), (double) p.y()); -} - -QPointF CvHelper::norm(QPointF p) -{ - return CvHelper::norm(p.x(), p.y()); -} - -double CvHelper::getDistance(double x1, double y1, double x2, double y2) -{ - return qSqrt( ( (x1 - x2) * (x1 - x2) ) + ( (y1 - y2) * (y1 - y2) ) ); -} - -double CvHelper::getDistance(double x1, double y1, double z1, double x2, double y2, double z2 ) -{ - return qSqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)) + ((z1 - z2) * (z1 - z2))); -} - -double CvHelper::getSqDistance(double x1, double y1, double x2, double y2) -{ - return ( (x1 - x2) * (x1 - x2) ) + ( (y1 - y2) * (y1 - y2) ); -} - -double CvHelper::getSqDistance(double x1, double y1, double z1, double x2, double y2, double z2) -{ - return ((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)) + ((z1 - z2) * (z1 - z2)); -} - -double CvHelper::getDistance(QPoint p1, QPoint p2) -{ - return getDistance((double) p1.x(), (double) p1.y(), (double) p2.x(), (double) p2.y()); -} - -double CvHelper::getDistance(QPointF p1, QPointF p2) -{ - return getDistance(p1.x(), p1.y(), p2.x(), p2.y()); -} - -double CvHelper::getDistance(cv::Point2f p1, cv::Point2f p2) -{ - return getDistance(p1.x, p1.y, p2.x, p2.y); -} - -double CvHelper::getDistance(cv::Point3f p1, cv::Point3f p2) -{ - return getDistance(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z); -} - -double CvHelper::getDistance(cv::Point p1, cv::Point p2) -{ - return sqrt(double((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))); -} - -double CvHelper::getSqDistance(cv::Point2f p1, cv::Point2f p2) -{ - return getSqDistance(p1.x, p1.y, p2.x, p2.y); -} - -double CvHelper::getSqDistance(cv::Point3f p1, cv::Point3f p2) -{ - return getSqDistance(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z); -} - -double CvHelper::orientation(cv::Point2f front, cv::Point2f back) -{ - cv::Point2f diff = front - back; - //return qAtan2(diff.x, diff.y); - - // need to check the origin of coorindiates - return qAtan2(diff.x, diff.y) + CV_PI / 2.0; -} - -double CvHelper::orientation(QPointF front, QPointF back) -{ - //QPointF diff = front - back; - //return qAtan2(diff.x(), diff.y()); - return orientation(cv::Point2f(front.x(),front.y()),cv::Point2f(back.x(),back.y())); -} - -float CvHelper::angleDifference(float alpha, float beta) -{ - float difference = alpha - beta; - while (difference < -CV_PI) difference += 2.0f * CV_PI; - while (difference > +CV_PI) difference -= 2.0f * CV_PI; - return difference; -} - -float CvHelper::findMin(float n1, float n2, float n3) { - return (n1 < n2 && n1 < n3) ? n1 : (n2 < n3 ? n2 : n3); -} - -float CvHelper::findMax(float n1, float n2, float n3) { - return (n1 > n2 && n1 > n3) ? n1 : (n2 > n3 ? n2 : n3); -} - -float CvHelper::normalDist(float x, float mean, float variance) { - return 1.0 / (variance *qSqrt(2*CV_PI)) * qExp(- ((x - mean) * (x - mean)) / (2 * variance * variance)); -} - -float CvHelper::sigmoid(float x, float shrink) { - return (2.0 / (1.0 + qExp(-x * shrink)) - 1.0); -} - -float CvHelper::sigmoidAbsInv(float x, float shrink) { - return 1.0 - qAbs((2.0 / (1.0 + qExp(-x * shrink)) - 1.0)); -} - -double CvHelper::getAngleDifference(double dirToTargetAsRad, double currOrientationAsRad) { - /*double angleDiff = dirToTargetAsRad - currOrientationAsRad + CV_PI / 2.0; - while (angleDiff < -CV_PI) angleDiff += 2 * CV_PI; - while (angleDiff > CV_PI) angleDiff -= 2 * CV_PI; - return angleDiff;*/ - - double a = dirToTargetAsRad - currOrientationAsRad; - a += (a > CV_PI) ? -(2*CV_PI) : (a < -CV_PI) ? (2*CV_PI) : 0; - return a; -} - -//double CvHelper::getAngleToTarget(cv::Point2f A, cv::Point2f B) { -// double ab = A.x*B.x + A.y*B.y; -// double a = qSqrt(A.x*A.x + A.y*A.y); -// double b = qSqrt(B.x*B.x + B.y*B.y); -// double cosT = ab / (a*b); -// return qAcos(cosT); -//} - -double CvHelper::getAngleToTarget(cv::Point2f currentPos, cv::Point2f targetPos) { - return qAtan2(targetPos.x - currentPos.x, targetPos.y - currentPos.y); -} - -std::deque<cv::Point2f> CvHelper::convertMat2Point2fDeque(cv::Mat mat) -{ - std::deque<cv::Point2f> point2fS; - - if(mat.cols != 2) - return point2fS; - - for (int row = 0; row < mat.rows; row++) - { - float x = mat.at<float>(row,0); - float y = mat.at<float>(row,1); - point2fS.push_back(cv::Point2f(x,y)); - } - - return point2fS; -} - -cv::Mat CvHelper::convertPoint2fDeque2Mat(std::deque<cv::Point2f> points) -{ - cv::Mat mat; - - if(points.empty()) - return mat; - - mat = cv::Mat(points.size(), 2, CV_32F); - - for (int i = 0; i < points.size(); i++) - { - cv::Point2f p = points.at(i); - mat.at<float>(i,0)= p.x; - mat.at<float>(i,1)= p.y; - } - - return mat; -} - -QList<std::deque<cv::Point2f>> CvHelper::convertMatList2Point2fDequeList(QList<cv::Mat> mats) -{ - QList<std::deque<cv::Point2f>> pointList; - cv::Mat mat; - foreach (mat , mats) - { - pointList << CvHelper::convertMat2Point2fDeque(mat); - } - return pointList; -} - -cv::Point2f CvHelper::getMirrowPoint(cv::Point2f point2Mirror, cv::Point2f pointOfOrigin, float angelAsGrad) -{ - //Convert angelAsGrad to radian - float angelAsRadian = (angelAsGrad * CV_PI / 180.0); - - cv::Mat G = (cv::Mat_<float>(2,2) << cos(2.0 * angelAsRadian), sin(2.0 * angelAsRadian), sin(2.0 * angelAsRadian), -cos(2.0 * angelAsRadian)); - - cv::Mat point2MirrorMat(1/*rows*/,2 /* cols */,CV_32F); - point2MirrorMat.at<float>(0,0) = point2Mirror.x; - point2MirrorMat.at<float>(0,1) = point2Mirror.y; - - cv::Mat pointOfOriginMat(1/*rows*/,2 /* cols */,CV_32F); - pointOfOriginMat.at<float>(0,0) = pointOfOrigin.x; - pointOfOriginMat.at<float>(0,1) = pointOfOrigin.y; - - cv::Mat point2MirrorFromOrigin = point2MirrorMat - pointOfOriginMat; - - cv::Mat point2MirrorMatT; - cv::transpose(point2MirrorFromOrigin, point2MirrorMatT); - - cv::Mat mirrowedPointMat = (G * point2MirrorMatT); - - cv::Mat mirrowedPointMatT; - cv::transpose(mirrowedPointMat, mirrowedPointMatT); - - cv::Mat finalMat = mirrowedPointMatT + pointOfOriginMat; - - return cv::Point2f(finalMat.at<float>(0,0),finalMat.at<float>(0,1)); -} - -std::deque<cv::Point2f> CvHelper::getMirrowPoints(std::deque<cv::Point2f> points2Mirror, cv::Point2f pointOfOrigin, float angelAsGrad) -{ - std::deque<cv::Point2f> mirrowedPoints; - - for(int i = 0; i < points2Mirror.size(); i++) - { - cv::Point2f p = CvHelper::getMirrowPoint(points2Mirror.at(i), pointOfOrigin, angelAsGrad); - mirrowedPoints.push_back(p); - } - return mirrowedPoints; - -} - -std::deque<cv::Point2f> CvHelper::getMirrowLine(cv::Point2f pointOfOrigin, float width, float height, float angelAsGrad) -{ - float angle = angelAsGrad * CV_PI / 180.0; - - float r = CvHelper::getDistance(pointOfOrigin, cv::Point2f(width, height)); - - float xOff1 = pointOfOrigin.x + r * cos(angle); - float yOff1 = pointOfOrigin.y + r * sin(angle); - - float xOff2 = pointOfOrigin.x - r * cos(angle); - float yOff2 = pointOfOrigin.y - r * sin(angle); - - cv::Point2f front(xOff2,yOff2); - cv::Point2f back(xOff1,yOff1); - - std::deque<cv::Point2f> points; - - points.push_back(front); - points.push_back(back); - return points; -} - - -std::vector<cv::Point> CvHelper::convertMat2Vector(cv::Mat mat) -{ - std::vector<cv::Point> value(mat.rows); - for (int i = 0; i < value.size(); i++) - { - cv::Point p((int)mat.at<float>(i,0),(int)mat.at<float>(i,1)); - value.at(i) = p; - } - return value; -} - -cv::Mat CvHelper::convertVector2Mat(std::vector<cv::Point> vect) -{ - cv::Mat mat(vect.size(),2,CV_32F); - for (int i = 0; i < vect.size(); i++) - { - mat.at<float>(i,0) = (float)vect.at(i).x; - mat.at<float>(i,1) = (float)vect.at(i).y; - } - return mat; -} - -float CvHelper::degToRad(float deg) -{ - return deg * CV_PI / 180.0; -} - -float CvHelper::radToDeg(float rad) -{ - return rad * 180.0 / CV_PI; -} - -int CvHelper::stdStringToInt(std::string string) -{ - int numb; - std::istringstream iss(string); - if (!(iss >> numb)) - { - throw "String cannot convert to float number!"; - } - return numb; -} - -float CvHelper::stdStringToFloat(std::string string) -{ - float numb; - std::istringstream iss(string); - if (!(iss >> numb)) - { - throw "String cannot convert to float number!"; - } - - return numb; -} - -std::string CvHelper::convertStdVectorCvPointToStdString(std::vector<cv::Point> points) -{ - std::string pointListString; - for (int i = 0; i < points.size(); i++) - { - int x = points.at(i).x; - int y = points.at(i).y; - if(i < points.size() - 1) - pointListString.append(StringHelper::iToSS(x)).append(":").append(StringHelper::iToSS(y)).append(" "); - else - pointListString.append(StringHelper::iToSS(x)).append(":").append(StringHelper::iToSS(y)); - } - return pointListString; -} - -std::string CvHelper::convertCvScalarToStdString(cv::Scalar scalar) -{ - std::string scalarString; - - int r = scalar.val[0,0]; - int g = scalar.val[0,1]; - int b = scalar.val[0,2]; - - scalarString.append(StringHelper::iToSS(r)).append(" ").append(StringHelper::iToSS(g)).append(" ").append(StringHelper::iToSS(b)).append(" "); - - return scalarString; - -} - -std::string CvHelper::cvSizeToSS(cv::Size cvSize_value) -{ - std::string cvSizeString; - - int width = cvSize_value.width; - int height = cvSize_value.height; - - cvSizeString.append(StringHelper::iToSS(height)).append("x").append(StringHelper::iToSS(width)); - - return cvSizeString; -} - -std::string CvHelper::cvSize2fToSS(cv::Size2f cvSize2f_value) -{ - std::string cvSize2fString; - - float width = cvSize2f_value.width; - float height = cvSize2f_value.height; - - cvSize2fString.append(StringHelper::fToSS(height)).append("x").append(StringHelper::fToSS(width)); - - return cvSize2fString; -} - -std::string CvHelper::cvSize2fToSS(QString width, QString height) -{ - std::string cvSize2fString; - - cvSize2fString.append(height.toStdString()).append("x").append(width.toStdString()); - - return cvSize2fString; -} - -std::string CvHelper::getCurrentDatetimeAsStd() -{ - return QDateTime::currentDateTime().toString("_yyMMddThhmmss").toUtf8().constData(); -} - -bool CvHelper::isFrameSizeEqual(cv::Size o1, cv::Size o2) -{ - bool equal = false; - - if (o1.width == o2.width && o1.height == o2.height) - equal = true; - - return equal; -} \ No newline at end of file diff --git a/Src/helper/CvHelper.h b/Src/helper/CvHelper.h deleted file mode 100644 index 2c842df..0000000 --- a/Src/helper/CvHelper.h +++ /dev/null @@ -1,197 +0,0 @@ -#pragma once - -#include <QtMath> -#include <QPoint> -#include <QPointF> -#include <QList> -#include <QDateTime> -#include <QDebug> - -#include <opencv2/opencv.hpp> - - -/** - * Computer vision helper class, contains only static methods - */ -namespace CvHelper -{ - /** - * Subtract operation for two CvPoints. - * @return: the difference of the CvPoints. - */ - cv::Point subtractTwoCvPoints(cv::Point a, cv::Point b); - - /** - * Add operation for two CvPoints. - * @return: the sum of the CvPoints. - */ - cv::Point addTwoCvPoints(cv::Point a, cv::Point b); - - cv::Point multCvPoint(double scalar, cv::Point p); - - /** - * Normalizes a coordinate point. - * @param x, the x coordinate. - * @param y, the y coordinate. - * @return the normlized point as floating number. - */ - QPointF norm(double x, double y); - - /** - * Normalizes a point. - * @param p, point to normalize. - * @return the normalized point as floating number. - */ - QPointF norm(QPoint p); - - /** - * Normalizes a floating number point. - * @param p, point to normalize. - * @return the normalized point as floating number. - */ - QPointF norm(QPointF p); - - /** - * Calculates the distance between two coordinates. - * @param x1, x-coordinate of the source point. - * @param y1, y-coordinate of the source point. - * @param x2, x-coordinate of the destination point. - * @param y2, y-coordinate of the destination point. - * @return the distance between the provided coordinates as floating number. - */ - double getDistance(double x1, double y1, double x2, double y2); - double getSqDistance(double x1, double y1, double x2, double y2); - - /** - * Calculates the distance between two coordinates. - * @param x1, x-coordinate of the source point. - * @param y1, y-coordinate of the source point. - * @param z1, z-coordinate of the source point. - * @param x2, x-coordinate of the destination point. - * @param y2, y-coordinate of the destination point. - * @param z2, y-coordinate of the destination point. - * @return the distance between the provided coordinates as floating number. - */ - double getDistance(double x1, double y1, double z1, double x2, double y2, double z2); - double getSqDistance(double x1, double y1, double z1, double x2, double y2, double z2); - - /** - * Calculates the distance between two points. - * @param p1, source point. - * @param p2, destination point. - * @return the distance between p1 and p2 as floating number. - */ - double getDistance(QPoint p1, QPoint p2); - - /** - * Calculates the distance between two floating number points. - * @param p1, source point. - * @param p2, destination point. - * @return the distance between p1 and p2 as floating number. - */ - double getDistance(QPointF p1, QPointF p2); - - double getDistance(cv::Point2f p1, cv::Point2f p2); - double getDistance(cv::Point p1, cv::Point p2); - double getSqDistance(cv::Point2f p1, cv::Point2f p2); - - double getDistance(cv::Point3f p1, cv::Point3f p2); - double getSqDistance(cv::Point3f p1, cv::Point3f p2); - - double orientation(cv::Point2f front, cv::Point2f back); - double orientation(QPointF front, QPointF back); - - float angleDifference(float alpha, float beta); - - /** - * Convert degree to radian. - * @param: deg, degree value, - * @return: rad value. - */ - float degToRad(float deg); - - /** - * Convert radian to degree. - * @param: rad, radian value, - * @return: degree value. - */ - float radToDeg(float rad); - - /** - * This function finds the minimal number of three numbers. - */ - float findMin(float n1, float n2, float n3); - - /** - * This function finds the maximal number of three numbers. - */ - float findMax(float n1, float n2, float n3); - - float normalDist(float x, float mean, float variance); - - float sigmoid(float x, float shrink); - - float sigmoidAbsInv(float x, float shrink); - - double getAngleDifference(double dirToTargetAsRad, double currOrientationAsRad); - double getAngleToTarget(cv::Point2f A, cv::Point2f B); - //double getAngleToTarget(cv::Point2f currentPos, cv::Point2f targetPos); - - cv::Point2f getMirrowPoint(cv::Point2f point2Mirror, cv::Point2f pointOfOrigin, float angelAsGrad); - std::deque<cv::Point2f> getMirrowPoints(std::deque<cv::Point2f> points2Mirror, cv::Point2f pointOfOrigin, float angelAsGrad); - std::deque<cv::Point2f> getMirrowLine(cv::Point2f pointOfOrigin, float width, float height, float angelAsGrad); - - - std::deque<cv::Point2f> convertMat2Point2fDeque(cv::Mat mat); - cv::Mat convertPoint2fDeque2Mat(std::deque<cv::Point2f> points); - QList<std::deque<cv::Point2f>> convertMatList2Point2fDequeList(QList<cv::Mat> mats); - std::vector<cv::Point> convertMat2Vector(cv::Mat mat); - cv::Mat convertVector2Mat(std::vector<cv::Point> vect); - - /** - * Converts a string to an integer number. - * @param: string, a string containing a number. - * @return: a converted integer number. - */ - int stdStringToInt(std::string string); - - /** - * Converts a string to a float number. - * @param: string, a string containing a number. - * @return: a converted float number. - */ - float stdStringToFloat(std::string string); - - /** - * Converts a list of cv::Point to a proper string, which could be save into the config.ini file. - * @param: points, a list of cv::Point. - * @return: a converted formated string for the config.ini file. - */ - std::string convertStdVectorCvPointToStdString(std::vector<cv::Point> points); - - /** - * Converts a cv::Scalar to a proper standard string, which could be save into the config.ini file. - * @param: scalar, a scalar. - * @return: a converted formated string for the config.ini file. - */ - std::string convertCvScalarToStdString(cv::Scalar scalar); - - /** - * Gets the current date time as std string. - * @return: the current formated date time as standard string. - */ - std::string getCurrentDatetimeAsStd(); - - std::string cvSizeToSS(cv::Size cvSize_value); - std::string cvSize2fToSS(cv::Size2f cvSize2f_value); - std::string cvSize2fToSS(QString width, QString height); - - - /** - * Checks if image sizes are equal. - * @param: size of first object - * @param: size of second object - * @return: true if equal, false otherwise - */ - bool isFrameSizeEqual(cv::Size o1, cv::Size o2); -} -- GitLab