1#include <iostream>
2#include <string>
3
4#include "opencv2/core.hpp"
5#include "opencv2/core/utility.hpp"
6#include "opencv2/cudabgsegm.hpp"
7#include "opencv2/cudalegacy.hpp"
8#include "opencv2/video.hpp"
9#include "opencv2/highgui.hpp"
10
11using namespace std;
12using namespace cv;
13using namespace cv::cuda;
14
15enum Method
16{
17    MOG,
18    MOG2,
19    GMG,
20    FGD_STAT
21};
22
23int main(int argc, const char** argv)
24{
25    cv::CommandLineParser cmd(argc, argv,
26        "{ c camera |             | use camera }"
27        "{ f file   | ../data/768x576.avi | input video file }"
28        "{ m method | mog         | method (mog, mog2, gmg, fgd) }"
29        "{ h help   |             | print help message }");
30
31    if (cmd.has("help") || !cmd.check())
32    {
33        cmd.printMessage();
34        cmd.printErrors();
35        return 0;
36    }
37
38    bool useCamera = cmd.has("camera");
39    string file = cmd.get<string>("file");
40    string method = cmd.get<string>("method");
41
42    if (method != "mog"
43        && method != "mog2"
44        && method != "gmg"
45        && method != "fgd")
46    {
47        cerr << "Incorrect method" << endl;
48        return -1;
49    }
50
51    Method m = method == "mog" ? MOG :
52               method == "mog2" ? MOG2 :
53               method == "fgd" ? FGD_STAT :
54                                  GMG;
55
56    VideoCapture cap;
57
58    if (useCamera)
59        cap.open(0);
60    else
61        cap.open(file);
62
63    if (!cap.isOpened())
64    {
65        cerr << "can not open camera or video file" << endl;
66        return -1;
67    }
68
69    Mat frame;
70    cap >> frame;
71
72    GpuMat d_frame(frame);
73
74    Ptr<BackgroundSubtractor> mog = cuda::createBackgroundSubtractorMOG();
75    Ptr<BackgroundSubtractor> mog2 = cuda::createBackgroundSubtractorMOG2();
76    Ptr<BackgroundSubtractor> gmg = cuda::createBackgroundSubtractorGMG(40);
77    Ptr<BackgroundSubtractor> fgd = cuda::createBackgroundSubtractorFGD();
78
79    GpuMat d_fgmask;
80    GpuMat d_fgimg;
81    GpuMat d_bgimg;
82
83    Mat fgmask;
84    Mat fgimg;
85    Mat bgimg;
86
87    switch (m)
88    {
89    case MOG:
90        mog->apply(d_frame, d_fgmask, 0.01);
91        break;
92
93    case MOG2:
94        mog2->apply(d_frame, d_fgmask);
95        break;
96
97    case GMG:
98        gmg->apply(d_frame, d_fgmask);
99        break;
100
101    case FGD_STAT:
102        fgd->apply(d_frame, d_fgmask);
103        break;
104    }
105
106    namedWindow("image", WINDOW_NORMAL);
107    namedWindow("foreground mask", WINDOW_NORMAL);
108    namedWindow("foreground image", WINDOW_NORMAL);
109    if (m != GMG)
110    {
111        namedWindow("mean background image", WINDOW_NORMAL);
112    }
113
114    for(;;)
115    {
116        cap >> frame;
117        if (frame.empty())
118            break;
119        d_frame.upload(frame);
120
121        int64 start = cv::getTickCount();
122
123        //update the model
124        switch (m)
125        {
126        case MOG:
127            mog->apply(d_frame, d_fgmask, 0.01);
128            mog->getBackgroundImage(d_bgimg);
129            break;
130
131        case MOG2:
132            mog2->apply(d_frame, d_fgmask);
133            mog2->getBackgroundImage(d_bgimg);
134            break;
135
136        case GMG:
137            gmg->apply(d_frame, d_fgmask);
138            break;
139
140        case FGD_STAT:
141            fgd->apply(d_frame, d_fgmask);
142            fgd->getBackgroundImage(d_bgimg);
143            break;
144        }
145
146        double fps = cv::getTickFrequency() / (cv::getTickCount() - start);
147        std::cout << "FPS : " << fps << std::endl;
148
149        d_fgimg.create(d_frame.size(), d_frame.type());
150        d_fgimg.setTo(Scalar::all(0));
151        d_frame.copyTo(d_fgimg, d_fgmask);
152
153        d_fgmask.download(fgmask);
154        d_fgimg.download(fgimg);
155        if (!d_bgimg.empty())
156            d_bgimg.download(bgimg);
157
158        imshow("image", frame);
159        imshow("foreground mask", fgmask);
160        imshow("foreground image", fgimg);
161        if (!bgimg.empty())
162            imshow("mean background image", bgimg);
163
164        int key = waitKey(30);
165        if (key == 27)
166            break;
167    }
168
169    return 0;
170}
171