root / trunk / tbeta / Windows / addons / ofxTBeta / Calibration / Calibration.cpp @ 66

View | Annotate | Download (17.6 KB)

1
/*
2
 *  Cali.cpp
3
 *  tbeta
4
 *
5
 *  Created by Artem Titoulenko on 2/1/09.
6
 *  Copyright 2009 NUI Inc.. All rights reserved.
7
 *
8
 */
9
10
#include "Calibration.h"
11
12
/******************************************************************************
13
 * The setup function is run once to perform initializations in the application
14
 *****************************************************************************/
15
void Calibration::setup(int _camWidth, int _camHeight, BlobTracker *trackerIn)
16
{
17
        /********************
18
         * Initalize Variables
19
         *********************/
20
        calibrationParticle.loadImage("images/particle.png");
21
        calibrationParticle.setUseTexture(true);
22
23
    calibrating = false;
24
        bShowTargets = true;
25
        bW                        = false;
26
        bA                        = false;
27
        bS                        = false;
28
        bD                        = false;
29
30
    //Fonts - Is there a way to dynamically change font size?
31
        verdana.loadFont("verdana.ttf", 8, true, true);           //Font used for small images
32
        calibrationText.loadFont("verdana.ttf", 10, true, true);
33
34
        //Load Calibration Settings from calibration.xml file
35
        calibrate.setCamRes(_camWidth, _camHeight);
36
        calibrate.loadXMLSettings();
37
38
        tracker = trackerIn;
39
        tracker->passInCalibration(&calibrate);
40
41
        printf("Calibration is setup!\n");
42
}
43
44
void Calibration::passInContourFinder(int numBlobs, vector<ofxTBetaCvBlob> blobs) {
45
46
    contourFinder.nBlobs = numBlobs;
47
        contourFinder.blobs  = blobs;
48
}
49
50
void Calibration::passInTracker(BlobTracker *trackerIn) {
51
        tracker = trackerIn;
52
        tracker->passInCalibration(&calibrate);
53
}
54
55
56
/******************************
57
 *                  CALIBRATION
58
 *******************************/
