diff --git a/Src/CMakeLists.txt b/Src/CMakeLists.txt index 8e6b18bd27d0e36e00ae7e94a912bc0d88f5b20f..8dc0aae19d643b26a11869fd1d106484f2f205ea 100644 --- a/Src/CMakeLists.txt +++ b/Src/CMakeLists.txt @@ -21,6 +21,8 @@ add_behavior_plugin(${target} "Model/TrackedComponents/TrackedTrajectory.cpp" "Model/TrackedComponents/pose/FishPose.cpp" "Model/TrackingAlgorithm/NN2dMapper.cpp" + "Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h" + "Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp" "Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp" "Model/TrackingAlgorithm/imageProcessor/cvblobs/blob.cpp" "Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobContour.cpp" diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..62653744096999a7dc6a5129bf67b3bd7abfff58 --- /dev/null +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp @@ -0,0 +1,53 @@ +#include "CustomBackgroundSubtractor.h" + +#include <vector> +#include <future> + +void CustomBackgroundSubtractor::getBackgroundImage(cv::OutputArray backgroundImage) const +{ + m_background.copyTo(backgroundImage); +} + +void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgmask, double learningRate) +{ + if (!m_background.data) { + image.copyTo(m_background); + } + + const int imageWidth = m_background.cols; + const int imageHeight = m_background.rows; + const int totalRegionsX = 4; + const int totalRegionsY = 4; + const int totalRegions = totalRegionsX * totalRegionsY; + const int regionWidth = imageWidth / totalRegionsX; + const int regionHeight = imageHeight / totalRegionsY; + + fgmask.create(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_background(subArea); + cv::Mat subImage = image.getMat()(subArea); + cv::Mat subResults = fgmask.getMat()(subArea); + + subResults = (subBackground - subImage); + subBackground = (1.0 - learningRate) * subBackground + learningRate * 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(); + } +} diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h new file mode 100644 index 0000000000000000000000000000000000000000..0f28bc2f8061899187f442d8d5174b10b558d1ea --- /dev/null +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h @@ -0,0 +1,14 @@ +#pragma once + +#include <opencv2/video/background_segm.hpp> + +class CustomBackgroundSubtractor : public cv::BackgroundSubtractor +{ +public: + void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRate = -1) override; + + void getBackgroundImage(cv::OutputArray backgroundImage) const override; + +private: + cv::Mat m_background; +}; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp index b44a2536da158ed36126510e8bc210c764cfb303..cac1f19c30d8f4c9641fb0b52cf538dcd4de350c 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp @@ -2,15 +2,17 @@ #include <opencv2/highgui.hpp> -#include <future> #include <QMutex> +#include "CustomBackgroundSubtractor.h" + QMutex bgsMutex; QMutex oriImageMutex; QMutex initBgkFrameNumMutex; ImagePreProcessor::ImagePreProcessor(TrackerParameter* p_TrackingParameter) : _maxBackgroundImageInitTime(0) + , m_subtractor(new CustomBackgroundSubtractor()) { _TrackingParameter = p_TrackingParameter; init(); @@ -100,49 +102,10 @@ cv::Mat ImagePreProcessor::dilate(cv::Mat& image) cv::Mat ImagePreProcessor::backgroundSubtraction(cv::Mat& image) { - if (!m_backgroundImage->data) - image.copyTo(*m_backgroundImage); - - // calculate the image difference - const double alpha = m_TrackingParameter->getBackgroundRatio(); - - 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; + cv::Mat foreground; + m_subtractor->apply(image, foreground, m_TrackingParameter->getBackgroundRatio()); + m_subtractor->getBackgroundImage(*m_backgroundImage); + return foreground; } std::map<std::string, std::shared_ptr<cv::Mat>> ImagePreProcessor::preProcess(std::shared_ptr<cv::Mat> p_image) diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h index 70b6709c7d5a22066eaf90cc65fab6d883cc0ec3..925e5d261547a0bdaf5ff322905967ff9ff72826 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h @@ -97,6 +97,8 @@ private: TrackerParameter* _TrackingParameter; + cv::BackgroundSubtractor* m_subtractor; + // functions void setBkgFrameNum(int); int getBkgFrameNum();