-
Notifications
You must be signed in to change notification settings - Fork 4
/
bsgmm.hpp
127 lines (115 loc) · 3.57 KB
/
bsgmm.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef BSGMM_HPP
#define BSGMM_HPP
#include "header.hpp"
/*
* Usage:
* #include "bsgmm.hpp"
* cv::Mat inputImg, outputImg;
* BackgroundSubtractorGMM bsgmm( inputImg.rows, inputImg.cols );
* And keep update frames using loop
* bsgmm.updateFrame( inputImg.ptr(), outputImg.ptr() );
* When works are done, release the resources
* bsgmm.freeMem();
*/
enum Color
{
BLACK = 0,
WHITE = 255,
GRAY = 127
};
// Gaussian Mixture Models
typedef struct
{
// stores RGB values from frames
double R;
double G;
double B;
// modeling the distribution off RGB values
double variance;
// use to balance different GMM models
double weight;
} gaussian;
/*
* Store GMM models for each model
* 4 GMM for each pixel is usually enough.
* We declare the array size plus one for implementation
* because sometimes number of GMM will bigger than 4 and will be resized to 4
*/
typedef struct
{
// Store GMM models
gaussian arr[4];
// Number of GMM of current pixel
int GMMCount;
} PIXELGMM;
class BackgroundSubtractorGMM
{
public:
BackgroundSubtractorGMM( int frameHeight, int frameWidth );
void updateFrame( uchar *inputPtr, uchar *outputPtr );
~BackgroundSubtractorGMM();
double alpha;
/*
* If the object be in static for approximately
* log(1-cf) / log(1-alpha) frames,it will be considered
* to be in the background
* alpha = 0.001 the result is 105 frames
* alpha = 0.002 the result is 52 frames
* alpha = 0.003 the result is 35 frames
* alpha = 0.004 the result is 26 frames
* alpha = 0.003 the result is 21 frames
* which value of alpha depends on the fps of the video
*/
double alpha_bar;
double cT;
// Number of samples needed to accept that a component actually exists
double defaultVariance;
// default variance for GMM models
double minVariance;
/*
* min variance for GMM models
* From paper : in [5, 11] the pixel value distribution over time is modelled as an autoregressive process
*/
double maxVariance;
// max variance for GMM models
double cf;
/*
* cf is a measure of the maximum portion of the data
* that can belong to foreground objects without influencing
* the background model
*/
double cfbar;
// The threshold that effect pixel to be part of background
double prune;
// A value to decide whether a GMM model should be removed
double BGSigma;
/*
* A threshold that effect pixel to be part of background
* In the paper : If Mahalanobis distance is smaller than three standard deviations
* it can be part of the background, but here I pick 4
*/
double closeSigma;
/*
* A threshold that decide to add a new GMM model to pixel
* In the paper : If Mahalanobis distance is bigger than three standard deviations
* add new GMM model to that pixel
*/
int defaultGMMCount;
// 4 GMMCount is enough to this paper's algorithm
bool shadowDetection;
double tau;
bool removeForeground;
bool shadowBeBackground;
/*
* Shadow threshold.
* The shadow is detected if the pixel is a darker version of the background.
* Tau is a threshold defining how much darker the shadow can be.
* Tau= 0.5 means that if a pixel is more than twice darker then it is not shadow.
*/
private:
bool isBackGround( double red, double green, double blue, PIXELGMM *currentPixel );
bool isShadow( double red, double green, double blue, PIXELGMM *currentPixel );
PIXELGMM *pixelGMMBuffer;
int frameHeight, frameWidth;
};
#endif