Skip to content

Commit 6bce74f

Browse files
committed
Added SuBSENSE and LOBSTER background subtractors
1 parent a060503 commit 6bce74f

20 files changed

Lines changed: 2569 additions & 27 deletions

CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
3030
Detector/Detector.cpp
3131
Detector/BackgroundSubtract.cpp
3232
Detector/vibe_src/vibe.cpp
33+
Detector/Subsense/BackgroundSubtractorLBSP.cpp
34+
Detector/Subsense/BackgroundSubtractorLOBSTER.cpp
35+
Detector/Subsense/BackgroundSubtractorSuBSENSE.cpp
36+
Detector/Subsense/LBSP.cpp
37+
3338
Tracker/Ctracker.cpp
3439
Tracker/HungarianAlg/HungarianAlg.cpp
3540
Tracker/LocalTracker.cpp
@@ -39,6 +44,13 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
3944
Detector/Detector.h
4045
Detector/BackgroundSubtract.h
4146
Detector/vibe_src/vibe.hpp
47+
Detector/Subsense/BackgroundSubtractorLBSP.h
48+
Detector/Subsense/BackgroundSubtractorLOBSTER.h
49+
Detector/Subsense/BackgroundSubtractorSuBSENSE.h
50+
Detector/Subsense/DistanceUtils.h
51+
Detector/Subsense/LBSP.h
52+
Detector/Subsense/RandUtils.h
53+
4254
pedestrians/c4-pedestrian-detector.h
4355
Tracker/Ctracker.h
4456
Tracker/track.h
@@ -169,7 +181,8 @@ endif(USE_OCV_UKF)
169181
# ----------------------------------------------------------------------------
170182
INCLUDE_DIRECTORIES(
171183
${PROJECT_SOURCE_DIR}/Detector
172-
${PROJECT_SOURCE_DIR}/vibe_src
184+
${PROJECT_SOURCE_DIR}/Detector/vibe_src
185+
${PROJECT_SOURCE_DIR}/Detector/Subsense
173186
${PROJECT_SOURCE_DIR}/Tracker
174187
${PROJECT_SOURCE_DIR}/Tracker/HungarianAlg
175188
${PROJECT_SOURCE_DIR}/Tracker/graph

Detector/BackgroundSubtract.cpp

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,64 @@ BackgroundSubtract::BackgroundSubtract(
1414
)
1515
:
1616
m_channels(channels),
17-
m_algType(algType)
17+
m_algType(algType)
1818
{
19-
switch (m_algType)
20-
{
21-
case ALG_VIBE:
22-
m_modelVibe = std::make_unique<vibe::VIBE>(m_channels, samples, pixel_neighbor, distance_threshold, matching_threshold, update_factor);
23-
break;
19+
for (bool failed = true; failed;)
20+
{
21+
failed = false;
22+
23+
switch (m_algType)
24+
{
25+
case ALG_VIBE:
26+
m_modelVibe = std::make_unique<vibe::VIBE>(m_channels, samples, pixel_neighbor, distance_threshold, matching_threshold, update_factor);
27+
break;
2428

2529
#if USE_OCV_BGFG
26-
case ALG_MOG:
27-
m_modelOCV = cv::bgsegm::createBackgroundSubtractorMOG(100, 3, 0.7, 0);
28-
break;
30+
case ALG_MOG:
31+
m_modelOCV = cv::bgsegm::createBackgroundSubtractorMOG(100, 3, 0.7, 0);
32+
break;
2933

30-
case ALG_GMG:
31-
m_modelOCV = cv::bgsegm::createBackgroundSubtractorGMG(50, 0.7);
32-
break;
34+
case ALG_GMG:
35+
m_modelOCV = cv::bgsegm::createBackgroundSubtractorGMG(50, 0.7);
36+
break;
3337

34-
case ALG_CNT:
38+
case ALG_CNT:
3539
#if (((CV_VERSION_MAJOR == 3) && (CV_VERSION_MINOR >= 2)) || (CV_VERSION_MAJOR > 3))
36-
m_modelOCV = cv::bgsegm::createBackgroundSubtractorCNT(15, true, 15 * 60, true);
37-
break;
40+
m_modelOCV = cv::bgsegm::createBackgroundSubtractorCNT(15, true, 15 * 60, true);
41+
break;
3842
#else
39-
std::cerr << "OpenCV CNT algorithm is not implemented! Used Vibe by default." << std::endl;
43+
std::cerr << "OpenCV CNT algorithm is not implemented! Used Vibe by default." << std::endl;
44+
failed = true;
45+
break;
4046
#endif
4147

4248
#else
43-
case ALG_MOG:
44-
case ALG_GMG:
45-
case ALG_CNT:
46-
std::cerr << "OpenCV bgfg algorithms are not implemented! Used Vibe by default." << std::endl;
49+
case ALG_MOG:
50+
case ALG_GMG:
51+
case ALG_CNT:
52+
std::cerr << "OpenCV bgfg algorithms are not implemented! Used Vibe by default." << std::endl;
53+
failed = true;
54+
break;
4755
#endif
4856

49-
default:
50-
m_modelVibe = std::make_unique<vibe::VIBE>(m_channels, samples, pixel_neighbor, distance_threshold, matching_threshold, update_factor);
51-
break;
52-
}
57+
case ALG_SuBSENSE:
58+
m_modelSuBSENSE = std::make_unique<BackgroundSubtractorSuBSENSE>(); // default params
59+
break;
60+
61+
case ALG_LOBSTER:
62+
m_modelSuBSENSE = std::make_unique<BackgroundSubtractorLOBSTER>(); // default params
63+
break;
64+
65+
default:
66+
m_modelVibe = std::make_unique<vibe::VIBE>(m_channels, samples, pixel_neighbor, distance_threshold, matching_threshold, update_factor);
67+
break;
68+
}
69+
if (failed)
70+
{
71+
m_algType = ALG_VIBE;
72+
failed = false;
73+
}
74+
}
5375
}
5476

5577
//----------------------------------------------------------------------
@@ -99,8 +121,22 @@ void BackgroundSubtract::subtract(const cv::Mat& image, cv::Mat& foreground)
99121
break;
100122
#else
101123
std::cerr << "OpenCV bgfg algorithms are not implemented!" << std::endl;
124+
break;
102125
#endif
103126

127+
case ALG_SuBSENSE:
128+
case ALG_LOBSTER:
129+
if (foreground.size() != image.size())
130+
{
131+
m_modelSuBSENSE->initialize(GetImg(), cv::Mat());
132+
foreground.create(image.size(), CV_8UC1);
133+
}
134+
else
135+
{
136+
m_modelSuBSENSE->apply(GetImg(), foreground);
137+
}
138+
break;
139+
104140
default:
105141
m_modelVibe->update(GetImg());
106142
foreground = m_modelVibe->getMask();

Detector/BackgroundSubtract.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include "defines.h"
55
#include "vibe_src/vibe.hpp"
6+
#include "Subsense/BackgroundSubtractorSuBSENSE.h"
7+
#include "Subsense/BackgroundSubtractorLOBSTER.h"
68

79
#if USE_OCV_BGFG
810
#include <opencv2/bgsegm.hpp>
@@ -16,7 +18,9 @@ class BackgroundSubtract
1618
ALG_VIBE,
1719
ALG_MOG,
1820
ALG_GMG,
19-
ALG_CNT
21+
ALG_CNT,
22+
ALG_SuBSENSE,
23+
ALG_LOBSTER
2024
};
2125