59
void Calibration::doCalibration(){
60
61
        //Change the background color to black
62
        ofSetColor(0x000000);
63
        ofFill();
64
        ofRect(0, 0, ofGetWidth(), ofGetHeight());
65
66
    //Draw Calibration Screen
67
    drawCalibrationPointsAndBox();
68
    //Draw blobs in calibration to see where you are touching
69
        if(!calibrate.bCalibrating) drawCalibrationBlobs();
70
71
        /************************************
72
         * Onscreen Calibration Instructions
73
         ************************************/
74
        ofSetColor(0xFF00FF);
75
        //ofSetWindowTitle("Calibration");
76
        char reportStr[10240];
77
        calibrationText.setLineHeight(20.0f);
78
79
        if(calibrate.bCalibrating){
80
                sprintf(reportStr,
81
                                "CALIBRATING: \n\n-Touch current circle target and lift up to calibrate point \n-Press [b] to recapture background (if there's false blobs) \n-Press [r] to go back to previous point(s) \n");
82
                calibrationText.drawString(reportStr, ofGetWidth()/2 - calibrationText.stringWidth(reportStr)/2, ofGetHeight()/2 - calibrationText.stringHeight(reportStr)/2);
83
        }else
84
        {
85
                sprintf(reportStr,
86
                                "CALIBRATION \n\n-Press [c] to start calibrating \n-Press [x] to return main screen \n-Press [b] to recapture background \n-Press [t] to toggle blob targets \n\nCHANGING GRID SIZE (number of points): \n\n-Current Grid Size is %i x %i \n-Press [+]/[-] to add/remove points on X axis \n-Press [shift][+]/[-] to add/remove points on Y axis \n\nALINGING BOUNDING BOX TO PROJECTION SCREEN: \n\n-Use arrow keys to move bounding box\n-Press and hold [w],[a],[s],[d] (top, left, bottom, right) and arrow keys to adjust each side\n", calibrate.GRID_X + 1, calibrate.GRID_Y + 1);
87
                calibrationText.drawString(reportStr, ofGetWidth()/2 - calibrationText.stringWidth(reportStr)/2, ofGetHeight()/2 - calibrationText.stringHeight(reportStr)/2);
88
        }
89
}
90
91
void Calibration::drawCalibrationPointsAndBox(){
92
93
    //Get the screen points so we can make a grid
94
        vector2df *screenpts = calibrate.getScreenPoints();
95
96
        int i;
97
        //For each grid point
98
        for(i=0; i<calibrate.GRID_POINTS; i++)
99
        {
100
                //If calibrating, draw a red circle around the active point
101
                if(calibrate.calibrationStep == i && calibrate.bCalibrating)
102
                {
103
                        glPushMatrix();
104
                        glTranslatef(screenpts[i].X * ofGetWidth(), screenpts[i].Y * ofGetHeight(), 0.0f);
105
                        //draw Circle
106
                        ofFill();
107
                        ofSetColor(downColor);
108
                        ofCircle(0.f, 0.f, 40);
109
                        //Cutout Middle of circle
110
                        ofSetColor(0x000000);
111
                        ofCircle(0.f, 0.f, 25);
112
                        glPopMatrix();
113
                }
114
                ofSetColor(0x00FF00); //Make Plus Sign
115
                ofRect(screenpts[i].X * ofGetWidth() - 2, screenpts[i].Y * ofGetHeight() - 10, 4, 20); //Horizontal Plus
116
                ofRect(screenpts[i].X * ofGetWidth() - 10, screenpts[i].Y * ofGetHeight() - 2, 20, 4); //Vertical Plus
117
        }
118
        //Draw Bounding Box
119
        ofSetColor(0xFFFFFF);
120
        ofNoFill();
121
        ofRect(calibrate.screenBB.upperLeftCorner.X * ofGetWidth(), calibrate.screenBB.upperLeftCorner.Y * ofGetHeight(),
122
                   calibrate.screenBB.getWidth() * ofGetWidth(), calibrate.screenBB.getHeight() * ofGetHeight());
123
}
124
125
void Calibration::drawCalibrationBlobs(){
126
127
    //Find the blobs
128
    for(int i=0; i<contourFinder.nBlobs; i++)
129
    {
130
        //temp blob to rescale and draw on screen
131
        ofxTBetaCvBlob drawBlob2;
132
        drawBlob2 = contourFinder.blobs[i];
133
134
        //transform height/width to calibrated space
135
        calibrate.transformDimension(drawBlob2.boundingRect.width, drawBlob2.boundingRect.height);
136
        drawBlob2.boundingRect.width *= calibrate.screenBB.getWidth() * ofGetWidth() * 4;
137
        drawBlob2.boundingRect.height *= calibrate.screenBB.getHeight() * ofGetHeight() * 4 ;
138
139
        //transform x/y position to calibrated space
140
        calibrate.cameraToScreenPosition(drawBlob2.centroid.x, drawBlob2.centroid.y);
141
142
                //Get a random color for each blob
143
        if(blobcolor[drawBlob2.id] == 0)
144
        {
145
            int r = ofRandom(0, 255);
146
            int g = ofRandom(0, 255);
147
            int b = ofRandom(0, 255);
148
            //Convert to hex
149
            int rgbNum = ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
150
            //Set hex into map position
151
            blobcolor[drawBlob2.id] = rgbNum;
152
        }
153
154
        //Draw Fuzzy Circles
155
        ofEnableAlphaBlending();
156
        ofImage tempCalibrationParticle;
157
        tempCalibrationParticle.clone(calibrationParticle);
158
        ofSetColor(blobcolor[drawBlob2.id]);
159
        tempCalibrationParticle.draw(drawBlob2.centroid.x * ofGetWidth() - drawBlob2.boundingRect.width * .625, drawBlob2.centroid.y * ofGetHeight() - drawBlob2.boundingRect.height * .625,
160
                                                                         drawBlob2.boundingRect.width * 1.25, drawBlob2.boundingRect.height * 1.25);
161
        ofDisableAlphaBlending();
162
163
        //Draw Blob Targets
164
        if(bShowTargets)
165
        {
166
            ofSetColor(0xFFFFFF);
167
            glLineWidth(5);
168
            glPushMatrix();
169
                        //        glLoadIdentity();
170
            glTranslatef(drawBlob2.centroid.x * ofGetWidth(), ((drawBlob2.centroid.y * ofGetHeight())), 0);
171
                        //  ofEllipse(0, 0, drawBlob2.boundingRect.width/2, drawBlob2.boundingRect.height/2);
172
            ofLine(0, -drawBlob2.boundingRect.height/2, 0, drawBlob2.boundingRect.height/2);
173
            ofLine(-drawBlob2.boundingRect.width/2, 0, drawBlob2.boundingRect.width/2, 0);
174
            glPopMatrix();
175
        }
176
177
        //set line width back to normal
178
        glLineWidth(1);
179
180
         // Displat Text of blob information
181
/*                 NOT SURE WE WANT TO KEEP THIS. DON'T THINK IT'S USEFUL
182
183
                 ofSetColor(0xFFFFFF);
184
                 glLineWidth(1);
185
                 char idStr[1024];
186
                 sprintf(idStr, "id: %i \n x: %f \n y: %f",drawBlob2.id, ceil(drawBlob2.centroid.x * ofGetWidth()),
187
                 ceil(drawBlob2.centroid.y * ofGetHeight()));
188
                 verdana.drawString(idStr, drawBlob2.centroid.x * ofGetWidth() - drawBlob2.boundingRect.width/2 + 40,
189
                 drawBlob2.centroid.y * ofGetHeight() - drawBlob2.boundingRect.height/2 + 40);
190
*/
191
    }
192
}
193
194
/*****************************************************************************
195
 * TOUCH EVENTS
196
 *****************************************************************************/
