diff --git a/Src/Config.cpp b/Src/Config.cpp index 1bcb8633472759d637aa4c77f3c281950f37dbfd..1d102787e7b29b9d9c2d1b0809d74990f57638c6 100644 --- a/Src/Config.cpp +++ b/Src/Config.cpp @@ -62,10 +62,21 @@ void Config::load(QString dir, QString file) config->BinarizationThreshold = tree.get<int>( globalPrefix + "BinarizationThreshold", config->BinarizationThreshold); - config->OpeningErosionSize = tree.get<int>(globalPrefix + "OpeningErosionSize", - config->OpeningErosionSize); - config->OpeningDilationSize = tree.get<int>(globalPrefix + "OpeningDilationSize", - config->OpeningDilationSize); + + config->OpeningErosionSize = tree.get<int>(globalPrefix + + "OpeningErosionSize", + config->OpeningErosionSize); + config->OpeningDilationSize = tree.get<int>(globalPrefix + + "OpeningDilationSize", + config->OpeningDilationSize); + + config->ClosingDilationSize = tree.get<int>(globalPrefix + + "ClosingDilationSize", + config->ClosingDilationSize); + config->ClosingErosionSize = tree.get<int>(globalPrefix + + "ClosingErosionSize", + config->ClosingErosionSize); + config->MinBlobSize = tree.get<int>(globalPrefix + "MinBlobSize", config->MinBlobSize); config->MaxBlobSize = tree.get<int>(globalPrefix + "MaxBlobSize", @@ -101,7 +112,11 @@ void Config::save(QString dir, QString file) tree.put(globalPrefix + "BinarizationThreshold", config->BinarizationThreshold); tree.put(globalPrefix + "OpeningErosionSize", config->OpeningErosionSize); - tree.put(globalPrefix + "OpeningDilationSize", config->OpeningDilationSize); + tree.put(globalPrefix + "OpeningDilationSize", + config->OpeningDilationSize); + tree.put(globalPrefix + "ClosingDilationSize", + config->ClosingDilationSize); + tree.put(globalPrefix + "ClosingErosionSize", config->ClosingErosionSize); tree.put(globalPrefix + "MinBlobSize", config->MinBlobSize); tree.put(globalPrefix + "MaxBlobSize", config->MaxBlobSize); tree.put(globalPrefix + "LearningRate", config->LearningRate); diff --git a/Src/Config.h b/Src/Config.h index e3ecd5fdedb0388a6b0e016fdce8bec95e79a0c2..690b9b2ffbf9365622de9f1f8959e712e84bbb45 100644 --- a/Src/Config.h +++ b/Src/Config.h @@ -10,8 +10,12 @@ public: bool UseAbsoluteDifference = true; int BinarizationThreshold = 40; - int OpeningErosionSize = 8; - int OpeningDilationSize = 8; + int OpeningErosionSize = 8; + int OpeningDilationSize = 8; + + int ClosingDilationSize = 8; + int ClosingErosionSize = 8; + int MinBlobSize = 40; int MaxBlobSize = 999999; diff --git a/Src/Model/BioTrackerTrackingAlgorithm.cpp b/Src/Model/BioTrackerTrackingAlgorithm.cpp index e0efb8652d2f714fb9222cdcb934dda4cd5221a3..f615e6e2273de05ea934601d16491e2732578e42 100644 --- a/Src/Model/BioTrackerTrackingAlgorithm.cpp +++ b/Src/Model/BioTrackerTrackingAlgorithm.cpp @@ -95,14 +95,14 @@ void BioTrackerTrackingAlgorithm::sendSelectedImage( Q_EMIT emitChangeDisplayImage(QString("Foreground Mask")); break; case 3: - sendImage = images->find(std::string("Eroded"))->second; - Q_EMIT emitCvMatA(sendImage, QString("Eroded")); - Q_EMIT emitChangeDisplayImage(QString("Eroded")); + sendImage = images->find(std::string("Opened Mask"))->second; + Q_EMIT emitCvMatA(sendImage, QString("Opened Mask")); + Q_EMIT emitChangeDisplayImage(QString("Opened Mask")); break; case 4: - sendImage = images->find(std::string("Dilated"))->second; - Q_EMIT emitCvMatA(sendImage, QString("Dilated")); - Q_EMIT emitChangeDisplayImage(QString("Dilated")); + sendImage = images->find(std::string("Closed Mask"))->second; + Q_EMIT emitCvMatA(sendImage, QString("Closed Mask")); + Q_EMIT emitChangeDisplayImage(QString("Closed Mask")); break; } } @@ -195,16 +195,16 @@ void BioTrackerTrackingAlgorithm::doTracking(std::shared_ptr<cv::Mat> p_image, // Do the preprocessing std::map<std::string, std::shared_ptr<cv::Mat>> images = _ipp.preProcess( p_image); - std::shared_ptr<cv::Mat> dilated = - images.find(std::string("Dilated"))->second; + std::shared_ptr<cv::Mat> mask = + images.find(std::string("Closed Mask"))->second; std::shared_ptr<cv::Mat> greyMat = images.find(std::string("Greyscale"))->second; // Find blobs via ellipsefitting _bd.setMaxBlobSize(_TrackingParameter->getMaxBlobSize()); _bd.setMinBlobSize(_TrackingParameter->getMinBlobSize()); - // std::vector<BlobPose> blobs = _bd.getPoses(*dilated, *greyMat); - std::vector<BlobPose> blobs = getContourCentroids(*dilated, 111); + // std::vector<BlobPose> blobs = _bd.getPoses(*mask, *greyMat); + std::vector<BlobPose> blobs = getContourCentroids(*mask, 111); // Never switch the position of the trajectories. The NN2d mapper relies on // this! If you mess up the order, add or remove some t, then create a new diff --git a/Src/Model/TrackerParameter.cpp b/Src/Model/TrackerParameter.cpp index 3a47fd550e7fa8cd195da8ac20666f65dc2178bd..1bdbab5cb34753163f3417f3babc885845b8299e 100644 --- a/Src/Model/TrackerParameter.cpp +++ b/Src/Model/TrackerParameter.cpp @@ -9,8 +9,10 @@ TrackerParameter::TrackerParameter(QObject* parent) _UseAbsoluteDifference = _cfg->UseAbsoluteDifference; _BinarizationThreshold = _cfg->BinarizationThreshold; - _OpeningErosionSize = _cfg->OpeningErosionSize; - _OpeningDilationSize = _cfg->OpeningDilationSize; + _OpeningErosionSize = _cfg->OpeningErosionSize; + _OpeningDilationSize = _cfg->OpeningDilationSize; + _ClosingDilationSize = _cfg->ClosingDilationSize; + _ClosingErosionSize = _cfg->ClosingErosionSize; _MinBlobSize = _cfg->MinBlobSize; _MaxBlobSize = _cfg->MaxBlobSize; diff --git a/Src/Model/TrackerParameter.h b/Src/Model/TrackerParameter.h index 64a268ee0f617007879dd97b1d85a85e05187440..2df14f01d5cd95311891818863ecd051f315a339 100644 --- a/Src/Model/TrackerParameter.h +++ b/Src/Model/TrackerParameter.h @@ -49,6 +49,28 @@ public slots: Q_EMIT notifyView(); }; + int getClosingDilationSize() + { + return _ClosingDilationSize; + }; + void setClosingDilationSize(int x) + { + _ClosingDilationSize = x; + _cfg->ClosingDilationSize = x; + Q_EMIT notifyView(); + }; + + int getClosingErosionSize() + { + return _ClosingErosionSize; + }; + void setClosingErosionSize(int x) + { + _ClosingErosionSize = x; + _cfg->ClosingErosionSize = x; + Q_EMIT notifyView(); + }; + double getLearningRate() { return _LearningRate; @@ -150,8 +172,11 @@ private: bool _UseAbsoluteDifference; int _BinarizationThreshold; - int _OpeningErosionSize; - int _OpeningDilationSize; + int _OpeningErosionSize; + int _OpeningDilationSize; + int _ClosingDilationSize; + int _ClosingErosionSize; + double _LearningRate; int _MinBlobSize; int _MaxBlobSize; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp index 02b23e9da65db7a809d683e2374d7b04686f9f8b..ea01bd50eb4829baf51fc28962b93d19783dc38e 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp +++ b/Src/Model/TrackingAlgorithm/imageProcessor/cvblobs/BlobResult.cpp @@ -843,9 +843,9 @@ void CBlobResult::PrintBlobs(char* nom_fitxer) const 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", + // 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] ); + // perimetreConvex[i], exterior[i], compacitat[i], longitud[i] ); } fclose(fitxer_sortida); } diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp index 6a76e59786859b05472b6744c5935fb238a30b86..0f86ae824e3db0031ea8d877e0998c6a479f0a31 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp +++ b/Src/Model/TrackingAlgorithm/imageProcessor/detector/contour/ContoursDetector.cpp @@ -23,7 +23,7 @@ void ContoursDetector::createMask(std::vector<cv::Point> points) // return; // // mask = cvCreateImage(cvSize(_xRes, _yRes), IPL_DEPTH_8U,1);//erstellt -//schwarzwei� bild +// schwarzwei� bild // // //folgender Block setzt die Pixel schwarz // for( int y=0; y<mask->height; y++ ) { diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp index f9ff90d721169db2e8da17826b32b841befd12dd..872a6244d5acf564bb0ba9f0888306b14af98fc7 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp @@ -44,38 +44,36 @@ void ImagePreProcessor::init() _resetBackgroundImageEnabled = false; } -cv::Mat ImagePreProcessor::erode(cv::Mat& image) +cv::Mat ImagePreProcessor::erode(cv::Mat image, int kernelSize) { - cv::Mat erodedImage; - cv::Mat erodeKernel; - int sizeErode = m_TrackingParameter->getOpeningErosionSize(); - if (sizeErode > 0) { - erodeKernel = cv::getStructuringElement( + if (kernelSize > 0 && image.data) { + auto kernel = cv::getStructuringElement( cv::MORPH_CROSS, - cv::Size(sizeErode, sizeErode)); + cv::Size(kernelSize, kernelSize)); + + cv::Mat morphed; + cv::erode(image, morphed, kernel); + + return morphed; } else { return image; } - if (image.data) - cv::erode(image, erodedImage, erodeKernel); - return erodedImage; } -cv::Mat ImagePreProcessor::dilate(cv::Mat& image) +cv::Mat ImagePreProcessor::dilate(cv::Mat image, int kernelSize) { - cv::Mat dilatedImage; - cv::Mat dilateKernel; - int sizeDilate = m_TrackingParameter->getOpeningDilationSize(); - if (sizeDilate > 0) { - dilateKernel = cv::getStructuringElement( + if (kernelSize > 0 && image.data) { + auto kernel = cv::getStructuringElement( cv::MORPH_RECT, - cv::Size(sizeDilate, sizeDilate)); + cv::Size(kernelSize, kernelSize)); + + cv::Mat morphed; + cv::dilate(image, morphed, kernel); + + return morphed; } else { return image; } - if (image.data) - cv::dilate(image, dilatedImage, dilateKernel); - return dilatedImage; } cv::Mat ImagePreProcessor::backgroundSubtraction(cv::Mat& image) @@ -103,20 +101,24 @@ cv::Mat ImagePreProcessor::backgroundSubtraction(cv::Mat& image) 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> erodedImage = std::make_shared<cv::Mat>(); - std::shared_ptr<cv::Mat> dilatedImage = std::make_shared<cv::Mat>(); + std::shared_ptr<cv::Mat> greyMat = std::make_shared<cv::Mat>(); + std::shared_ptr<cv::Mat> openedMask = std::make_shared<cv::Mat>(); + std::shared_ptr<cv::Mat> closedMask = std::make_shared<cv::Mat>(); cv::cvtColor(*p_image, *greyMat, cv::COLOR_BGR2GRAY); // 1. step: do the background subtraction *m_foregroundMask = backgroundSubtraction(*greyMat); - // 2. step: erode the image - *erodedImage = erode(*m_foregroundMask); + // 2. step: open the mask + *openedMask = dilate( + erode(*m_foregroundMask, m_TrackingParameter->getOpeningErosionSize()), + m_TrackingParameter->getOpeningDilationSize()); - // 3. step: dilate the image - *dilatedImage = dilate(*erodedImage); + // 3. step: close the image + *closedMask = erode( + dilate(*openedMask, m_TrackingParameter->getClosingDilationSize()), + m_TrackingParameter->getClosingErosionSize()); std::map<std::string, std::shared_ptr<cv::Mat>> all; all.insert(std::pair<std::string, std::shared_ptr<cv::Mat>>( @@ -128,12 +130,12 @@ std::map<std::string, std::shared_ptr<cv::Mat>> ImagePreProcessor::preProcess( 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)); + std::string("Opened Mask"), + openedMask)); + all.insert(std::pair<std::string, std::shared_ptr<cv::Mat>>( + std::string("Closed Mask"), + closedMask)); return all; } diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h index b190f3941da64fa48b76edacc5bb343c9fb64b4e..0acbcc4c4733142741cd514e826084541814ecbc 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.h @@ -29,17 +29,19 @@ public: * A mathematical morphology operation using in computer vision to erode an * image. Erode image with 3x3 4-connectivity. * @param: image, image to erode, + * @param: kernelSize, size of erosion kernel, * @return: an eroded image. */ - cv::Mat erode(cv::Mat& image); + cv::Mat erode(cv::Mat image, int kernelSize); /** * A mathematical morphology operation using in computer vision to dilate * an image. Dilate image with 6x6 8-connectivity. * @param: image, image to dilate, + * @param: kernelSize, size of dilation kernel, * @return: a dilated image. */ - cv::Mat dilate(cv::Mat& image); + cv::Mat dilate(cv::Mat image, int kernelSize); /** * A computer vision methode to calculate the image difference. diff --git a/Src/View/TrackerParameterView.cpp b/Src/View/TrackerParameterView.cpp index 6d910e82a8f09c91a37e931147199abfbcd68031..2cdb497189b54991b0e0709f5384dd19bb832ff9 100644 --- a/Src/View/TrackerParameterView.cpp +++ b/Src/View/TrackerParameterView.cpp @@ -43,6 +43,24 @@ TrackerParameterView::TrackerParameterView(QWidget* parent, this, &TrackerParameterView::parametersChanged); + connect(_ui->lineEdit_4_ClosingDilationSize, + qOverload<int>(&QSpinBox::valueChanged), + parameter, + &TrackerParameter::setClosingDilationSize); + connect(_ui->lineEdit_4_ClosingDilationSize, + qOverload<int>(&QSpinBox::valueChanged), + this, + &TrackerParameterView::parametersChanged); + + connect(_ui->lineEdit_3_ClosingErosionSize, + qOverload<int>(&QSpinBox::valueChanged), + parameter, + &TrackerParameter::setClosingErosionSize); + connect(_ui->lineEdit_3_ClosingErosionSize, + qOverload<int>(&QSpinBox::valueChanged), + this, + &TrackerParameterView::parametersChanged); + connect(_ui->lineEdit_8_MinBlob, qOverload<int>(&QSpinBox::valueChanged), parameter, @@ -159,9 +177,17 @@ void TrackerParameterView::getNotified() _binThres->setValue(parameter->getBinarizationThreshold()); } - _ui->lineEdit_3_OpeningErosionSize->setValue(parameter->getOpeningErosionSize()); + _ui->lineEdit_3_OpeningErosionSize->setValue( + parameter->getOpeningErosionSize()); + + _ui->lineEdit_4_OpeningDilationSize->setValue( + parameter->getOpeningDilationSize()); + + _ui->lineEdit_4_ClosingDilationSize->setValue( + parameter->getClosingDilationSize()); - _ui->lineEdit_4_OpeningDilationSize->setValue(parameter->getOpeningDilationSize()); + _ui->lineEdit_3_ClosingErosionSize->setValue( + parameter->getClosingErosionSize()); _ui->lineEdit_8_MinBlob->setValue(parameter->getMinBlobSize()); diff --git a/Src/View/TrackerParameterView.ui b/Src/View/TrackerParameterView.ui index f1d3dfd6092bf6cc0662037034af0896de12680e..d3aaeffdab2e9d9af67c7e352bb5fdebea8d2330 100644 --- a/Src/View/TrackerParameterView.ui +++ b/Src/View/TrackerParameterView.ui @@ -221,54 +221,122 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_6"> <item> - <layout class="QFormLayout" name="formLayout_6"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> + <widget class="QGroupBox" name="groupBox_5"> + <property name="title"> + <string>Opening</string> </property> - <property name="horizontalSpacing"> - <number>74</number> + <layout class="QFormLayout" name="formLayout_3"> + <item row="0" column="0"> + <layout class="QFormLayout" name="formLayout_6"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <property name="horizontalSpacing"> + <number>74</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Erosion kernel size:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="lineEdit_3_OpeningErosionSize"> + <property name="minimumSize"> + <size> + <width>132</width> + <height>60</height> + </size> + </property> + <property name="toolTip"> + <string>Set the opening erosion size</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Dilation kernel size:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="lineEdit_4_OpeningDilationSize"> + <property name="minimumSize"> + <size> + <width>132</width> + <height>60</height> + </size> + </property> + <property name="toolTip"> + <string>Set the opening dilation size</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_6"> + <property name="title"> + <string>Closing</string> </property> - <item row="0" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Opening erosion size:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QSpinBox" name="lineEdit_3_OpeningErosionSize"> - <property name="minimumSize"> - <size> - <width>132</width> - <height>60</height> - </size> - </property> - <property name="toolTip"> - <string>Set the opening erosion size</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>Opening dilation size:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QSpinBox" name="lineEdit_4_OpeningDilationSize"> - <property name="minimumSize"> - <size> - <width>132</width> - <height>60</height> - </size> - </property> - <property name="toolTip"> - <string>Set the opening dilation size</string> - </property> - </widget> - </item> - </layout> + <layout class="QFormLayout" name="formLayout_5"> + <item row="0" column="0"> + <layout class="QFormLayout" name="formLayout_7"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <property name="horizontalSpacing"> + <number>74</number> + </property> + <item row="2" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Erosion kernel size:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="lineEdit_3_ClosingErosionSize"> + <property name="minimumSize"> + <size> + <width>132</width> + <height>60</height> + </size> + </property> + <property name="toolTip"> + <string>Set the opening erosion size</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="lineEdit_4_ClosingDilationSize"> + <property name="minimumSize"> + <size> + <width>132</width> + <height>60</height> + </size> + </property> + <property name="toolTip"> + <string>Set the opening dilation size</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Dilation kernel size:</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> </item> </layout> </widget> @@ -399,12 +467,12 @@ </item> <item> <property name="text"> - <string>Eroded</string> + <string>Opened Mask</string> </property> </item> <item> <property name="text"> - <string>Dilated</string> + <string>Closed Mask</string> </property> </item> </widget>