2226
BackgroundSubtract(BGFG_ALGS algType, int channels = 1, int samples = 20, int pixel_neighbor = 1, int distance_threshold = 20, int matching_threshold = 3, int update_factor = 16);
@@ -32,6 +36,7 @@ class BackgroundSubtract
3236
#if USE_OCV_BGFG
3337
cv::Ptr<cv::BackgroundSubtractor> m_modelOCV;
3438
#endif
39+
std::unique_ptr<BackgroundSubtractorLBSP> m_modelSuBSENSE;
3540
};
3641

3742
#endif
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "BackgroundSubtractorLBSP.h"
2+
#include "DistanceUtils.h"
3+
#include "RandUtils.h"
4+
#include <iostream>
5+
#include <opencv2/imgproc/imgproc.hpp>
6+
#include <opencv2/highgui/highgui.hpp>
7+
#include <iomanip>
8+
#include <exception>
9+
10+
// local define used to determine the default median blur kernel size
11+
#define DEFAULT_MEDIAN_BLUR_KERNEL_SIZE (9)
12+
13+
BackgroundSubtractorLBSP::BackgroundSubtractorLBSP(float fRelLBSPThreshold, size_t nLBSPThresholdOffset)
14+
: m_nImgChannels(0)
15+
,m_nImgType(0)
16+
,m_nLBSPThresholdOffset(nLBSPThresholdOffset)
17+
,m_fRelLBSPThreshold(fRelLBSPThreshold)
18+
,m_nTotPxCount(0)
19+
,m_nTotRelevantPxCount(0)
20+
,m_nFrameIndex(SIZE_MAX)
21+
,m_nFramesSinceLastReset(0)
22+
,m_nModelResetCooldown(0)
23+
,m_aPxIdxLUT(nullptr)
24+
,m_aPxInfoLUT(nullptr)
25+
,m_nDefaultMedianBlurKernelSize(DEFAULT_MEDIAN_BLUR_KERNEL_SIZE)
26+
,m_bInitialized(false)
27+
,m_bAutoModelResetEnabled(true)
28+
,m_bUsingMovingCamera(false)
29+
,nDebugCoordX(0),nDebugCoordY(0) {
30+
CV_Assert(m_fRelLBSPThreshold>=0);
31+
}
32+
33+
BackgroundSubtractorLBSP::~BackgroundSubtractorLBSP() {}
34+
35+
void BackgroundSubtractorLBSP::initialize(const cv::Mat& oInitImg) {
36+
this->initialize(oInitImg,cv::Mat());
37+
}
38+
39+
cv::Algorithm* BackgroundSubtractorLBSP::info() const {
40+
return nullptr;
41+
}
42+
43+
cv::Mat BackgroundSubtractorLBSP::getROICopy() const {
44+
return m_oROI.clone();
45+
}
46+
47+
void BackgroundSubtractorLBSP::setROI(cv::Mat& oROI) {
48+
LBSP::validateROI(oROI);
49+
CV_Assert(cv::countNonZero(oROI)>0);
50+
if(m_bInitialized) {
51+
cv::Mat oLatestBackgroundImage;
52+
getBackgroundImage(oLatestBackgroundImage);
53+
initialize(oLatestBackgroundImage,oROI);
54+
}
55+
else
56+
m_oROI = oROI.clone();
57+
}
58+
59+
void BackgroundSubtractorLBSP::setAutomaticModelReset(bool bVal) {
60+
m_bAutoModelResetEnabled = bVal;
61+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#pragma once
2+
3+
#include <opencv2/features2d/features2d.hpp>
4+
#include <opencv2/video/background_segm.hpp>
5+
#include "LBSP.h"
6+
7+
/*!
8+
Local Binary Similarity Pattern (LBSP)-based change detection algorithm (abstract version/base class).
9+
10+
For more details on the different parameters, see P.-L. St-Charles and G.-A. Bilodeau, "Improving Background
11+
Subtraction using Local Binary Similarity Patterns", in WACV 2014, or G.-A. Bilodeau et al, "Change Detection
12+
in Feature Space Using Local Binary Similarity Patterns", in CRV 2013.
13+
14+
This algorithm is currently NOT thread-safe.
15+
*/
16+
class BackgroundSubtractorLBSP : public cv::BackgroundSubtractor {
17+
public:
18+
//! full constructor
19+
BackgroundSubtractorLBSP(float fRelLBSPThreshold, size_t nLBSPThresholdOffset=0);
20+
//! default destructor
21+
virtual ~BackgroundSubtractorLBSP();
22+
//! (re)initiaization method; needs to be called before starting background subtraction
23+
virtual void initialize(const cv::Mat& oInitImg);
24+
//! (re)initiaization method; needs to be called before starting background subtraction
25+
virtual void initialize(const cv::Mat& oInitImg, const cv::Mat& oROI)=0;
26+
//! primary model update function; the learning param is used to override the internal learning speed (ignored when <= 0)
27+
virtual void operator()(cv::InputArray image, cv::OutputArray fgmask, double learningRate=0)=0;
28+
//! unused, always returns nullptr
29+
virtual cv::Algorithm* info() const;
30+
//! returns a copy of the ROI used for descriptor extraction
31+
virtual cv::Mat getROICopy() const;
32+
//! sets the ROI to be used for descriptor extraction (note: this function will reinit the model and return the usable ROI)
33+
virtual void setROI(cv::Mat& oROI);
34+
//! turns automatic model reset on or off
35+
void setAutomaticModelReset(bool);
36+
37+
protected:
38+
struct PxInfoBase {
39+
int nImgCoord_Y;
40+
int nImgCoord_X;
41+
size_t nModelIdx;
42+
};
43+
//! background model ROI used for LBSP descriptor extraction (specific to the input image size)
44+
cv::Mat m_oROI;
45+
//! input image size
46+
cv::Size m_oImgSize;
47+
//! input image channel size
48+
size_t m_nImgChannels;
49+
//! input image type
50+
int m_nImgType;
51+
//! LBSP internal threshold offset value, used to reduce texture noise in dark regions
52+
const size_t m_nLBSPThresholdOffset;
53+
//! LBSP relative internal threshold (kept here since we don't keep an LBSP object)
54+
const float m_fRelLBSPThreshold;
55+
//! total number of pixels (depends on the input frame size) & total number of relevant pixels
56+
size_t m_nTotPxCount, m_nTotRelevantPxCount;
57+
//! current frame index, frame count since last model reset & model reset cooldown counters
58+
size_t m_nFrameIndex, m_nFramesSinceLastReset, m_nModelResetCooldown;
59+
//! pre-allocated internal LBSP threshold values LUT for all possible 8-bit intensities
60+
size_t m_anLBSPThreshold_8bitLUT[UCHAR_MAX+1];
61+
//! internal pixel index LUT for all relevant analysis regions (based on the provided ROI)
62+
size_t* m_aPxIdxLUT;
63+
//! internal pixel info LUT for all possible pixel indexes
64+
PxInfoBase* m_aPxInfoLUT;
65+
//! default kernel size for median blur post-proc filtering
66+
const int m_nDefaultMedianBlurKernelSize;
67+
//! specifies whether the algorithm is fully initialized or not
68+
bool m_bInitialized;
69+
//! specifies whether automatic model resets are enabled or not
70+
bool m_bAutoModelResetEnabled;
71+
//! specifies whether the camera is considered moving or not
72+
bool m_bUsingMovingCamera;
73+
//! copy of latest pixel intensities (used when refreshing model)
74+
cv::Mat m_oLastColorFrame;
75+
//! copy of latest descriptors (used when refreshing model)
76+
cv::Mat m_oLastDescFrame;
77+
//! the foreground mask generated by the method at [t-1]
78+
cv::Mat m_oLastFGMask;
79+
80+
public:
81+
// ######## DEBUG PURPOSES ONLY ##########
82+
int nDebugCoordX, nDebugCoordY;
83+
std::string sDebugName;
84+
};
85+

0 commit comments

Comments
 (0)