~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/modules/cudabgsegm/src/mog2.cpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*M///////////////////////////////////////////////////////////////////////////////////////
 
2
//
 
3
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
 
4
//
 
5
//  By downloading, copying, installing or using the software you agree to this license.
 
6
//  If you do not agree to this license, do not download, install,
 
7
//  copy or use the software.
 
8
//
 
9
//
 
10
//                           License Agreement
 
11
//                For Open Source Computer Vision Library
 
12
//
 
13
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
 
14
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
 
15
// Third party copyrights are property of their respective owners.
 
16
//
 
17
// Redistribution and use in source and binary forms, with or without modification,
 
18
// are permitted provided that the following conditions are met:
 
19
//
 
20
//   * Redistribution's of source code must retain the above copyright notice,
 
21
//     this list of conditions and the following disclaimer.
 
22
//
 
23
//   * Redistribution's in binary form must reproduce the above copyright notice,
 
24
//     this list of conditions and the following disclaimer in the documentation
 
25
//     and/or other materials provided with the distribution.
 
26
//
 
27
//   * The name of the copyright holders may not be used to endorse or promote products
 
28
//     derived from this software without specific prior written permission.
 
29
//
 
30
// This software is provided by the copyright holders and contributors "as is" and
 
31
// any express or implied warranties, including, but not limited to, the implied
 
32
// warranties of merchantability and fitness for a particular purpose are disclaimed.
 
33
// In no event shall the Intel Corporation or contributors be liable for any direct,
 
34
// indirect, incidental, special, exemplary, or consequential damages
 
35
// (including, but not limited to, procurement of substitute goods or services;
 
36
// loss of use, data, or profits; or business interruption) however caused
 
37
// and on any theory of liability, whether in contract, strict liability,
 
38
// or tort (including negligence or otherwise) arising in any way out of
 
39
// the use of this software, even if advised of the possibility of such damage.
 
40
//
 
41
//M*/
 
42
 
 
43
#include "precomp.hpp"
 
44
 
 
45
using namespace cv;
 
46
using namespace cv::cuda;
 
47
 
 
48
#if !defined HAVE_CUDA || defined(CUDA_DISABLER)
 
49
 
 
50
Ptr<cuda::BackgroundSubtractorMOG2> cv::cuda::createBackgroundSubtractorMOG2(int, double, bool) { throw_no_cuda(); return Ptr<cuda::BackgroundSubtractorMOG2>(); }
 
51
 
 
52
#else
 
53
 
 
54
namespace cv { namespace cuda { namespace device
 
55
{
 
56
    namespace mog2
 
57
    {
 
58
        void loadConstants(int nmixtures, float Tb, float TB, float Tg, float varInit, float varMin, float varMax, float tau, unsigned char shadowVal);
 
59
        void mog2_gpu(PtrStepSzb frame, int cn, PtrStepSzb fgmask, PtrStepSzb modesUsed, PtrStepSzf weight, PtrStepSzf variance, PtrStepSzb mean, float alphaT, float prune, bool detectShadows, cudaStream_t stream);
 
60
        void getBackgroundImage2_gpu(int cn, PtrStepSzb modesUsed, PtrStepSzf weight, PtrStepSzb mean, PtrStepSzb dst, cudaStream_t stream);
 
61
    }
 
62
}}}
 
63
 
 
64
namespace
 