197
void Calibration::RAWTouchDown( ofxTBetaCvBlob b)
198
{
199
        if(calibrate.bCalibrating && contourFinder.nBlobs == 1)//If Calibrating, register the calibration point on blobOff
200
        {
201
                downColor = 0x2FB5FF;
202
        }
203
}
204
205
void Calibration::RAWTouchUp( ofxTBetaCvBlob b)
206
{
207
        if(calibrate.bCalibrating && contourFinder.nBlobs == 1)//If Calibrating, register the calibration point on blobOff
208
        {
209
                if(contourFinder.nBlobs == 1)//If calibrating change target color back when a finger is up
210
                        downColor = 0xFF0000;
211
                
212
                if(calibrate.bGoToNextStep) {
213
                        calibrate.nextCalibrationStep();
214
                        calibrate.bGoToNextStep = false;
215
                        
216
                        if(calibrate.calibrationStep != 0)
217
                                printf("%d (%f, %f)\n", calibrate.calibrationStep, b.centroid.x, b.centroid.y);
218
                        
219
                        if(calibrate.calibrationStep == 0){
220
                                printf("%d (%f, %f)\n", calibrate.GRID_POINTS, b.centroid.x, b.centroid.y);
221
                                printf("Calibration complete\n");
222
                        }
223
                }
224
        }
225
}
226
227
void Calibration::RAWTouchMoved( ofxTBetaCvBlob b)
228
{
229
}
230
231
void Calibration::RAWTouchHeld( ofxTBetaCvBlob b) {
232
        //printf("(%i:%i:%i) %i HELD!!!\n", ofGetHours(), ofGetMinutes(), ofGetSeconds(), b.id);
233
        //ofSetColor(0,b.age/1000*255,6);
234
        //ofFill();
235
        //ofEllipse(b.centroid.x, b.centroid.y, 20,20);
236
        
237
        if(calibrate.bCalibrating && contourFinder.nBlobs == 1)//If Calibrating, register the calibration point on blobOff
238
        {
239
                calibrate.cameraPoints[calibrate.calibrationStep] = vector2df(b.centroid.x, b.centroid.y);
240
                calibrate.bGoToNextStep = true;
241
                downColor = 0xFFFFFF;
242
        }
243
244
}
245
246
247
/*****************************************************************************
248
 * KEY EVENTS
249
 *****************************************************************************/
250
void Calibration::keyPressed(int key) {
251
252
        if(calibrating)
253
        {
254
        switch(key)
255
        {
256
            case 't':
257
                bShowTargets ? bShowTargets = false : bShowTargets = true;
258
                break;
259
                /***********************
260
                 * Keys for Calibration
261
                 ***********************/
262
            case 'c': //Enter/Exit Calibration
263
                if(calibrate.bCalibrating) {
264
                    calibrate.bCalibrating = false;
265
                    printf("Calibration Stoped\n");
266
                                } else {
267
                                        calibrate.beginCalibration();
268
                    printf("Calibration Started\n");
269
                                }
270
                break;
271
            case 'r': //Revert Calibration
272
                if(calibrate.bCalibrating)calibrate.revertCalibrationStep();
273
                break;
274
            case 'a': //Left
275
                bA = true;
276
                break;
277
            case 'd': //Right
278
                bD = true;
279
                break;
280
            case 'w': //Right
281
                bW = true;
282
                break;
283
            case 's': //Right
284
                bS = true;
285
                break;
286
            case OF_KEY_RIGHT: //Move bounding box right
287
                if(bD){
288
                    calibrate.screenBB.lowerRightCorner.X += .001;
289
                    if(calibrate.screenBB.lowerRightCorner.X > 1) calibrate.screenBB.lowerRightCorner.X = 1;
290
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
291
                    calibrate.calibrationStep = 0;
292
                }else if(bA){
293
                    calibrate.screenBB.upperLeftCorner.X += .001;
294
                    if(calibrate.screenBB.upperLeftCorner.X > 1) calibrate.screenBB.upperLeftCorner.X = 1;
295
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
296
                    calibrate.calibrationStep = 0;
297
                }else{
298
                    calibrate.screenBB.lowerRightCorner.X += .001;
299
                    if(calibrate.screenBB.lowerRightCorner.X > 1) calibrate.screenBB.lowerRightCorner.X = 1;
300
                    calibrate.screenBB.upperLeftCorner.X += .001;
301
                    if(calibrate.screenBB.upperLeftCorner.X > 1) calibrate.screenBB.upperLeftCorner.X = 1;
302
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
303
                    calibrate.calibrationStep = 0;
304
                }
305
                break;
306
            case OF_KEY_LEFT: //Move bounding box left
307
                if(bD){
308
                    calibrate.screenBB.lowerRightCorner.X -= .001;
309
                    if(calibrate.screenBB.lowerRightCorner.X < 0) calibrate.screenBB.lowerRightCorner.X = 0;
310
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
311
                    calibrate.calibrationStep = 0;
312
                }else if(bA){
313
                    calibrate.screenBB.upperLeftCorner.X -= .001;
314
                    if(calibrate.screenBB.upperLeftCorner.X < 0) calibrate.screenBB.upperLeftCorner.X = 0;
315
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
316
                    calibrate.calibrationStep = 0;
317
                }else{
318
                    calibrate.screenBB.lowerRightCorner.X -= .001;
319
                    if(calibrate.screenBB.lowerRightCorner.X < 0) calibrate.screenBB.lowerRightCorner.X = 0;
320
                    calibrate.screenBB.upperLeftCorner.X -= .001;
321
                    if(calibrate.screenBB.upperLeftCorner.X < 0) calibrate.screenBB.upperLeftCorner.X = 0;
322
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
323
                    calibrate.calibrationStep = 0;
324
                }
325
                break;
326
            case OF_KEY_DOWN: //Move bounding box down
327
                if(bS){
328
                    calibrate.screenBB.lowerRightCorner.Y += .001;
329
                    if(calibrate.screenBB.lowerRightCorner.Y > 1) calibrate.screenBB.lowerRightCorner.Y = 1;
330
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
331
                    calibrate.calibrationStep = 0;
332
                }else if(bW){
333
                    calibrate.screenBB.upperLeftCorner.Y += .001;
334
                    if(calibrate.screenBB.upperLeftCorner.Y > 1) calibrate.screenBB.upperLeftCorner.Y = 1;
335
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
336
                    calibrate.calibrationStep = 0;
337
                }else{
338
                    calibrate.screenBB.lowerRightCorner.Y += .001;
339
                    if(calibrate.screenBB.lowerRightCorner.Y > 1) calibrate.screenBB.lowerRightCorner.Y = 1;
340
                    calibrate.screenBB.upperLeftCorner.Y += .001;
341
                    if(calibrate.screenBB.upperLeftCorner.Y > 1) calibrate.screenBB.upperLeftCorner.Y = 1;
342
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
343
                    calibrate.calibrationStep = 0;
344
                }
345
                break;
346
            case OF_KEY_UP: //Move bounding box up
347
                if(bS){
348
                    calibrate.screenBB.lowerRightCorner.Y -= .001;
349
                    if(calibrate.screenBB.lowerRightCorner.Y < 0) calibrate.screenBB.lowerRightCorner.Y = 0;
350
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
351
                    calibrate.calibrationStep = 0;
352
                }else if(bW){
353
                    calibrate.screenBB.upperLeftCorner.Y -= .001;
354
                    if(calibrate.screenBB.upperLeftCorner.Y < 0) calibrate.screenBB.upperLeftCorner.Y = 0;
355
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
356
                    calibrate.calibrationStep = 0;
357
                }else{
358
                    calibrate.screenBB.lowerRightCorner.Y -= .001;
359
                    if(calibrate.screenBB.lowerRightCorner.Y < 0) calibrate.screenBB.lowerRightCorner.Y = 0;
360
                    calibrate.screenBB.upperLeftCorner.Y -= .001;
361
                    if(calibrate.screenBB.upperLeftCorner.Y < 0) calibrate.screenBB.upperLeftCorner.Y = 0;
362
                    calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
363
                    calibrate.calibrationStep = 0;
364
                }
365
                break;
366
                //Start Grid Point Changing
367
            case '=':
368
                calibrate.GRID_X ++;
369
                if(calibrate.GRID_X > 16) calibrate.GRID_X = 16; calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
370
                calibrate.calibrationStep = 0;
371
                break;
372
            case '-':
373
                calibrate.GRID_X --;
374
                if(calibrate.GRID_X < 1) calibrate.GRID_X = 1; calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
375
                calibrate.calibrationStep = 0;
376
                break;
377
            case '+':
378
                calibrate.GRID_Y ++;
379
                if(calibrate.GRID_Y > 16) calibrate.GRID_Y = 16; calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
380
                calibrate.calibrationStep = 0;
381
                break;
382
            case '_':
383
                calibrate.GRID_Y --;
384
                if(calibrate.GRID_Y < 1) calibrate.GRID_Y = 1; calibrate.setGrid(calibrate.GRID_X, calibrate.GRID_Y);
385
                calibrate.calibrationStep = 0;
386
                break;
387
        }
388
    }
389
}
390
391
void Calibration::keyReleased(int key){
392
393
        if(calibrating)
394
        {
395
                switch(key)
396
                {
397
                        case 'w':
398
                                bW = false;
399
                                break;
400
                        case 's':
401
                                bS = false;
402
                                break;
403
                        case 'a':
404
                                bA = false;
405
                                break;
406
                        case 'd':
407
                                bD = false;
408
                                break;
409
                        case '/':
410
                                if(calibrating) {
411
                                        ofxTBetaCvBlob tempBlob;
412
                                        tempBlob.centroid.x = mouseX;
413
                                        tempBlob.centroid.y = mouseY;
414
                                        tempBlob.simulated = true;
415
                                        RAWTouchDown(tempBlob);
416
                                }
417
                                break;
418
            case 'x': //Begin Calibrating
419
                tracker->passInCalibration(&calibrate);
420
                break;
421
                        case OF_KEY_RIGHT: //Move bounding box right
422
                calibrate.computeCameraToScreenMap();
423
                tracker->passInCalibration(&calibrate);
424
                break;
425
            case OF_KEY_LEFT: //Move bounding box left
426
                calibrate.computeCameraToScreenMap();
427
                tracker->passInCalibration(&calibrate);
428
                break;
429
            case OF_KEY_DOWN: //Move bounding box down
430
                calibrate.computeCameraToScreenMap();
431
                tracker->passInCalibration(&calibrate);
432
                break;
433
            case OF_KEY_UP: //Move bounding box up
434
                calibrate.computeCameraToScreenMap();
435
                tracker->passInCalibration(&calibrate);
436
                break;
437
                }
438
        }
439
}
440
441
/*****************************************************************************
442
 *        MOUSE EVENTS
443
 *****************************************************************************/
444
void Calibration::mouseMoved(int x, int y)
445
{
446
}
447
448
void Calibration::mouseDragged(int x, int y, int button)
449
{
450
}
451
452
void Calibration::mousePressed(int x, int y, int button)
453
{
454
455
}
456
457
void Calibration::mouseReleased()
458
{
459
460
}