Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/tapi/camshift.cpp
16337 views
1
#include "opencv2/core/utility.hpp"
2
#include "opencv2/core/ocl.hpp"
3
#include "opencv2/video/tracking.hpp"
4
#include "opencv2/imgproc.hpp"
5
#include "opencv2/videoio.hpp"
6
#include "opencv2/highgui.hpp"
7
8
#include <iostream>
9
#include <cctype>
10
11
static cv::UMat image;
12
static bool backprojMode = false;
13
static bool selectObject = false;
14
static int trackObject = 0;
15
static bool showHist = true;
16
static cv::Rect selection;
17
static int vmin = 10, vmax = 256, smin = 30;
18
19
static void onMouse(int event, int x, int y, int, void*)
20
{
21
static cv::Point origin;
22
23
if (selectObject)
24
{
25
selection.x = std::min(x, origin.x);
26
selection.y = std::min(y, origin.y);
27
selection.width = std::abs(x - origin.x);
28
selection.height = std::abs(y - origin.y);
29
30
selection &= cv::Rect(0, 0, image.cols, image.rows);
31
}
32
33
switch (event)
34
{
35
case cv::EVENT_LBUTTONDOWN:
36
origin = cv::Point(x, y);
37
selection = cv::Rect(x, y, 0, 0);
38
selectObject = true;
39
break;
40
case cv::EVENT_LBUTTONUP:
41
selectObject = false;
42
if (selection.width > 0 && selection.height > 0)
43
trackObject = -1;
44
break;
45
default:
46
break;
47
}
48
}
49
50
static void help()
51
{
52
std::cout << "\nThis is a demo that shows mean-shift based tracking using Transparent API\n"
53
"You select a color objects such as your face and it tracks it.\n"
54
"This reads from video camera (0 by default, or the camera number the user enters\n"
55
"Usage: \n"
56
" ./camshiftdemo [camera number]\n";
57
58
std::cout << "\n\nHot keys: \n"
59
"\tESC - quit the program\n"
60
"\ts - stop the tracking\n"
61
"\tb - switch to/from backprojection view\n"
62
"\th - show/hide object histogram\n"
63
"\tp - pause video\n"
64
"\tc - use OpenCL or not\n"
65
"To initialize tracking, select the object with mouse\n";
66
}
67
68
int main(int argc, const char ** argv)
69
{
70
help();
71
72
cv::VideoCapture cap;
73
cv::Rect trackWindow;
74
int hsize = 16;
75
float hranges[2] = { 0, 180 };
76
77
const char * const keys = { "{@camera_number| 0 | camera number}" };
78
cv::CommandLineParser parser(argc, argv, keys);
79
int camNum = parser.get<int>(0);
80
81
cap.open(camNum);
82
83
if (!cap.isOpened())
84
{
85
help();
86
87
std::cout << "***Could not initialize capturing...***\n";
88
std::cout << "Current parameter's value: \n";
89
parser.printMessage();
90
91
return EXIT_FAILURE;
92
}
93
94
cv::namedWindow("Histogram", cv::WINDOW_NORMAL);
95
cv::namedWindow("CamShift Demo", cv::WINDOW_NORMAL);
96
cv::setMouseCallback("CamShift Demo", onMouse);
97
cv::createTrackbar("Vmin", "CamShift Demo", &vmin, 256);
98
cv::createTrackbar("Vmax", "CamShift Demo", &vmax, 256);
99
cv::createTrackbar("Smin", "CamShift Demo", &smin, 256);
100
101
cv::Mat frame, histimg(200, 320, CV_8UC3, cv::Scalar::all(0));
102
cv::UMat hsv, hist, hue, mask, backproj;
103
bool paused = false;
104
105
for ( ; ; )
106
{
107
if (!paused)
108
{
109
cap >> frame;
110
if (frame.empty())
111
break;
112
}
113
114
frame.copyTo(image);
115
116
if (!paused)
117
{
118
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
119
120
if (trackObject)
121
{
122
int _vmin = vmin, _vmax = vmax;
123
124
cv::inRange(hsv, cv::Scalar(0, smin, std::min(_vmin, _vmax)),
125
cv::Scalar(180, 256, std::max(_vmin, _vmax)), mask);
126
127
int fromTo[2] = { 0,0 };
128
hue.create(hsv.size(), hsv.depth());
129
cv::mixChannels(std::vector<cv::UMat>(1, hsv), std::vector<cv::UMat>(1, hue), fromTo, 1);
130
131
if (trackObject < 0)
132
{
133
cv::UMat roi(hue, selection), maskroi(mask, selection);
134
cv::calcHist(std::vector<cv::Mat>(1, roi.getMat(cv::ACCESS_READ)), std::vector<int>(1, 0),
135
maskroi, hist, std::vector<int>(1, hsize), std::vector<float>(hranges, hranges + 2));
136
cv::normalize(hist, hist, 0, 255, cv::NORM_MINMAX);
137
138
trackWindow = selection;
139
trackObject = 1;
140
141
histimg = cv::Scalar::all(0);
142
int binW = histimg.cols / hsize;
143
cv::Mat buf (1, hsize, CV_8UC3);
144
for (int i = 0; i < hsize; i++)
145
buf.at<cv::Vec3b>(i) = cv::Vec3b(cv::saturate_cast<uchar>(i*180./hsize), 255, 255);
146
cv::cvtColor(buf, buf, cv::COLOR_HSV2BGR);
147
148
{
149
cv::Mat _hist = hist.getMat(cv::ACCESS_READ);
150
for (int i = 0; i < hsize; i++)
151
{
152
int val = cv::saturate_cast<int>(_hist.at<float>(i)*histimg.rows/255);
153
cv::rectangle(histimg, cv::Point(i*binW, histimg.rows),
154
cv::Point((i+1)*binW, histimg.rows - val),
155
cv::Scalar(buf.at<cv::Vec3b>(i)), -1, 8);
156
}
157
}
158
}
159
160
cv::calcBackProject(std::vector<cv::UMat>(1, hue), std::vector<int>(1, 0), hist, backproj,
161
std::vector<float>(hranges, hranges + 2), 1.0);
162
cv::bitwise_and(backproj, mask, backproj);
163
164
cv::RotatedRect trackBox = cv::CamShift(backproj, trackWindow,
165
cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::COUNT, 10, 1));
166
if (trackWindow.area() <= 1)
167
{
168
int cols = backproj.cols, rows = backproj.rows, r = (std::min(cols, rows) + 5)/6;
169
trackWindow = cv::Rect(trackWindow.x - r, trackWindow.y - r,
170
trackWindow.x + r, trackWindow.y + r) &
171
cv::Rect(0, 0, cols, rows);
172
}
173
174
if (backprojMode)
175
cv::cvtColor(backproj, image, cv::COLOR_GRAY2BGR);
176
177
{
178
cv::Mat _image = image.getMat(cv::ACCESS_RW);
179
cv::ellipse(_image, trackBox, cv::Scalar(0, 0, 255), 3, cv::LINE_AA);
180
}
181
}
182
}
183
else if (trackObject < 0)
184
paused = false;
185
186
if (selectObject && selection.width > 0 && selection.height > 0)
187
{
188
cv::UMat roi(image, selection);
189
cv::bitwise_not(roi, roi);
190
}
191
192
cv::imshow("CamShift Demo", image);
193
if (showHist)
194
cv::imshow("Histogram", histimg);
195
196
char c = (char)cv::waitKey(10);
197
if (c == 27)
198
break;
199
200
switch(c)
201
{
202
case 'b':
203
backprojMode = !backprojMode;
204
break;
205
case 't':
206
trackObject = 0;
207
histimg = cv::Scalar::all(0);
208
break;
209
case 'h':
210
showHist = !showHist;
211
if (!showHist)
212
cv::destroyWindow("Histogram");
213
else
214
cv::namedWindow("Histogram", cv::WINDOW_AUTOSIZE);
215
break;
216
case 'p':
217
paused = !paused;
218
break;
219
case 'c':
220
cv::ocl::setUseOpenCL(!cv::ocl::useOpenCL());
221
default:
222
break;
223
}
224
}
225
226
return EXIT_SUCCESS;
227
}
228
229