-
Notifications
You must be signed in to change notification settings - Fork 0
/
videoBall.cpp
127 lines (98 loc) · 3.67 KB
/
videoBall.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdio.h>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/opencv.hpp"
#include "physics.h"
using namespace cv;
using namespace std;
const char *win = "Flying Pancake";
static bool reverseMirror = false;
int main(int argc, char **argv)
{
if (argc > 2) {
fprintf(stderr, "Error: Please limit arguments to 1 or none.\n");
exit(1);
}
else if (argc == 2) {
if (!strcmp(argv[1], "-m"))
reverseMirror = true;
else {
fprintf(stderr, "Usage: videoBall [-m]\n");
exit(1);
}
}
int cam = 0; // default camera
VideoCapture cap(cam);
if (!cap.isOpened()) {
fprintf(stderr, "Error: Cannot open camera %d\n", cam);
exit(1);
}
namedWindow(win, CV_WINDOW_AUTOSIZE);
Mat fgMaskMOG; // foreground mask generated by MOG method
Mat inputFrame, outFrame;
Mat circ;
Point pt; // center of the ball
BackgroundSubtractorMOG2 MOG;
// initial position
pt.x = 500;
pt.y = 0;
Point momentum;
momentum.x = 10;
momentum.y = 50;
cap >> inputFrame;
cvtColor(inputFrame, outFrame, CV_LOAD_IMAGE_COLOR);
cvtColor(inputFrame, circ, CV_BGR2GRAY);
int height = inputFrame.rows - 2 * RADIUS;
int width = inputFrame.cols - 2 * RADIUS;
int count = 0;
int sum;
Point small;
Mat ballFrame, handFrame;
Mat foregroundMask, backgroundMask;
Mat reverseFrame;
while (++count) {
cap >> inputFrame;
if (reverseMirror) {
inputFrame.copyTo(reverseFrame);
flip(reverseFrame, inputFrame, 1); // 1 ~ flip against y axis
}
calcDir(&momentum, &pt, height, width); // according to last frame
MOG(inputFrame, fgMaskMOG);
// blank canvas
circ.setTo(Scalar(0,0,0));
Rect ballRegion(pt.x - RADIUS, pt.y - RADIUS, 2 * RADIUS, 2 * RADIUS);
ballFrame = circ(ballRegion);
foregroundMask = fgMaskMOG > THRESH; // have to put here otherwise floating point exception
backgroundMask = fgMaskMOG <= THRESH;
// fgMaskMOG.setTo(Scalar(255, 255, 255), foregroundMask); // clean up
fgMaskMOG.setTo(Scalar(0, 0, 0), backgroundMask);
handFrame = fgMaskMOG(ballRegion); // cut to small size
int halfRad = RADIUS / 2;
// top left
small.x = halfRad; small.y = halfRad;
sum = getOverlap(&ballFrame, &handFrame, &small);
momentum.x += sum; momentum.y += sum;
// top right
small.x = 3 * halfRad; small.y = halfRad;
sum = getOverlap(&ballFrame, &handFrame, &small);
momentum.x -= sum; momentum.y += sum;
// bottom left
small.x = halfRad; small.y = 3 * halfRad;
sum = getOverlap(&ballFrame, &handFrame, &small);
momentum.x += sum; momentum.y -= sum/3;
// bottom right
small.x = 3 * halfRad; small.y = 3 * halfRad;
sum = getOverlap(&ballFrame, &handFrame, &small);
momentum.x -= sum; momentum.y -= sum/3;
// EVERYTHING BELOW THIS LINE SHOULD BE DRAWING THE outFrame
outFrame.setTo(Scalar(0,0,0)); // set all of outFrame to be black
outFrame.setTo(Scalar(255, 255, 255), foregroundMask);
drawCircle(outFrame, pt, RADIUS, Scalar(255, 255, 255));
imshow(win, outFrame);
if (waitKey(1) >= 0) // listening for key press
break;
}
return 0;
}