-
Notifications
You must be signed in to change notification settings - Fork 70
/
ofApp.cpp
190 lines (140 loc) · 5.72 KB
/
ofApp.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// This example shows how to work with the BodyIndex image in order to create
// a green screen effect. Note that this isn't super fast, but is helpful
// in understanding how the different image types & coordinate spaces work
// together. If you need performance, you will probably want to do this with shaders!
#include "ofApp.h"
#define DEPTH_WIDTH 512
#define DEPTH_HEIGHT 424
#define DEPTH_SIZE DEPTH_WIDTH * DEPTH_HEIGHT
#define COLOR_WIDTH 1920
#define COLOR_HEIGHT 1080
//--------------------------------------------------------------
void ofApp::setup() {
ofSetWindowShape(DEPTH_WIDTH * 2, DEPTH_HEIGHT);
kinect.open();
kinect.initDepthSource();
kinect.initColorSource();
kinect.initInfraredSource();
kinect.initBodySource();
kinect.initBodyIndexSource();
if (kinect.getSensor()->get_CoordinateMapper(&coordinateMapper) < 0) {
ofLogError() << "Could not acquire CoordinateMapper!";
}
numBodiesTracked = 0;
bHaveAllStreams = false;
bodyIndexImg.allocate(DEPTH_WIDTH, DEPTH_HEIGHT, OF_IMAGE_COLOR);
foregroundImg.allocate(DEPTH_WIDTH, DEPTH_HEIGHT, OF_IMAGE_COLOR);
colorCoords.resize(DEPTH_WIDTH * DEPTH_HEIGHT);
}
//--------------------------------------------------------------
void ofApp::update() {
kinect.update();
// Get pixel data
auto& depthPix = kinect.getDepthSource()->getPixels();
auto& bodyIndexPix = kinect.getBodyIndexSource()->getPixels();
auto& colorPix = kinect.getColorSource()->getPixels();
// Make sure there's some data here, otherwise the cam probably isn't ready yet
if (!depthPix.size() || !bodyIndexPix.size() || !colorPix.size()) {
bHaveAllStreams = false;
return;
} else {
bHaveAllStreams = true;
}
// Count number of tracked bodies
numBodiesTracked = 0;
auto& bodies = kinect.getBodySource()->getBodies();
for (auto& body : bodies) {
if (body.tracked) {
numBodiesTracked++;
}
}
// Do the depth space -> color space mapping
// More info here:
// https://msdn.microsoft.com/en-us/library/windowspreview.kinect.coordinatemapper.mapdepthframetocolorspace.aspx
// https://msdn.microsoft.com/en-us/library/dn785530.aspx
coordinateMapper->MapDepthFrameToColorSpace(DEPTH_SIZE, (UINT16*) depthPix.getPixels(), DEPTH_SIZE, (ColorSpacePoint*) colorCoords.data());
// Loop through the depth image
for (int y = 0; y < DEPTH_HEIGHT; y++) {
for (int x = 0; x < DEPTH_WIDTH; x++) {
int index = (y * DEPTH_WIDTH) + x;
bodyIndexImg.setColor(x, y, ofColor::white);
foregroundImg.setColor(x, y, ofColor::white);
// This is the check to see if a given pixel is inside a tracked body or part of the background.
// If it's part of a body, the value will be that body's id (0-5), or will > 5 if it's
// part of the background
// More info here:
// https://msdn.microsoft.com/en-us/library/windowspreview.kinect.bodyindexframe.aspx
float val = bodyIndexPix[index];
if (val >= bodies.size()) {
continue;
}
// Give each tracked body a color value so we can tell
// them apart on screen
ofColor c = ofColor::fromHsb(val * 255 / bodies.size(), 200, 255);
bodyIndexImg.setColor(x, y, c);
// For a given (x,y) in the depth image, lets look up where that point would be
// in the color image
ofVec2f mappedCoord = colorCoords[index];
// Mapped x/y coordinates in the color can come out as floats since it's not a 1:1 mapping
// between depth <-> color spaces i.e. a pixel at (100, 100) in the depth image could map
// to (405.84637, 238.13828) in color space
// So round the x/y values down to ints so that we can look up the nearest pixel
mappedCoord.x = floor(mappedCoord.x);
mappedCoord.y = floor(mappedCoord.y);
// Make sure it's within some sane bounds, and skip it otherwise
if (mappedCoord.x < 0 || mappedCoord.y < 0 || mappedCoord.x >= COLOR_WIDTH || mappedCoord.y >= COLOR_HEIGHT) {
continue;
}
// Finally, pull the color from the color image based on its coords in
// the depth image
foregroundImg.setColor(x, y, colorPix.getColor(mappedCoord.x, mappedCoord.y));
}
}
// Update the images since we manipulated the pixels manually. This uploads to the
// pixel data to the texture on the GPU so it can get drawn to screen
bodyIndexImg.update();
foregroundImg.update();
}
//--------------------------------------------------------------
void ofApp::draw() {
bodyIndexImg.draw(0, 0);
foregroundImg.draw(DEPTH_WIDTH, 0);
stringstream ss;
ss << ofGetFrameRate() << endl;
ss << "Tracked bodies: " << numBodiesTracked;
if (!bHaveAllStreams) ss << endl << "Not all streams detected!";
ofDrawBitmapStringHighlight(ss.str(), 20, 20);
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
}
//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){
}
//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){
}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){
}