65
{
 
66
    // default parameters of gaussian background detection algorithm
 
67
    const int defaultHistory = 500; // Learning rate; alpha = 1/defaultHistory2
 
68
    const float defaultVarThreshold = 4.0f * 4.0f;
 
69
    const int defaultNMixtures = 5; // maximal number of Gaussians in mixture
 
70
    const float defaultBackgroundRatio = 0.9f; // threshold sum of weights for background test
 
71
    const float defaultVarThresholdGen = 3.0f * 3.0f;
 
72
    const float defaultVarInit = 15.0f; // initial variance for new components
 
73
    const float defaultVarMax = 5.0f * defaultVarInit;
 
74
    const float defaultVarMin = 4.0f;
 
75
 
 
76
    // additional parameters
 
77
    const float defaultCT = 0.05f; // complexity reduction prior constant 0 - no reduction of number of components
 
78
    const unsigned char defaultShadowValue = 127; // value to use in the segmentation mask for shadows, set 0 not to do shadow detection
 
79
    const float defaultShadowThreshold = 0.5f; // Tau - shadow threshold, see the paper for explanation
 
80
 
 
81
    class MOG2Impl : public cuda::BackgroundSubtractorMOG2
 
82
    {
 
83
    public:
 
84
        MOG2Impl(int history, double varThreshold, bool detectShadows);
 
85
 
 
86
        void apply(InputArray image, OutputArray fgmask, double learningRate=-1);
 
87
        void apply(InputArray image, OutputArray fgmask, double learningRate, Stream& stream);
 
88
 
 
89
        void getBackgroundImage(OutputArray backgroundImage) const;
 
90
        void getBackgroundImage(OutputArray backgroundImage, Stream& stream) const;
 
91
 
 
92
        int getHistory() const { return history_; }
 
93
        void setHistory(int history) { history_ = history; }
 
94
 
 
95
        int getNMixtures() const { return nmixtures_; }
 
96
        void setNMixtures(int nmixtures) { nmixtures_ = nmixtures; }
 
97
 
 
98
        double getBackgroundRatio() const { return backgroundRatio_; }
 
99
        void setBackgroundRatio(double ratio) { backgroundRatio_ = (float) ratio; }
 
100
 
 
101
        double getVarThreshold() const { return varThreshold_; }
 
102
        void setVarThreshold(double varThreshold) { varThreshold_ = (float) varThreshold; }
 
103
 
 
104
        double getVarThresholdGen() const { return varThresholdGen_; }
 
105
        void setVarThresholdGen(double varThresholdGen) { varThresholdGen_ = (float) varThresholdGen; }
 
106
 
 
107
        double getVarInit() const { return varInit_; }
 
108
        void setVarInit(double varInit) { varInit_ = (float) varInit; }
 
109
 
 
110
        double getVarMin() const { return varMin_; }
 
111
        void setVarMin(double varMin) { varMin_ = (float) varMin; }
 
112
 
 
113
        double getVarMax() const { return varMax_; }
 
114
        void setVarMax(double varMax) { varMax_ = (float) varMax; }
 
115
 
 
116
        double getComplexityReductionThreshold() const { return ct_; }
 
117
        void setComplexityReductionThreshold(double ct) { ct_ = (float) ct; }
 
118
 
 
119
        bool getDetectShadows() const { return detectShadows_; }
 
120
        void setDetectShadows(bool detectShadows) { detectShadows_ = detectShadows; }
 
121
 
 
122
        int getShadowValue() const { return shadowValue_; }
 
123
        void setShadowValue(int value) { shadowValue_ = (uchar) value; }
 
124
 
 
125
        double getShadowThreshold() const { return shadowThreshold_; }
 
126
        void setShadowThreshold(double threshold) { shadowThreshold_ = (float) threshold; }
 
127
 
 
128
    private:
 
129
        void initialize(Size frameSize, int frameType);
 
130
 
 
131
        int history_;
 
132
        int nmixtures_;
 
133
        float backgroundRatio_;
 
134
        float varThreshold_;
 
135
        float varThresholdGen_;
 
136
        float varInit_;
 
137
        float varMin_;
 
138
        float varMax_;
 
139
        float ct_;
 
140
        bool detectShadows_;
 
141
        uchar shadowValue_;
 
142
        float shadowThreshold_;
 
143
 
 
144
        Size frameSize_;
 
145
        int frameType_;
 
146
        int nframes_;
 
147
 
 
148
        GpuMat weight_;
 
149
        GpuMat variance_;
 
150
        GpuMat mean_;
 
151
 
 
152
        //keep track of number of modes per pixel
 
153
        GpuMat bgmodelUsedModes_;
 
154
    };
 
155
 
 
156
    MOG2Impl::MOG2Impl(int history, double varThreshold, bool detectShadows) :
 
157
        frameSize_(0, 0), frameType_(0), nframes_(0)
 
158
    {
 
159
        history_ = history > 0 ? history : defaultHistory;
 
160
        varThreshold_ = varThreshold > 0 ? (float) varThreshold : defaultVarThreshold;
 
161
        detectShadows_ = detectShadows;
 
162
 
 
163
        nmixtures_ = defaultNMixtures;
 
164
        backgroundRatio_ = defaultBackgroundRatio;
 
165
        varInit_ = defaultVarInit;
 
166
        varMax_ = defaultVarMax;
 
167
        varMin_ = defaultVarMin;
 
168
        varThresholdGen_ = defaultVarThresholdGen;
 
169
        ct_ = defaultCT;
 
170
        shadowValue_ =  defaultShadowValue;
 
171
        shadowThreshold_ = defaultShadowThreshold;
 
172
    }
 
173
 
 
174
    void MOG2Impl::apply(InputArray image, OutputArray fgmask, double learningRate)
 
175
    {
 
176
        apply(image, fgmask, learningRate, Stream::Null());
 
177
    }
 
178
 
 
179
    void MOG2Impl::apply(InputArray _frame, OutputArray _fgmask, double learningRate, Stream& stream)
 
180
    {
 
181
        using namespace cv::cuda::device::mog2;
 
182
 
 
183
        GpuMat frame = _frame.getGpuMat();
 
184
 
 
185
        int ch = frame.channels();
 
186
        int work_ch = ch;
 
187
 
 
188
        if (nframes_ == 0 || learningRate >= 1.0 || frame.size() != frameSize_ || work_ch != mean_.channels())
 
189
            initialize(frame.size(), frame.type());
 
190
 
 
191
        _fgmask.create(frameSize_, CV_8UC1);
 
192
        GpuMat fgmask = _fgmask.getGpuMat();
 
193
 
 
194
        fgmask.setTo(Scalar::all(0), stream);
 
195
 
 
196
        ++nframes_;
 
197
        learningRate = learningRate >= 0 && nframes_ > 1 ? learningRate : 1.0 / std::min(2 * nframes_, history_);
 
198
        CV_Assert( learningRate >= 0 );
 
199
 
 
200
        mog2_gpu(frame, frame.channels(), fgmask, bgmodelUsedModes_, weight_, variance_, mean_,
 
201
                 (float) learningRate, static_cast<float>(-learningRate * ct_), detectShadows_, StreamAccessor::getStream(stream));
 
202
    }
 
203
 
 
204
    void MOG2Impl::getBackgroundImage(OutputArray backgroundImage) const
 
205
    {
 
206
        getBackgroundImage(backgroundImage, Stream::Null());
 
207
    }
 
208
 
 
209
    void MOG2Impl::getBackgroundImage(OutputArray _backgroundImage, Stream& stream) const
 
210
    {
 
211
        using namespace cv::cuda::device::mog2;
 
212
 
 
213
        _backgroundImage.create(frameSize_, frameType_);
 
214
        GpuMat backgroundImage = _backgroundImage.getGpuMat();
 
215
 
 
216
        getBackgroundImage2_gpu(backgroundImage.channels(), bgmodelUsedModes_, weight_, mean_, backgroundImage, StreamAccessor::getStream(stream));
 
217
    }
 
218
 
 
219
    void MOG2Impl::initialize(cv::Size frameSize, int frameType)
 
220
    {
 
221
        using namespace cv::cuda::device::mog2;
 
222
 
 
223
        CV_Assert( frameType == CV_8UC1 || frameType == CV_8UC3 || frameType == CV_8UC4 );
 
224
 
 
225
        frameSize_ = frameSize;
 
226
        frameType_ = frameType;
 
227
        nframes_ = 0;
 
228
 
 
229
        int ch = CV_MAT_CN(frameType);
 
230
        int work_ch = ch;
 
231
 
 
232
        // for each gaussian mixture of each pixel bg model we store ...
 
233
        // the mixture weight (w),
 
234
        // the mean (nchannels values) and
 
235
        // the covariance
 
236
        weight_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC1);
 
237
        variance_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC1);
 
238
        mean_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC(work_ch));
 
239
 
 
240
        //make the array for keeping track of the used modes per pixel - all zeros at start
 
241
        bgmodelUsedModes_.create(frameSize_, CV_8UC1);
 
242
        bgmodelUsedModes_.setTo(Scalar::all(0));
 
243
 
 
244
        loadConstants(nmixtures_, varThreshold_, backgroundRatio_, varThresholdGen_, varInit_, varMin_, varMax_, shadowThreshold_, shadowValue_);
 
245
    }
 
246
}
 
247
 
 
248
Ptr<cuda::BackgroundSubtractorMOG2> cv::cuda::createBackgroundSubtractorMOG2(int history, double varThreshold, bool detectShadows)
 
249
{
 
250
    return makePtr<MOG2Impl>(history, varThreshold, detectShadows);
 
251
}
 
252
 
 
253
#endif