Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
a2adab72
Commit
a2adab72
authored
May 06, 2013
by
Vladislav Vinogradov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactored MOG algorithm
converted it to abstract interface
parent
88e67545
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
157 additions
and
126 deletions
+157
-126
gpubgsegm.hpp
modules/gpubgsegm/include/opencv2/gpubgsegm.hpp
+26
-47
perf_bgsegm.cpp
modules/gpubgsegm/perf/perf_bgsegm.cpp
+4
-3
mog.cpp
modules/gpubgsegm/src/mog.cpp
+118
-67
test_bgsegm.cpp
modules/gpubgsegm/test/test_bgsegm.cpp
+2
-2
bgfg_segm.cpp
samples/gpu/bgfg_segm.cpp
+4
-4
tests.cpp
samples/gpu/performance/tests.cpp
+3
-3
No files found.
modules/gpubgsegm/include/opencv2/gpubgsegm.hpp
View file @
a2adab72
...
...
@@ -47,13 +47,37 @@
# error gpubgsegm.hpp header must be compiled as C++
#endif
#include <memory>
#include "opencv2/core/gpu.hpp"
#include "opencv2/video/background_segm.hpp"
#include <memory>
#include "opencv2/gpufilters.hpp"
namespace
cv
{
namespace
gpu
{
////////////////////////////////////////////////////
// MOG
class
CV_EXPORTS
BackgroundSubtractorMOG
:
public
cv
::
BackgroundSubtractorMOG
{
public
:
using
cv
::
BackgroundSubtractorMOG
::
apply
;
using
cv
::
BackgroundSubtractorMOG
::
getBackgroundImage
;
virtual
void
apply
(
InputArray
image
,
OutputArray
fgmask
,
double
learningRate
,
Stream
&
stream
)
=
0
;
virtual
void
getBackgroundImage
(
OutputArray
backgroundImage
,
Stream
&
stream
)
const
=
0
;
};
CV_EXPORTS
Ptr
<
gpu
::
BackgroundSubtractorMOG
>
createBackgroundSubtractorMOG
(
int
history
=
200
,
int
nmixtures
=
5
,
double
backgroundRatio
=
0.7
,
double
noiseSigma
=
0
);
// Foreground Object Detection from Videos Containing Complex Background.
// Liyuan Li, Weimin Huang, Irene Y.H. Gu, and Qi Tian.
// ACM MM2003 9p
...
...
@@ -116,51 +140,6 @@ private:
std
::
auto_ptr
<
Impl
>
impl_
;
};
/*!
Gaussian Mixture-based Backbround/Foreground Segmentation Algorithm
The class implements the following algorithm:
"An improved adaptive background mixture model for real-time tracking with shadow detection"
P. KadewTraKuPong and R. Bowden,
Proc. 2nd European Workshp on Advanced Video-Based Surveillance Systems, 2001."
http://personal.ee.surrey.ac.uk/Personal/R.Bowden/publications/avbs01/avbs01.pdf
*/
class
CV_EXPORTS
MOG_GPU
{
public
:
//! the default constructor
MOG_GPU
(
int
nmixtures
=
-
1
);
//! re-initiaization method
void
initialize
(
Size
frameSize
,
int
frameType
);
//! the update operator
void
operator
()(
const
GpuMat
&
frame
,
GpuMat
&
fgmask
,
float
learningRate
=
0.0
f
,
Stream
&
stream
=
Stream
::
Null
());
//! computes a background image which are the mean of all background gaussians
void
getBackgroundImage
(
GpuMat
&
backgroundImage
,
Stream
&
stream
=
Stream
::
Null
())
const
;
//! releases all inner buffers
void
release
();
int
history
;
float
varThreshold
;
float
backgroundRatio
;
float
noiseSigma
;
private
:
int
nmixtures_
;
Size
frameSize_
;
int
frameType_
;
int
nframes_
;
GpuMat
weight_
;
GpuMat
sortKey_
;
GpuMat
mean_
;
GpuMat
var_
;
};
/*!
The class implements the following algorithm:
"Improved adaptive Gausian mixture model for background subtraction"
...
...
modules/gpubgsegm/perf/perf_bgsegm.cpp
View file @
a2adab72
...
...
@@ -176,11 +176,12 @@ PERF_TEST_P(Video_Cn_LearningRate, MOG,
if
(
PERF_RUN_GPU
())
{
cv
::
Ptr
<
cv
::
BackgroundSubtractor
>
d_mog
=
cv
::
gpu
::
createBackgroundSubtractorMOG
();
cv
::
gpu
::
GpuMat
d_frame
(
frame
);
cv
::
gpu
::
MOG_GPU
d_mog
;
cv
::
gpu
::
GpuMat
foreground
;
d_mog
(
d_frame
,
foreground
,
learningRate
);
d_mog
->
apply
(
d_frame
,
foreground
,
learningRate
);
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
...
...
@@ -200,7 +201,7 @@ PERF_TEST_P(Video_Cn_LearningRate, MOG,
d_frame
.
upload
(
frame
);
startTimer
();
next
();
d_mog
(
d_frame
,
foreground
,
learningRate
);
d_mog
->
apply
(
d_frame
,
foreground
,
learningRate
);
stopTimer
();
}
...
...
modules/gpubgsegm/src/mog.cpp
View file @
a2adab72
...
...
@@ -42,13 +42,12 @@
#include "precomp.hpp"
using
namespace
cv
;
using
namespace
cv
::
gpu
;
#if !defined HAVE_CUDA || defined(CUDA_DISABLER)
cv
::
gpu
::
MOG_GPU
::
MOG_GPU
(
int
)
{
throw_no_cuda
();
}
void
cv
::
gpu
::
MOG_GPU
::
initialize
(
cv
::
Size
,
int
)
{
throw_no_cuda
();
}
void
cv
::
gpu
::
MOG_GPU
::
operator
()(
const
cv
::
gpu
::
GpuMat
&
,
cv
::
gpu
::
GpuMat
&
,
float
,
Stream
&
)
{
throw_no_cuda
();
}
void
cv
::
gpu
::
MOG_GPU
::
getBackgroundImage
(
GpuMat
&
,
Stream
&
)
const
{
throw_no_cuda
();
}
void
cv
::
gpu
::
MOG_GPU
::
release
()
{}
Ptr
<
gpu
::
BackgroundSubtractorMOG
>
cv
::
gpu
::
createBackgroundSubtractorMOG
(
int
,
int
,
double
,
double
)
{
throw_no_cuda
();
return
Ptr
<
gpu
::
BackgroundSubtractorMOG
>
();
}
#else
...
...
@@ -63,7 +62,7 @@ namespace cv { namespace gpu { namespace cudev
}
}}}
namespace
mog
namespace
{
const
int
defaultNMixtures
=
5
;
const
int
defaultHistory
=
200
;
...
...
@@ -71,88 +70,140 @@ namespace mog
const
float
defaultVarThreshold
=
2.5
f
*
2.5
f
;
const
float
defaultNoiseSigma
=
30.0
f
*
0.5
f
;
const
float
defaultInitialWeight
=
0.05
f
;
}
cv
::
gpu
::
MOG_GPU
::
MOG_GPU
(
int
nmixtures
)
:
frameSize_
(
0
,
0
),
frameType_
(
0
),
nframes_
(
0
)
{
nmixtures_
=
std
::
min
(
nmixtures
>
0
?
nmixtures
:
mog
::
defaultNMixtures
,
8
);
history
=
mog
::
defaultHistory
;
varThreshold
=
mog
::
defaultVarThreshold
;
backgroundRatio
=
mog
::
defaultBackgroundRatio
;
noiseSigma
=
mog
::
defaultNoiseSigma
;
}
class
MOGImpl
:
public
gpu
::
BackgroundSubtractorMOG
{
public
:
MOGImpl
(
int
history
,
int
nmixtures
,
double
backgroundRatio
,
double
noiseSigma
);
void
cv
::
gpu
::
MOG_GPU
::
initialize
(
cv
::
Size
frameSize
,
int
frameType
)
{
CV_Assert
(
frameType
==
CV_8UC1
||
frameType
==
CV_8UC3
||
frameType
==
CV_8UC4
);
void
apply
(
InputArray
image
,
OutputArray
fgmask
,
double
learningRate
=-
1
);
void
apply
(
InputArray
image
,
OutputArray
fgmask
,
double
learningRate
,
Stream
&
stream
);
frameSize_
=
frameSize
;
frameType_
=
frameType
;
void
getBackgroundImage
(
OutputArray
backgroundImage
)
const
;
void
getBackgroundImage
(
OutputArray
backgroundImage
,
Stream
&
stream
)
const
;
int
ch
=
CV_MAT_CN
(
frameType
);
int
work_ch
=
ch
;
int
getHistory
()
const
{
return
history_
;
}
void
setHistory
(
int
nframes
)
{
history_
=
nframes
;
}
// for each gaussian mixture of each pixel bg model we store
// the mixture sort key (w/sum_of_variances), the mixture weight (w),
// the mean (nchannels values) and
// the diagonal covariance matrix (another nchannels values)
int
getNMixtures
()
const
{
return
nmixtures_
;
}
void
setNMixtures
(
int
nmix
)
{
nmixtures_
=
nmix
;
}
weight_
.
create
(
frameSize
.
height
*
nmixtures_
,
frameSize_
.
width
,
CV_32FC1
);
sortKey_
.
create
(
frameSize
.
height
*
nmixtures_
,
frameSize_
.
width
,
CV_32FC1
);
mean_
.
create
(
frameSize
.
height
*
nmixtures_
,
frameSize_
.
width
,
CV_32FC
(
work_ch
));
var_
.
create
(
frameSize
.
height
*
nmixtures_
,
frameSize_
.
width
,
CV_32FC
(
work_ch
));
double
getBackgroundRatio
()
const
{
return
backgroundRatio_
;
}
void
setBackgroundRatio
(
double
backgroundRatio
)
{
backgroundRatio_
=
(
float
)
backgroundRatio
;
}
weight_
.
setTo
(
cv
::
Scalar
::
all
(
0
));
sortKey_
.
setTo
(
cv
::
Scalar
::
all
(
0
));
mean_
.
setTo
(
cv
::
Scalar
::
all
(
0
));
var_
.
setTo
(
cv
::
Scalar
::
all
(
0
));
double
getNoiseSigma
()
const
{
return
noiseSigma_
;
}
void
setNoiseSigma
(
double
noiseSigma
)
{
noiseSigma_
=
(
float
)
noiseSigma
;
}
nframes_
=
0
;
}
private
:
//! re-initiaization method
void
initialize
(
Size
frameSize
,
int
frameType
);
void
cv
::
gpu
::
MOG_GPU
::
operator
()(
const
cv
::
gpu
::
GpuMat
&
frame
,
cv
::
gpu
::
GpuMat
&
fgmask
,
float
learningRate
,
Stream
&
stream
)
{
using
namespace
cv
::
gpu
::
cudev
::
mog
;
int
history_
;
int
nmixtures_
;
float
backgroundRatio_
;
float
noiseSigma_
;
CV_Assert
(
frame
.
depth
()
==
CV_8U
)
;
float
varThreshold_
;
int
ch
=
frame
.
channels
();
int
work_ch
=
ch
;
Size
frameSize_
;
int
frameType_
;
int
nframes_
;
if
(
nframes_
==
0
||
learningRate
>=
1.0
||
frame
.
size
()
!=
frameSize_
||
work_ch
!=
mean_
.
channels
())
initialize
(
frame
.
size
(),
frame
.
type
());
GpuMat
weight_
;
GpuMat
sortKey_
;
GpuMat
mean_
;
GpuMat
var_
;
};
fgmask
.
create
(
frameSize_
,
CV_8UC1
);
MOGImpl
::
MOGImpl
(
int
history
,
int
nmixtures
,
double
backgroundRatio
,
double
noiseSigma
)
:
frameSize_
(
0
,
0
),
frameType_
(
0
),
nframes_
(
0
)
{
history_
=
history
>
0
?
history
:
defaultHistory
;
nmixtures_
=
std
::
min
(
nmixtures
>
0
?
nmixtures
:
defaultNMixtures
,
8
);
backgroundRatio_
=
backgroundRatio
>
0
?
(
float
)
backgroundRatio
:
defaultBackgroundRatio
;
noiseSigma_
=
noiseSigma
>
0
?
(
float
)
noiseSigma
:
defaultNoiseSigma
;
++
nframes_
;
learningRate
=
learningRate
>=
0.0
f
&&
nframes_
>
1
?
learningRate
:
1.0
f
/
std
::
min
(
nframes_
,
history
);
CV_Assert
(
learningRate
>=
0.0
f
);
varThreshold_
=
defaultVarThreshold
;
}
mog_gpu
(
frame
,
ch
,
fgmask
,
weight_
,
sortKey_
,
mean_
,
var_
,
nmixtures_
,
varThreshold
,
learningRate
,
backgroundRatio
,
noiseSigma
,
StreamAccessor
::
getStream
(
stream
));
}
void
MOGImpl
::
apply
(
InputArray
image
,
OutputArray
fgmask
,
double
learningRate
)
{
apply
(
image
,
fgmask
,
learningRate
,
Stream
::
Null
(
));
}
void
cv
::
gpu
::
MOG_GPU
::
getBackgroundImage
(
GpuMat
&
backgroundImage
,
Stream
&
stream
)
const
{
using
namespace
cv
::
gpu
::
cudev
::
mog
;
void
MOGImpl
::
apply
(
InputArray
_frame
,
OutputArray
_fgmask
,
double
learningRate
,
Stream
&
stream
)
{
using
namespace
cv
::
gpu
::
cudev
::
mog
;
GpuMat
frame
=
_frame
.
getGpuMat
();
CV_Assert
(
frame
.
depth
()
==
CV_8U
);
int
ch
=
frame
.
channels
();
int
work_ch
=
ch
;
if
(
nframes_
==
0
||
learningRate
>=
1.0
||
frame
.
size
()
!=
frameSize_
||
work_ch
!=
mean_
.
channels
())
initialize
(
frame
.
size
(),
frame
.
type
());
backgroundImage
.
create
(
frameSize_
,
frameType_
);
_fgmask
.
create
(
frameSize_
,
CV_8UC1
);
GpuMat
fgmask
=
_fgmask
.
getGpuMat
();
getBackgroundImage_gpu
(
backgroundImage
.
channels
(),
weight_
,
mean_
,
backgroundImage
,
nmixtures_
,
backgroundRatio
,
StreamAccessor
::
getStream
(
stream
));
++
nframes_
;
learningRate
=
learningRate
>=
0
&&
nframes_
>
1
?
learningRate
:
1.0
/
std
::
min
(
nframes_
,
history_
);
CV_Assert
(
learningRate
>=
0
);
mog_gpu
(
frame
,
ch
,
fgmask
,
weight_
,
sortKey_
,
mean_
,
var_
,
nmixtures_
,
varThreshold_
,
(
float
)
learningRate
,
backgroundRatio_
,
noiseSigma_
,
StreamAccessor
::
getStream
(
stream
));
}
void
MOGImpl
::
getBackgroundImage
(
OutputArray
backgroundImage
)
const
{
getBackgroundImage
(
backgroundImage
,
Stream
::
Null
());
}
void
MOGImpl
::
getBackgroundImage
(
OutputArray
_backgroundImage
,
Stream
&
stream
)
const
{
using
namespace
cv
::
gpu
::
cudev
::
mog
;
_backgroundImage
.
create
(
frameSize_
,
frameType_
);
GpuMat
backgroundImage
=
_backgroundImage
.
getGpuMat
();
getBackgroundImage_gpu
(
backgroundImage
.
channels
(),
weight_
,
mean_
,
backgroundImage
,
nmixtures_
,
backgroundRatio_
,
StreamAccessor
::
getStream
(
stream
));
}
void
MOGImpl
::
initialize
(
Size
frameSize
,
int
frameType
)
{
CV_Assert
(
frameType
==
CV_8UC1
||
frameType
==
CV_8UC3
||
frameType
==
CV_8UC4
);
frameSize_
=
frameSize
;
frameType_
=
frameType
;
int
ch
=
CV_MAT_CN
(
frameType
);
int
work_ch
=
ch
;
// for each gaussian mixture of each pixel bg model we store
// the mixture sort key (w/sum_of_variances), the mixture weight (w),
// the mean (nchannels values) and
// the diagonal covariance matrix (another nchannels values)
weight_
.
create
(
frameSize
.
height
*
nmixtures_
,
frameSize_
.
width
,
CV_32FC1
);
sortKey_
.
create
(
frameSize
.
height
*
nmixtures_
,
frameSize_
.
width
,
CV_32FC1
);
mean_
.
create
(
frameSize
.
height
*
nmixtures_
,
frameSize_
.
width
,
CV_32FC
(
work_ch
));
var_
.
create
(
frameSize
.
height
*
nmixtures_
,
frameSize_
.
width
,
CV_32FC
(
work_ch
));
weight_
.
setTo
(
cv
::
Scalar
::
all
(
0
));
sortKey_
.
setTo
(
cv
::
Scalar
::
all
(
0
));
mean_
.
setTo
(
cv
::
Scalar
::
all
(
0
));
var_
.
setTo
(
cv
::
Scalar
::
all
(
0
));
nframes_
=
0
;
}
}
void
cv
::
gpu
::
MOG_GPU
::
release
(
)
Ptr
<
gpu
::
BackgroundSubtractorMOG
>
cv
::
gpu
::
createBackgroundSubtractorMOG
(
int
history
,
int
nmixtures
,
double
backgroundRatio
,
double
noiseSigma
)
{
frameSize_
=
Size
(
0
,
0
);
frameType_
=
0
;
nframes_
=
0
;
weight_
.
release
();
sortKey_
.
release
();
mean_
.
release
();
var_
.
release
();
return
new
MOGImpl
(
history
,
nmixtures
,
backgroundRatio
,
noiseSigma
);
}
#endif
modules/gpubgsegm/test/test_bgsegm.cpp
View file @
a2adab72
...
...
@@ -193,7 +193,7 @@ GPU_TEST_P(MOG, Update)
cap
>>
frame
;
ASSERT_FALSE
(
frame
.
empty
());
cv
::
gpu
::
MOG_GPU
mog
;
cv
::
Ptr
<
cv
::
BackgroundSubtractorMOG
>
mog
=
cv
::
gpu
::
createBackgroundSubtractorMOG
()
;
cv
::
gpu
::
GpuMat
foreground
=
createMat
(
frame
.
size
(),
CV_8UC1
,
useRoi
);
cv
::
Ptr
<
cv
::
BackgroundSubtractorMOG
>
mog_gold
=
cv
::
createBackgroundSubtractorMOG
();
...
...
@@ -211,7 +211,7 @@ GPU_TEST_P(MOG, Update)
cv
::
swap
(
temp
,
frame
);
}
mog
(
loadMat
(
frame
,
useRoi
),
foreground
,
(
float
)
learningRate
);
mog
->
apply
(
loadMat
(
frame
,
useRoi
),
foreground
,
learningRate
);
mog_gold
->
apply
(
frame
,
foreground_gold
,
learningRate
);
...
...
samples/gpu/bgfg_segm.cpp
View file @
a2adab72
...
...
@@ -76,7 +76,7 @@ int main(int argc, const char** argv)
GpuMat
d_frame
(
frame
);
FGDStatModel
fgd_stat
;
MOG_GPU
mog
;
cv
::
Ptr
<
cv
::
BackgroundSubtractorMOG
>
mog
=
cv
::
gpu
::
createBackgroundSubtractorMOG
()
;
MOG2_GPU
mog2
;
GMG_GPU
gmg
;
gmg
.
numInitializationFrames
=
40
;
...
...
@@ -96,7 +96,7 @@ int main(int argc, const char** argv)
break
;
case
MOG
:
mog
(
d_frame
,
d_fgmask
,
0.01
f
);
mog
->
apply
(
d_frame
,
d_fgmask
,
0.01
);
break
;
case
MOG2
:
...
...
@@ -135,8 +135,8 @@ int main(int argc, const char** argv)
break
;
case
MOG
:
mog
(
d_frame
,
d_fgmask
,
0.01
f
);
mog
.
getBackgroundImage
(
d_bgimg
);
mog
->
apply
(
d_frame
,
d_fgmask
,
0.01
);
mog
->
getBackgroundImage
(
d_bgimg
);
break
;
case
MOG2
:
...
...
samples/gpu/performance/tests.cpp
View file @
a2adab72
...
...
@@ -1346,10 +1346,10 @@ TEST(MOG)
cap
>>
frame
;
cv
::
gpu
::
GpuMat
d_frame
(
frame
);
cv
::
gpu
::
MOG_GPU
d_mog
;
cv
::
Ptr
<
cv
::
BackgroundSubtractor
>
d_mog
=
cv
::
gpu
::
createBackgroundSubtractorMOG
()
;
cv
::
gpu
::
GpuMat
d_foreground
;
d_mog
(
d_frame
,
d_foreground
,
0.01
f
);
d_mog
->
apply
(
d_frame
,
d_foreground
,
0.01
);
while
(
!
TestSystem
::
instance
().
stop
())
{
...
...
@@ -1358,7 +1358,7 @@ TEST(MOG)
TestSystem
::
instance
().
gpuOn
();
d_mog
(
d_frame
,
d_foreground
,
0.01
f
);
d_mog
->
apply
(
d_frame
,
d_foreground
,
0.01
);
TestSystem
::
instance
().
gpuOff
();
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment