camshiftdemo.cpp

Pei JIA, 2011-03-19 07:08 pm

Download (6.5 kB)

 
1
2
#include <iostream>
3
#include "cv.h"
4
#include "highgui.h"
5
6
using namespace std;
7
using namespace cv;
8
9
10
int hbins = 16;                                                                                // quantize the hue2 to 32 levels
11
int sbins = 32;                                                                                // quantize the saturation to 32 levels
12
//int CTrackingAlgs::histSize[] = {hbins, sbins};        // histSize
13
int histSize[] = {hbins};                                                        // histSize
14
float hranges[] = { 0, 180 };                                                // hue2 varies from 0 to 179, see cvtColor
15
float sranges[] = { 0, 256 };                                                // saturation varies from 0 (black-gray-white) to 255 (pure spectrum color)
16
//const float* ranges[] = { hranges, sranges };                // ranges
17
const float* ranges[] = { hranges };                                // ranges
18
int channels[] = {0};
19
20
int backproject_mode = 0;
21
int select_object = 0;
22
int track_object = 0;
23
int show_hist = 1;
24
25
Point origin2;
26
Rect selection2;
27
Rect track_window2;
28
RotatedRect        track_box2;
29
int vmin = 10, vmax = 256, smin = 30;
30
Mat image2, hsv2, hue2, mask2, backproject2;
31
MatND hist2;
32
Mat histimg2 = Mat::zeros(200, 320, CV_8UC3);
33
34
35
void on_mouse( int event, int x, int y, int flags, void* param )
36
{
37
    if( image2.empty() )
38
        return;
39
40
    if( select_object )
41
    {
42
        selection2.x = MIN(x,origin2.x);
43
        selection2.y = MIN(y,origin2.y);
44
        selection2.width = selection2.x + CV_IABS(x - origin2.x);
45
        selection2.height = selection2.y + CV_IABS(y - origin2.y);
46
47
        selection2.x = MAX( selection2.x, 0 );
48
        selection2.y = MAX( selection2.y, 0 );
49
        selection2.width = MIN( selection2.width, image2.cols );
50
        selection2.height = MIN( selection2.height, image2.rows );
51
        selection2.width -= selection2.x;
52
        selection2.height -= selection2.y;
53
    }
54
55
    switch( event )
56
    {
57
    case CV_EVENT_LBUTTONDOWN:
58
        origin2 = cvPoint(x,y);
59
        selection2 = cvRect(x,y,0,0);
60
        select_object = 1;
61
        break;
62
    case CV_EVENT_LBUTTONUP:
63
        select_object = 0;
64
        if( selection2.width > 0 && selection2.height > 0 )
65
            track_object = -1;
66
        break;
67
    }
68
}
69
70
71
Scalar hsv2rgb( float hue2 )
72
{
73
    int rgb[3], p, sector;
74
    static const int sector_data[][3]=
75
        {{0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0}, {0,1,2}};
76
    hue2 *= 0.033333333333333333333333333333333f;
77
    sector = cvFloor(hue2);
78
    p = cvRound(255*(hue2 - sector));
79
    p ^= sector & 1 ? 255 : 0;
80
81
    rgb[sector_data[sector][0]] = 255;
82
    rgb[sector_data[sector][1]] = 0;
83
    rgb[sector_data[sector][2]] = p;
84
85
    return Scalar(rgb[2], rgb[1], rgb[0],0);
86
}
87
88
89
int main( int argc, char** argv )
90
{
91
    VideoCapture capture;
92
        capture.set(CV_CAP_PROP_FRAME_WIDTH,320);
93
        capture.set(CV_CAP_PROP_FRAME_HEIGHT,240);
94
        bool isOpened = false;
95
        
96
    if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
97
        isOpened = capture.open( argc == 2 ? argv[1][0] - '0' : 0 );
98
    else if( argc == 2 )
99
        isOpened = capture.open( argv[1] );
100
101
    if( !capture.isOpened() )
102
    {
103
        cerr << "Could not initialize capturing..." << endl;
104
        return -1;
105
    }
106
107
    cout << "Hot keys: " << endl
108
        << "\tESC - quit the program" << endl
109
        << "\tc - stop the tracking" << endl
110
        << "\tb - switch to/from backprojection view" << endl
111
        << "\th - show/hide object histogram" << endl
112
        << "To initialize tracking, select the object with mouse" << endl;
113
                
114
        namedWindow( "CamShiftDemo", 1 );        
115
    cvSetMouseCallback( "CamShiftDemo", on_mouse, 0 );
116
    createTrackbar( "Vmin", "CamShiftDemo", &vmin, 256, 0 );
117
    createTrackbar( "Vmax", "CamShiftDemo", &vmax, 256, 0 );
118
    createTrackbar( "Smin", "CamShiftDemo", &smin, 256, 0 );
119
        namedWindow( "Histogram", 1 );
120
121
    for(;;)
122
    {
123
        Mat frame;
124
        int i, bin_w, c;
125
126
        capture >> frame;
127
        if (frame.empty())        break;
128
129
                
130
        frame.copyTo( image2 );
131
        cvtColor( image2, hsv2, CV_BGR2HSV );
132
133
        if( track_object )
134
        {
135
            int _vmin = vmin, _vmax = vmax;
136
137
            inRange( hsv2, Scalar(0,smin,MIN(_vmin,_vmax),0),
138
                        Scalar(180,256,MAX(_vmin,_vmax),0), mask2 );
139
                        vector<Mat> vhsv;
140
                        vhsv.resize(3);
141
                        split( hsv2, vhsv );
142
                        vhsv[0].copyTo(hue2);
143
144
                        
145
            if( track_object < 0 )
146
            {
147
                double max_val2 = 0.f;
148
                                Mat roi = hue2(Range(selection2.y, selection2.y+selection2.height), 
149
                                                        Range(selection2.x, selection2.x+selection2.width) );
150
                                Mat roi_mask = mask2(Range(selection2.y, selection2.y+selection2.height), 
151
                                                        Range(selection2.x, selection2.x+selection2.width) );
152
                                calcHist( &roi, 1, channels, roi_mask,
153
                                                        hist2, 1, histSize, ranges,
154
                                                        true, // the histogram is uniform
155
                                                        false );
156
                                minMaxLoc(hist2, 0, &max_val2, 0, 0);
157
                                hist2.convertTo(hist2, hist2.type(), (max_val2 ? 255. / max_val2 : 0.), 0);
158
                                track_window2 = selection2;
159
                track_object = 1;
160
                                
161
                                histimg2 = Mat::zeros(histimg2.size(), histimg2.type());
162
                bin_w = histimg2.cols / hbins;
163
                for( i = 0; i < hbins; i++ )
164
                {
165
                                        int val2 = cvRound( hist2.at<float>(i)*(float)histimg2.rows/255.0 );
166
                    Scalar color = hsv2rgb(i*180.f/hbins);
167
                                        rectangle(histimg2, Point(i*bin_w,histimg2.rows), 
168
                                                        Point((i+1)*bin_w,histimg2.rows - val2),
169
                                                        color, -1, 8, 0);
170
                }
171
            }
172
                        
173
                        
174
                        calcBackProject( &hue2, 1, channels, hist2, backproject2, ranges);
175
            bitwise_and( backproject2, mask2, backproject2 );
176
                        track_box2 = CamShift( backproject2, track_window2, TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 10, 1) );
177
                        
178
            if( backproject_mode )
179
                cvtColor( backproject2, image2, CV_GRAY2BGR );
180
                        ellipse(image2, track_box2, CV_RGB(255,0,0), 3, CV_AA);
181
                        
182
        }
183
184
                // This is for display, just indicate what is the area that the user has selected
185
        if( select_object && selection2.width > 0 && selection2.height > 0 )
186
        {
187
                        Mat roi(image2, selection2);
188
                        bitwise_xor( roi, cvScalarAll(255), roi );
189
        }
190
                
191
                imshow( "CamShiftDemo", image2 );
192
                imshow( "Histogram", histimg2 );
193
                waitKey(10);
194
195
        if( (char) c == 27 )
196
            break;
197
        switch( (char) c )
198
        {
199
        case 'b':
200
            backproject_mode ^= 1;
201
            break;
202
        case 'c':
203
            track_object = 0;
204
                        histimg2 = Mat::zeros(histimg2.size(), histimg2.type());
205
            break;
206
        case 'h':
207
            show_hist ^= 1;
208
            if( !show_hist )
209
                cvDestroyWindow( "Histogram2" );
210
            else
211
                namedWindow( "Histogram2", 1 );
212
            break;
213
        default:
214
            ;
215
        }
216
    }
217
218
    return 0;
219
}
220