diff --git a/Src/Model/BioTrackerTrackingAlgorithm.cpp b/Src/Model/BioTrackerTrackingAlgorithm.cpp index 36dd0769d7738b65f6be0003a02067d3f82bbf7c..483c498584b1335ca6c4cd00abab38fe5ea999e7 100644 --- a/Src/Model/BioTrackerTrackingAlgorithm.cpp +++ b/Src/Model/BioTrackerTrackingAlgorithm.cpp @@ -77,21 +77,16 @@ void BioTrackerTrackingAlgorithm::sendSelectedImage(std::map<std::string, std::s Q_EMIT emitChangeDisplayImage(QString("Background")); break; case 2: - sendImage = images->find(std::string("Foreground"))->second; - Q_EMIT emitCvMatA(sendImage, QString("Foreground")); - Q_EMIT emitChangeDisplayImage(QString("Foreground")); + sendImage = images->find(std::string("Foreground Mask"))->second; + Q_EMIT emitCvMatA(sendImage, QString("Foreground Mask")); + Q_EMIT emitChangeDisplayImage(QString("Foreground Mask")); break; case 3: - sendImage = images->find(std::string("Binarized"))->second; - Q_EMIT emitCvMatA(sendImage, QString("Binarized")); - Q_EMIT emitChangeDisplayImage(QString("Binarized")); - break; - case 4: sendImage = images->find(std::string("Eroded"))->second; Q_EMIT emitCvMatA(sendImage, QString("Eroded")); Q_EMIT emitChangeDisplayImage(QString("Eroded")); break; - case 5: + case 4: sendImage = images->find(std::string("Dilated"))->second; Q_EMIT emitCvMatA(sendImage, QString("Dilated")); Q_EMIT emitChangeDisplayImage(QString("Dilated")); diff --git a/Src/Model/TrackerParameter.h b/Src/Model/TrackerParameter.h index 2a62b7b8809682c4be4637a8f9ec706794671519..02479e022ffb6f61589bd88342171b51872db293 100644 --- a/Src/Model/TrackerParameter.h +++ b/Src/Model/TrackerParameter.h @@ -28,8 +28,8 @@ public slots: Q_EMIT notifyView(); }; - double getBackgroundRatio() { return _LearningRate; }; - void setBackgroundRatio(double x) { + double getLearningRate() { return _LearningRate; }; + void setLearningRate(double x) { _LearningRate = x; Q_EMIT notifyView(); }; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp index 62653744096999a7dc6a5129bf67b3bd7abfff58..95e46cc4d4f6ce1afc6b059289506d2cae301fbb 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp @@ -3,6 +3,13 @@ #include <vector> #include <future> +#include <opencv2/imgproc.hpp> + +void CustomBackgroundSubtractor::setBinarizationThreshold(int value) +{ + m_binarizationThreshold = value; +} + void CustomBackgroundSubtractor::getBackgroundImage(cv::OutputArray backgroundImage) const { m_background.copyTo(backgroundImage); @@ -24,13 +31,15 @@ void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgm fgmask.create(imageHeight, imageWidth, image.type()); + auto fgmaskmat = fgmask.getMat(); + 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); + cv::Mat subResults = fgmaskmat(subArea); subResults = (subBackground - subImage); subBackground = (1.0 - learningRate) * subBackground + learningRate * subImage; @@ -50,4 +59,8 @@ void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgm for (const auto & asyncResult : merger) { asyncResult.wait(); } + + if (fgmaskmat.data) { + cv::threshold(fgmaskmat, fgmaskmat, m_binarizationThreshold, 255, cv::THRESH_BINARY); + } } diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h index 0f28bc2f8061899187f442d8d5174b10b558d1ea..551748cfdb8e4c7717633d8d4f44266c7b3d8407 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h @@ -9,6 +9,10 @@ public: void getBackgroundImage(cv::OutputArray backgroundImage) const override; + void setBinarizationThreshold(int value); + private: cv::Mat m_background; + + int m_binarizationThreshold; }; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp index cac1f19c30d8f4c9641fb0b52cf538dcd4de350c..06497ef219e4efc258ae805a941e6cbeb65d151e 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp @@ -40,7 +40,7 @@ void ImagePreProcessor::init() QMutexLocker locker(&bgsMutex); m_backgroundImage = std::make_shared<cv::Mat>(); - m_foregroundImage = std::make_shared<cv::Mat>(); + m_foregroundMask = std::make_shared<cv::Mat>(); _backgroundSubtractionEnabled = true; _backgroundEnabled = true; @@ -51,21 +51,6 @@ void ImagePreProcessor::init() _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; @@ -102,38 +87,37 @@ cv::Mat ImagePreProcessor::dilate(cv::Mat& image) cv::Mat ImagePreProcessor::backgroundSubtraction(cv::Mat& image) { - cv::Mat foreground; - m_subtractor->apply(image, foreground, m_TrackingParameter->getBackgroundRatio()); + if (auto subtractor = dynamic_cast<CustomBackgroundSubtractor*>(m_subtractor); subtractor) { + subtractor->setBinarizationThreshold(m_TrackingParameter->getBinarizationThreshold()); + } + + cv::Mat fgmask; + m_subtractor->apply(image, fgmask, m_TrackingParameter->getLearningRate()); m_subtractor->getBackgroundImage(*m_backgroundImage); - return foreground; + return fgmask; } 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::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); + *m_foregroundMask = backgroundSubtraction(*greyMat); - // 3. step: erode the image - *erodedImage = erode(*binarizedImage); + // 2. step: erode the image + *erodedImage = erode(*m_foregroundMask); - // 4. step: dilate the image + // 3. 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("Foreground"), 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("Foreground Mask"), m_foregroundMask)); 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)); diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h index 925e5d261547a0bdaf5ff322905967ff9ff72826..1cc9417797f9215e6b6ff8e60424ab4691882285 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h @@ -28,13 +28,6 @@ public: */ 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. @@ -82,7 +75,7 @@ private: cv::Mat _outputImage; std::shared_ptr<cv::Mat> m_backgroundImage; - std::shared_ptr<cv::Mat> m_foregroundImage; + std::shared_ptr<cv::Mat> m_foregroundMask; //parameters for image pre-processing bool _backgroundSubtractionEnabled; diff --git a/Src/View/TrackerParameterView.cpp b/Src/View/TrackerParameterView.cpp index a91d5593f9f1352faa2c39539dcc715f4945e329..984c2c9066c43f47e5b40e55138022fb281090c6 100644 --- a/Src/View/TrackerParameterView.cpp +++ b/Src/View/TrackerParameterView.cpp @@ -26,7 +26,7 @@ TrackerParameterView::TrackerParameterView(QWidget *parent, IController *control connect(_ui->lineEdit_9MaxBlob, qOverload<int>(&QSpinBox::valueChanged), parameter, &TrackerParameter::setMaxBlobSize); connect(_ui->lineEdit_9MaxBlob, qOverload<int>(&QSpinBox::valueChanged), this, &TrackerParameterView::parametersChanged); - connect(_ui->lineEdit_7_learningRate, qOverload<double>(&QDoubleSpinBox::valueChanged), parameter, &TrackerParameter::setBackgroundRatio); + connect(_ui->lineEdit_7_learningRate, qOverload<double>(&QDoubleSpinBox::valueChanged), parameter, &TrackerParameter::setLearningRate); connect(_ui->lineEdit_7_learningRate, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TrackerParameterView::parametersChanged); } @@ -61,7 +61,7 @@ void TrackerParameterView::getNotified() val = parameter->getSizeDilate(); _ui->lineEdit_4_SizeDilate->setValue(val); - double dval = parameter->getBackgroundRatio(); + double dval = parameter->getLearningRate(); _ui->lineEdit_7_learningRate->setValue(dval); val = parameter->getMinBlobSize(); diff --git a/Src/View/TrackerParameterView.ui b/Src/View/TrackerParameterView.ui index be7087ccace3ce8eb86d1a6b00959c01c331cb3e..1c183b7cab0fc7bc5dc29572be4a25e9297d0bf3 100644 --- a/Src/View/TrackerParameterView.ui +++ b/Src/View/TrackerParameterView.ui @@ -94,7 +94,7 @@ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> </property> <property name="horizontalSpacing"> - <number>44</number> + <number>13</number> </property> <item row="0" column="0"> <widget class="QLabel" name="label_7"> @@ -103,6 +103,26 @@ </property> </widget> </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Binarization Threshold:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="lineEdit_2_binThresh"> + <property name="minimumSize"> + <size> + <width>132</width> + <height>30</height> + </size> + </property> + <property name="toolTip"> + <string>Set the binarization threshold</string> + </property> + </widget> + </item> <item row="0" column="1"> <widget class="QDoubleSpinBox" name="lineEdit_7_learningRate"> <property name="minimumSize"> @@ -188,36 +208,16 @@ <enum>QFormLayout::ExpandingFieldsGrow</enum> </property> <property name="horizontalSpacing"> - <number>16</number> + <number>74</number> </property> <item row="0" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Binarization Threshold:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QSpinBox" name="lineEdit_2_binThresh"> - <property name="minimumSize"> - <size> - <width>132</width> - <height>30</height> - </size> - </property> - <property name="toolTip"> - <string>Set the binarization threshold</string> - </property> - </widget> - </item> - <item row="1" column="0"> <widget class="QLabel" name="label_3"> <property name="text"> <string>Size Erosion:</string> </property> </widget> </item> - <item row="1" column="1"> + <item row="0" column="1"> <widget class="QSpinBox" name="lineEdit_3_SizeErode"> <property name="minimumSize"> <size> @@ -230,14 +230,14 @@ </property> </widget> </item> - <item row="2" column="0"> + <item row="1" column="0"> <widget class="QLabel" name="label_4"> <property name="text"> <string>Size Dilation:</string> </property> </widget> </item> - <item row="2" column="1"> + <item row="1" column="1"> <widget class="QSpinBox" name="lineEdit_4_SizeDilate"> <property name="minimumSize"> <size> @@ -364,12 +364,7 @@ </item> <item> <property name="text"> - <string>Foreground</string> - </property> - </item> - <item> - <property name="text"> - <string>Binarized</string> + <string>Foreground Mask</string> </property> </item> <item>