Merge pull request #1804 from alekcac:youtube_link_fix
[profile/ivi/opencv.git] / samples / cpp / segment_objects.cpp
1 #include "opencv2/imgproc/imgproc.hpp"
2 #include "opencv2/highgui/highgui.hpp"
3 #include "opencv2/video/background_segm.hpp"
4 #include <stdio.h>
5 #include <string>
6
7 using namespace std;
8 using namespace cv;
9
10 static void help()
11 {
12     printf("\n"
13             "This program demonstrated a simple method of connected components clean up of background subtraction\n"
14             "When the program starts, it begins learning the background.\n"
15             "You can toggle background learning on and off by hitting the space bar.\n"
16             "Call\n"
17             "./segment_objects [video file, else it reads camera 0]\n\n");
18 }
19
20 static void refineSegments(const Mat& img, Mat& mask, Mat& dst)
21 {
22     int niters = 3;
23
24     vector<vector<Point> > contours;
25     vector<Vec4i> hierarchy;
26
27     Mat temp;
28
29     dilate(mask, temp, Mat(), Point(-1,-1), niters);
30     erode(temp, temp, Mat(), Point(-1,-1), niters*2);
31     dilate(temp, temp, Mat(), Point(-1,-1), niters);
32
33     findContours( temp, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE );
34
35     dst = Mat::zeros(img.size(), CV_8UC3);
36
37     if( contours.size() == 0 )
38         return;
39
40     // iterate through all the top-level contours,
41     // draw each connected component with its own random color
42     int idx = 0, largestComp = 0;
43     double maxArea = 0;
44
45     for( ; idx >= 0; idx = hierarchy[idx][0] )
46     {
47         const vector<Point>& c = contours[idx];
48         double area = fabs(contourArea(Mat(c)));
49         if( area > maxArea )
50         {
51             maxArea = area;
52             largestComp = idx;
53         }
54     }
55     Scalar color( 0, 0, 255 );
56     drawContours( dst, contours, largestComp, color, FILLED, LINE_8, hierarchy );
57 }
58
59
60 int main(int argc, char** argv)
61 {
62     VideoCapture cap;
63     bool update_bg_model = true;
64
65     help();
66
67     if( argc < 2 )
68         cap.open(0);
69     else
70         cap.open(std::string(argv[1]));
71
72     if( !cap.isOpened() )
73     {
74         printf("\nCan not open camera or video file\n");
75         return -1;
76     }
77
78     Mat tmp_frame, bgmask, out_frame;
79
80     cap >> tmp_frame;
81     if(!tmp_frame.data)
82     {
83         printf("can not read data from the video source\n");
84         return -1;
85     }
86
87     namedWindow("video", 1);
88     namedWindow("segmented", 1);
89
90     Ptr<BackgroundSubtractorMOG> bgsubtractor=createBackgroundSubtractorMOG();
91     bgsubtractor->setNoiseSigma(10);
92
93     for(;;)
94     {
95         cap >> tmp_frame;
96         if( !tmp_frame.data )
97             break;
98         bgsubtractor->apply(tmp_frame, bgmask, update_bg_model ? -1 : 0);
99         //CvMat _bgmask = bgmask;
100         //cvSegmentFGMask(&_bgmask);
101         refineSegments(tmp_frame, bgmask, out_frame);
102         imshow("video", tmp_frame);
103         imshow("segmented", out_frame);
104         int keycode = waitKey(30);
105         if( keycode == 27 )
106             break;
107         if( keycode == ' ' )
108         {
109             update_bg_model = !update_bg_model;
110             printf("Learn background is in state = %d\n",update_bg_model);
111         }
112     }
113
114     return 0;
115 }