Revision 56

trunk/tbeta/Windows/addons/ofxTBeta/TBetaBase.h (revision 56)
25 25

26 26
#include "Filters/CPUImageFilter.h"
27 27

28
#include "Camera/Camera.h"
29

30 28
#include "Calibration/Calibration.h"
31 29

32 30
//#include "ConfigurationApp.h"
33

34
class Camera
35
	{
36
	public:
37
		
38
		Camera();
39
		~Camera();
40
		
41
		void grabFrameToCPU();
42
		void grabFrameToGPU(GLuint target);
43
		
44
		int					deviceID;
45
		int 				camRate;
46
		int 				camWidth;
47
		int 				camHeight;
48
		
49
		bool				bcamera;
50
		
51
		ofxCvColorImage		sourceImg;
52
		
53
		/***************************************************************
54
		 *						Video Settings
55
		 ***************************************************************/
56
		ofVideoGrabber 		vidGrabber;
57
		ofVideoPlayer 		vidPlayer;
58
	};	
59

31

32
#include "ofxTouchAdaptiveFilter.h"
33

60 34
class TBetaBase : public ofSimpleApp, public ofxGuiListener, public TouchListener//, public BlobManager
61 35
	{
62 36
		//ofxGUI setup stuff
......
118 92
			TouchEvents.addListener(this);
119 93
			showConfiguration = false;
120 94
		}
121
		
122
		Camera camera;
123 95

124 96
		/****************************************************************
125 97
		 *						Public functions
126 98
		 ****************************************************************/
127

128 99
		//Basic Methods
129 100
		void setup();
130 101
		void update();
......
151 122
		void TouchUp( ofxTBetaCvBlob b );
152 123

153 124
		//image processing stuff
154
		//void grabFrameToCPU(); //moved to Camera.h
155
		void applyImageFilters();
125
		void grabFrameToCPU();
126
		void grabFrameToGPU(GLuint target);
156 127

157
		//void grabFrameToGPU(GLuint target); //moved to Camera.h
158
		void applyGPUImageFilters();
159
		void resetGPUTextures();
160

161
		void bgCapture(ofxCvGrayscaleImage & _giLive);        //Background Capture
162
	    void learnBackground( ofxCvGrayscaleImage & _giLive,  //Background Learn (bgCapture and dynamic Bg subtraction
163
							 ofxCvGrayscaleImage & _grayBg,
164
							 ofxCvFloatImage & _fiLearn,
165
							 float _fLearnRate );
166

167 128
		void drawToScreen();
168 129
		void drawFingerOutlines();
169 130

170 131
		//Other Methods
171 132
		void loadXMLSettings();								  // Load Settings
172 133
		void saveConfiguration();
173
		
174
		
175
		
176
		
177
		/****************************************************************
178
		 *							Video Crap
179
		 *****************************************************************/
180
		//ofVideoPlayer 		vidPlayer; //this and grabber are in Camera.h
181
		
182
		
183 134

135
		/***************************************************************
136
		 *						Video Settings
137
		 ***************************************************************/
138
		ofVideoGrabber 		vidGrabber;
139
		ofVideoPlayer 		vidPlayer;
140

184 141
		/****************************************************************
185 142
		 *            Variables in config.xml Settings file
186 143
		 *****************************************************************/
187

188
	    //int					deviceID; //moved to Camera.h
144
	    int					deviceID;
189 145
		int 				frameseq;
190 146
		int 				threshold;
191
		int 				blurValue;
192
		int 				blurGaussianValue;
193 147
		int					wobbleThreshold;
194
		//int 				camRate;   //moved
195
		//int 				camWidth;  //to
196
		//int 				camHeight; //Camera.h
148
		int 				camRate;
149
		int 				camWidth;
150
		int 				camHeight;
197 151
		int					winWidth;
198 152
		int					winHeight;
199 153
		int					minWidth;
200
		int					minHeight;
201
		int					highpassBlur;
202
		int					highpassNoise;
203
		int					highpassAmp;
204
		int					smooth;
154
		int					minHeight;
205 155

206 156
		bool				showConfiguration;
207 157

208
		//bool				bcamera; //moved to Camera.h
158
		bool				bcamera;
209 159
		bool				bDrawVideo;
210 160
		bool  				bFastMode;
211 161
		bool				bShowInterface;
212 162
		bool				bShowPressure;
213
		bool				bLearnBakground;
214
		bool				bInvertVideo;
215 163
		bool				bDrawOutlines;
216 164
		bool				bTUIOMode;
217 165
		bool  				bFullscreen;
......
220 168
		bool				bHorizontalMirror;
221 169
		bool				bShowLabels;
222 170
		bool				bNewFrame;
223

224 171
		//filters
225
		bool				bHighpass;
226
		bool				bAmplify;
227
		bool				bThreshold;
228
		bool				bSmooth;
229
		bool				bDynamicBG;
230 172
		bool				bAutoBackground;
231

232 173
		//modes
233 174
		bool				bGPUMode;
234 175

235 176
		/****************************************************
236 177
		 *End config.xml variables
237 178
		 *****************************************************/
238

239 179
		bool				activeInput;
240 180

241
		float				fLearnRate;// rate to learn background
242

243 181
		//FPS variables
244 182
		int 					frames;
245 183
		int  					fps;
......
259 197
		BlobTracker			tracker;
260 198

261 199
        string				tmpLocalHost;
262
        int					tmpPort;
200
        int					tmpPort;
201

202
        //---------------------------------------Blob Tracker
203
        ofxTouchFilter*  filter;
263 204

264

265 205
        /****************************************************************
266 206
		 *						Private Stuff
267
		 ****************************************************************/
268

207
    	 ****************************************************************/
269 208
		string videoFileName;
270 209
		int	maxBlobs;
271 210

......
276 215

277 216
		//---------------------------------------Images
278 217
 		CPUImageFilter      processedImg;
218
		ofxCvColorImage		sourceImg;
279 219

280
		//ofxCvColorImage		sourceImg; //moved to Camera.h
281
        ofxCvGrayscaleImage grayImg;
282
		ofxCvGrayscaleImage grayBg;
283
		ofxCvGrayscaleImage subtractBg;
284
		ofxCvGrayscaleImage grayDiff;
285
		ofxCvGrayscaleImage highpassImg;
286
		ofxCvGrayscaleImage ampImg;
287

288
		//---------------------------------------Pressure Map
289
		ofxCvColorImage		pressureMap;
290

291
		//---------------------------------------Background Subtraction
292
	    ofxCvFloatImage		fiLearn;
293

294 220
		//---------------------------------------XML Settings Vars (BLOATED)
295 221
		ofxXmlSettings		XML;
296 222
		string				message;
297 223

298 224
		//---------------------------------------FOR NETWORK
299 225
		TUIOOSC				myTUIO;
300

301
		//---------------------------------------FOR gpuTracker
302
		GLuint			gpuSourceTex;
303
		GLuint			gpuBGTex;
304

305
		unsigned char * gpuReadBackBuffer;
306
		ofxCvColorImage gpuReadBackImage;
307
		ofxCvGrayscaleImage gpuReadBackImageGS;
308

309
		ImageFilter*	contrastFilter;
310
		ImageFilter*	subtractFilter;
311
		ImageFilter*	subtractFilter2; //we need 2 because we are showing the output of each
312
		ImageFilter*	gaussVFilter;
313
		ImageFilter*	gaussVFilter2;
314
		ImageFilter*	gaussHFilter;
315
		ImageFilter*	gaussHFilter2;
316
		ImageFilter*	threshFilter;
317 226
	};
318 227

319 228
#endif
trunk/tbeta/Windows/addons/ofxTBeta/ofxTouchAdaptiveFilter.h (revision 56)
1
/*
2
* Copyright 2008 NOR_/D <http://nortd.com>
3
*
4
* * *
5
* The default filter.
6
*/
7

8
#ifndef OFX_TOUCHADAPTIVEFILTER
9
#define OFX_TOUCHADAPTIVEFILTER
10

11
#include "ofxTouchFilter.h"
12

13
class ofxTouchAdaptiveFilter : public ofxTouchFilter {
14

15
  public:
16

17
    void allocate( int w, int h ) {
18

19
        camWidth = w;
20
        camHeight = h;
21

22
        exposureStartTime = ofGetElapsedTimeMillis();
23

24
        //CPU Setup
25
        grayImg.allocate(camWidth, camHeight);		//Gray Image
26
        grayBg.allocate(camWidth, camHeight);		//Background Image
27
        subtractBg.allocate(camWidth, camHeight);   //Background After subtraction
28
        grayDiff.allocate(camWidth, camHeight);		//Difference Image between Background and Source
29
        highpassImg.allocate(camWidth, camHeight);  //Highpass Image
30
        ampImg.allocate(camWidth, camHeight);		//Amplied Image
31
        fiLearn.allocate(camWidth, camHeight);		//ofxFloatImage used for simple dynamic background subtraction
32

33
        //GPU Setup
34
        allocateGPU();
35
    }
36

37
    void allocateGPU(){
38

39
        glGenTextures(1, &gpuSourceTex);
40
        glGenTextures(1, &gpuBGTex);
41

42
        delete gpuReadBackBuffer;
43

44
        gpuReadBackBuffer = new unsigned char[camWidth*camHeight*3];
45
        gpuReadBackImage.allocate(camWidth, camHeight);
46
        gpuReadBackImageGS.allocate(camWidth, camHeight);
47

48
        glEnable(GL_TEXTURE_2D);
49
        glBindTexture(GL_TEXTURE_2D, gpuSourceTex);
50
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  camWidth, camHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
51
        glBindTexture(GL_TEXTURE_2D, gpuBGTex);
52
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  camWidth, camHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
53
        glBindTexture(GL_TEXTURE_2D, 0);
54
        glDisable(GL_TEXTURE_2D);
55

56
        subtractFilter = new ImageFilter("filters/absSubtract.xml", camWidth, camHeight);
57
        subtractFilter2 = new ImageFilter("filters/subtract.xml", camWidth, camHeight);
58
        contrastFilter = new ImageFilter("filters/contrast.xml", camWidth, camHeight);
59
        gaussVFilter = new ImageFilter("filters/gaussV.xml", camWidth, camHeight);
60
        gaussHFilter = new ImageFilter("filters/gauss.xml", camWidth, camHeight);
61
        gaussVFilter2 = new ImageFilter("filters/gaussV2.xml", camWidth, camHeight);
62
        gaussHFilter2 = new ImageFilter("filters/gauss2.xml", camWidth, camHeight);
63
        threshFilter = new ImageFilter("filters/threshold.xml", camWidth, camHeight);
64
        copyFilter = new ImageFilter("filters/copy.xml", camWidth, camHeight);
65
    }
66

67

68
     void applyCPUFilters(CPUImageFilter& img){
69

70
        //Set Mirroring Horizontal/Vertical
71
        if(bVerticalMirror || bHorizontalMirror) img.mirror(bVerticalMirror, bHorizontalMirror);
72

73
        //if(!bFastMode)
74
        grayImg = img; //for drawing
75

76
        //Dynamic background with learn rate...eventually learnrate will have GUI sliders
77
        if(bDynamicBG){
78
            learnBackground( img, grayBg, fiLearn, fLearnRate);
79
        }
80

81
        //recapature the background for 2 seconds to make sure the background image is when the camera is fully loaded
82
        if((ofGetElapsedTimeMillis() - exposureStartTime) < CAMERA_EXPOSURE_TIME) bLearnBakground = true;
83

84
        //Capture full background
85
        if (bLearnBakground == true){
86

87
            learnBackground( img, grayBg, fiLearn, 1.0f);
88

89
            bLearnBakground = false;
90
        }
91

92
        img.absDiff(grayBg, img); //Background Subtraction
93

94
        if(bSmooth){//Smooth
95
            img.blur((smooth * 2) + 1); //needs to be an odd number
96
            //if(!bFastMode)
97
            subtractBg = img; //for drawing
98
        }
99

100
        if(bHighpass){//HighPass
101
            img.highpass(highpassBlur, highpassNoise);
102
            //if(!bFastMode)
103
            highpassImg = img; //for drawing
104
        }
105

106
        if(bAmplify){//Amplify
107
            img.amplify(img, highpassAmp);
108
            //if(!bFastMode)
109
            ampImg = img; //for drawing
110
        }
111

112
        img.threshold(threshold); //Threshold
113
        //if(!bFastMode)
114
        grayDiff = img; //for drawing
115
    }
116

117
    void learnBackground( ofxCvGrayscaleImage& live, ofxCvGrayscaleImage& _grayBg, ofxCvFloatImage& fLearn, float learnRate )
118
    {
119
        fLearn.addWeighted( live, learnRate);
120
        _grayBg = fLearn;
121
    }
122

123
    void applyGPUFilters(){
124

125
        if((ofGetElapsedTimeMillis() - exposureStartTime) < CAMERA_EXPOSURE_TIME) bLearnBakground = true;
126

127
        if (bLearnBakground == true){
128

129
            gpuBGTex = copyFilter->apply(gpuSourceTex, gpuBGTex);
130
            bLearnBakground = false;
131
        }
132

133
        GLuint processedTex;
134

135
        processedTex = subtractFilter->apply(gpuSourceTex, gpuBGTex);
136

137
        if(bSmooth){//Smooth
138
            gaussHFilter->parameters["kernel_size"]->value = (float)smooth;
139
            gaussVFilter->parameters["kernel_size"]->value = (float)smooth;
140
            processedTex = gaussHFilter->apply(processedTex);
141
            processedTex = gaussVFilter->apply(processedTex);
142
        }
143

144
        if(bHighpass){//Highpass
145
            gaussHFilter2->parameters["kernel_size"]->value = (float)highpassBlur;
146
            gaussVFilter2->parameters["kernel_size"]->value = (float)highpassBlur;
147
            processedTex = gaussHFilter2->apply(processedTex);
148
            processedTex = gaussVFilter2->apply(processedTex);
149
            processedTex = subtractFilter2->apply(gaussVFilter->output_texture, processedTex);
150
        }
151

152
        if(bAmplify){}//amplify
153

154
        threshFilter->parameters["Threshold"]->value = (float)threshold / 255.0; //threshold
155
        threshFilter->apply(processedTex);
156

157
        //until the rest of the pipeline is fixed well just download the preprocessing result from the gpu and use that for the blob detection
158
        //TODO: make this part not super slow ;)
159
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, threshFilter->output_buffer);
160
        glReadPixels(0,0,camWidth, camHeight, GL_RGB, GL_UNSIGNED_BYTE, gpuReadBackBuffer);
161
        gpuReadBackImage.setFromPixels(gpuReadBackBuffer, camWidth, camHeight);
162
        gpuReadBackImageGS = gpuReadBackImage;
163
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
164
    }
165

166
    void draw()
167
    {
168
        grayImg.draw(40, 30, 320, 240);
169
        grayDiff.draw(385, 30, 320, 240);
170
        fiLearn.draw(85, 392, 128, 96);
171
        subtractBg.draw(235, 392, 128, 96);
172
        highpassImg.draw(385, 392, 128, 96);
173
        ampImg.draw(535, 392, 128, 96);
174
//      ofSetColor(0x000000);
175
//      bigvideo.drawString("Source Image", 140, 20);
176
//		bigvideo.drawString("Tracked Image", 475, 20);
177
    }
178

179
    void drawGPU()
180
    {
181
        drawGLTexture(40, 30, 320, 240, gpuSourceTex);
182
        drawGLTexture(85, 392, 128, 96, gpuBGTex);
183
        gaussVFilter->drawOutputTexture(235, 392, 128, 96);
184
        subtractFilter2->drawOutputTexture(385, 392, 128, 96);
185
        threshFilter->drawOutputTexture(535, 392, 128, 96);
186
        gpuReadBackImageGS.draw(385, 30, 320, 240);
187
    }
188
};
189
#endif
trunk/tbeta/Windows/addons/ofxTBeta/gui.h (revision 56)
9 9
{
10 10
	appPtr = this;
11 11

12
	//if(!gui->buildFromXml(OFXGUI_XML))
13
	//{
14 12
		//panel border color
15 13
		gui->mGlobals->mBorderColor.r = 0;
16 14
		gui->mGlobals->mBorderColor.g = 0;
......
46 44
		gui->mGlobals->mSliderColor.b = 0;
47 45
		gui->mGlobals->mSliderColor.a = .8;
48 46

49

50

51

52 47
		ofxGuiPanel* propPanel = gui->addPanel(appPtr->propertiesPanel, "Source Properties", 735, 10, 12, OFXGUI_PANEL_SPACING);
53 48
		propPanel->addButton(appPtr->propertiesPanel_settings, "Camera Settings (v)", OFXGUI_BUTTON_HEIGHT, OFXGUI_BUTTON_HEIGHT, kofxGui_Button_Off, kofxGui_Button_Trigger, "");
54 49
		propPanel->addButton(appPtr->propertiesPanel_flipV, "Flip Vertical (j)", OFXGUI_BUTTON_HEIGHT, OFXGUI_BUTTON_HEIGHT, kofxGui_Button_Off, kofxGui_Button_Switch, "");
......
68 63
		cPanel->mObjWidth = 200;
69 64

70 65
		ofxGuiPanel* panel2 = gui->addPanel(appPtr->savePanel, "files", 735, 303, OFXGUI_PANEL_BORDER, OFXGUI_PANEL_SPACING);
71
		//savePanel->addFiles(kParameter_File, "files", 110, OFXGUI_FILES_HEIGHT, "", "", "xml");
72 66
		panel2->addButton(appPtr->kParameter_SaveXml, "Save Settings (s)", OFXGUI_BUTTON_HEIGHT, OFXGUI_BUTTON_HEIGHT, kofxGui_Button_Off, kofxGui_Button_Trigger, "");
73 67
		panel2->mObjWidth = 200;
74 68

......
76 70
		ofxGuiPanel* trackPanel = gui->addPanel(appPtr->trackedPanel, "Tracked Image", 386, 270, OFXGUI_PANEL_BORDER, OFXGUI_PANEL_SPACING);
77 71
		trackPanel->addButton(appPtr->trackedPanel_outlines, "Show Outlines (o)", OFXGUI_BUTTON_HEIGHT, OFXGUI_BUTTON_HEIGHT, kofxGui_Button_Off, kofxGui_Button_Switch, "");
78 72
		trackPanel->addButton(appPtr->trackedPanel_ids, "Show IDs (i)", OFXGUI_BUTTON_HEIGHT, OFXGUI_BUTTON_HEIGHT, kofxGui_Button_Off, kofxGui_Button_Switch, "");
79
		trackPanel->addSlider(appPtr->trackedPanel_threshold, "Threshold (a/z)", 300, 13, 0.0f, 255.0f, threshold, kofxGui_Display_Int, 0);
73
		trackPanel->addSlider(appPtr->trackedPanel_threshold, "Threshold (a/z)", 300, 13, 0.0f, 255.0f, filter->threshold, kofxGui_Display_Int, 0);
80 74
		trackPanel->mObjHeight = 85;
81 75
		trackPanel->mObjWidth = 319;
82 76
		trackPanel->mObjects[1]->mObjX = 130;
......
108 102
		//Smooth Image
109 103
		ofxGuiPanel* sPanel = gui->addPanel(appPtr->smoothPanel, "Smooth", 236, 487, 10, 7);
110 104
		sPanel->addButton(smoothPanel_use, "", 12, 12, kofxGui_Button_Off, kofxGui_Button_Switch, "");
111
		sPanel->addSlider(smoothPanel_smooth, "Smooth", 110, 13, 0.0f, 15.0f, smooth, kofxGui_Display_Int, 0);
105
		sPanel->addSlider(smoothPanel_smooth, "Smooth", 110, 13, 0.0f, 15.0f, filter->smooth, kofxGui_Display_Int, 0);
112 106
		sPanel->mObjects[0]->mObjX = 105;
113 107
		sPanel->mObjects[0]->mObjY = 10;
114 108
		sPanel->mObjects[1]->mObjY = 30;
......
118 112
		//Highpass Image
119 113
		ofxGuiPanel* hpPanel = gui->addPanel(appPtr->highpassPanel, "Highpass", 386, 487, OFXGUI_PANEL_BORDER, 7);
120 114
		hpPanel->addButton(highpassPanel_use, "", 12, 12, kofxGui_Button_Off, kofxGui_Button_Switch, "");
121
		hpPanel->addSlider(highpassPanel_blur, "Blur", 110, 13, 0.0f, 200.0f, highpassBlur, kofxGui_Display_Int, 0);
122
		hpPanel->addSlider(highpassPanel_noise, "Noise", 110, 13, 0.0f, 30.0f, highpassNoise, kofxGui_Display_Int, 0);
115
		hpPanel->addSlider(highpassPanel_blur, "Blur", 110, 13, 0.0f, 200.0f, filter->highpassBlur, kofxGui_Display_Int, 0);
116
		hpPanel->addSlider(highpassPanel_noise, "Noise", 110, 13, 0.0f, 30.0f, filter->highpassNoise, kofxGui_Display_Int, 0);
123 117
		hpPanel->mObjects[0]->mObjX = 105;
124 118
		hpPanel->mObjects[0]->mObjY = 10;
125 119
		hpPanel->mObjects[1]->mObjY = 30;
......
127 121
		hpPanel->mObjWidth = 127;
128 122
		hpPanel->mObjHeight = 95;
129 123

130

131 124
		//Amplify Image
132 125
		ofxGuiPanel* ampPanel = gui->addPanel(appPtr->amplifyPanel, "Amplify", 536, 487, OFXGUI_PANEL_BORDER, 7);
133 126
		ampPanel->addButton(amplifyPanel_use, "", 12, 12, kofxGui_Button_Off, kofxGui_Button_Switch, "");
134
		ampPanel->addSlider(amplifyPanel_amp, "Amplify", 110, 13, 0.0f, 300.0f, highpassAmp, kofxGui_Display_Int, 0);
127
		ampPanel->addSlider(amplifyPanel_amp, "Amplify", 110, 13, 0.0f, 300.0f, filter->highpassAmp, kofxGui_Display_Int, 0);
135 128
		ampPanel->mObjects[0]->mObjX = 105;
136 129
		ampPanel->mObjects[0]->mObjY = 10;
137 130
		ampPanel->mObjects[1]->mObjY = 30;
......
141 134
		//do update while inactive
142 135
		gui->forceUpdate(false);
143 136
		gui->activate(true);
144
	//}
137

145 138
		/****************************
146 139
		* Set GUI values on startup
147 140
		****************************/
......
150 143
		gui->update(appPtr->trackedPanel_outlines, kofxGui_Set_Bool, &appPtr->bDrawOutlines, sizeof(bool));
151 144
		gui->update(appPtr->trackedPanel_ids, kofxGui_Set_Bool, &appPtr->bShowLabels, sizeof(bool));
152 145
		//Source
153
		gui->update(appPtr->sourcePanel_cam, kofxGui_Set_Bool, &appPtr->camera.bcamera, sizeof(bool));
154
		if(!camera.bcamera){
146
		gui->update(appPtr->sourcePanel_cam, kofxGui_Set_Bool, &appPtr->bcamera, sizeof(bool));
147
		if(!bcamera){
155 148
		bool bvideo = true;
156 149
		gui->update(appPtr->sourcePanel_video, kofxGui_Set_Bool, &bvideo, sizeof(bool));
157 150
		}
158 151
		//Calibration
159 152
		gui->update(appPtr->calibrationPanel_calibrate, kofxGui_Set_Bool, &appPtr->bCalibration, sizeof(bool));
160 153
		//Dynamic Background
161
		gui->update(appPtr->backgroundPanel_dynamic, kofxGui_Set_Bool, &appPtr->bDynamicBG, sizeof(bool));
154
		gui->update(appPtr->backgroundPanel_dynamic, kofxGui_Set_Bool, &appPtr->filter->bDynamicBG, sizeof(bool));
162 155
		//Smooth
163
		gui->update(appPtr->smoothPanel_use, kofxGui_Set_Bool, &appPtr->bSmooth, sizeof(bool));
164
		gui->update(appPtr->smoothPanel_smooth, kofxGui_Set_Bool, &appPtr->smooth, sizeof(float));
156
		gui->update(appPtr->smoothPanel_use, kofxGui_Set_Bool, &appPtr->filter->bSmooth, sizeof(bool));
157
		gui->update(appPtr->smoothPanel_smooth, kofxGui_Set_Bool, &appPtr->filter->smooth, sizeof(float));
165 158
		//Highpass
166
		gui->update(appPtr->highpassPanel_use, kofxGui_Set_Bool, &appPtr->bHighpass, sizeof(bool));
167
		gui->update(appPtr->highpassPanel_blur, kofxGui_Set_Bool, &appPtr->highpassBlur, sizeof(float));
168
		gui->update(appPtr->highpassPanel_noise, kofxGui_Set_Bool, &appPtr->highpassNoise, sizeof(float));
159
		gui->update(appPtr->highpassPanel_use, kofxGui_Set_Bool, &appPtr->filter->bHighpass, sizeof(bool));
160
		gui->update(appPtr->highpassPanel_blur, kofxGui_Set_Bool, &appPtr->filter->highpassBlur, sizeof(float));
161
		gui->update(appPtr->highpassPanel_noise, kofxGui_Set_Bool, &appPtr->filter->highpassNoise, sizeof(float));
169 162
		//Amplify
170
		gui->update(appPtr->amplifyPanel_use, kofxGui_Set_Bool, &appPtr->bAmplify, sizeof(bool));
171
		gui->update(appPtr->amplifyPanel_amp, kofxGui_Set_Bool, &appPtr->highpassAmp, sizeof(float));
163
		gui->update(appPtr->amplifyPanel_use, kofxGui_Set_Bool, &appPtr->filter->bAmplify, sizeof(bool));
164
		gui->update(appPtr->amplifyPanel_amp, kofxGui_Set_Bool, &appPtr->filter->highpassAmp, sizeof(float));
172 165
		//Threshold
173
		gui->update(appPtr->trackedPanel_threshold, kofxGui_Set_Bool, &appPtr->threshold, sizeof(float));
166
		gui->update(appPtr->trackedPanel_threshold, kofxGui_Set_Bool, &appPtr->filter->threshold, sizeof(float));
174 167
		//Send TUIO
175 168
		gui->update(appPtr->optionPanel_tuio, kofxGui_Set_Bool, &appPtr->bTUIOMode, sizeof(bool));
176 169
		//GPU Mode
......
188 181
				{
189 182
					if(*(bool*)data)
190 183
					{
191
						if(!camera.bcamera){
184
						if(!bcamera){
192 185
							activeInput = false; //this stops the app from doing everything when changing source
193
							camera.bcamera = true;
194
							camera.vidGrabber.close();
195
							camera.vidGrabber.setDeviceID(camera.deviceID);
196
							camera.vidGrabber.setVerbose(false);
197
							camera.camWidth = camera.vidGrabber.width;
198
							camera.camHeight = camera.vidGrabber.height;
199
							camera.vidGrabber.initGrabber(camera.camWidth,camera.camHeight);
200

201
//							calibrate.setCamRes(camera.camHeight, camera.camWidth);
186
							bcamera = true;
187
							vidGrabber.close();
188
							vidGrabber.setDeviceID(deviceID);
189
							vidGrabber.setVerbose(false);
190
							camWidth = vidGrabber.width;
191
							camHeight = vidGrabber.height;
192
							vidGrabber.initGrabber(camWidth,camHeight);
193
//							calibrate.setCamRes(camHeight, camWidth);
202 194
//							calibrate.computeCameraToScreenMap();
203 195

204 196
							//reset gpu textures and filters
205
							resetGPUTextures();
206

207
							processedImg.allocate(camera.camWidth, camera.camHeight); //Processed Image
197
							processedImg.allocate(camWidth, camHeight); //Processed Image
208 198
							processedImg.setUseTexture(false);
209
							camera.sourceImg.allocate(camera.camWidth, camera.camHeight);    //Source Image
210
							camera.sourceImg.setUseTexture(false);
211
							grayImg.allocate(camera.camWidth, camera.camHeight);		//Gray Image
212
							grayBg.allocate(camera.camWidth, camera.camHeight);		//Background Image
213
							subtractBg.allocate(camera.camWidth, camera.camHeight);   //Background After subtraction
214
							grayDiff.allocate(camera.camWidth, camera.camHeight);		//Difference Image between Background and Source
215
							highpassImg.allocate(camera.camWidth, camera.camHeight);  //Highpass Image
216
							ampImg.allocate(camera.camWidth, camera.camHeight);		//Amplify Image
217
							fiLearn.allocate(camera.camWidth, camera.camHeight);		//ofxFloatImage used for simple dynamic background subtracti
218
							pressureMap.allocate(camera.camWidth, camera.camHeight);	//Pressure Map Image
219

199
							sourceImg.allocate(camWidth, camHeight);    //Source Image
200
							sourceImg.setUseTexture(false);
201
							filter->allocate(camWidth, camHeight);
220 202
							activeInput = true;		//set to active again
221
							bLearnBakground = true; //recapture background
222 203
							//Turn off the video button;
223 204
							bool setBool = false;
224 205
							gui->update(sourcePanel_video, kofxGui_Set_Bool, &setBool, length);
......
231 212
				{
232 213
					if(*(bool*)data)
233 214
					{
234
						if(camera.bcamera){
215
						if(bcamera){
235 216
							activeInput = false; //this stops the app from doing everything when changing source
236
							camera.bcamera = false;
237
							camera.vidPlayer.loadMovie("test_videos/" + videoFileName);
238
							camera.vidPlayer.play();
217
							bcamera = false;
218
							vidPlayer.loadMovie("test_videos/" + videoFileName);
219
							vidPlayer.play();
239 220
							printf("Video Mode\n");
240
							camera.camHeight = camera.vidPlayer.height;
241
							camera.camWidth = camera.vidPlayer.width;
242

243
//							calibrate.setCamRes(camera.camHeight, camera.camWidth);
221
							camHeight = vidPlayer.height;
222
							camWidth = vidPlayer.width;
223
//							calibrate.setCamRes(camHeight, camWidth);
244 224
//							calibrate.computeCameraToScreenMap();
245 225

246 226
							//reset gpu textures and filters
247
							resetGPUTextures();
248

249
							processedImg.allocate(camera.camWidth, camera.camHeight); //Processed Image
227
							processedImg.allocate(camWidth, camHeight); //Processed Image
250 228
							processedImg.setUseTexture(false);
251
							camera.sourceImg.allocate(camera.camWidth, camera.camHeight);    //Source Image
252
							camera.sourceImg.setUseTexture(false);
253
							grayImg.allocate(camera.camWidth, camera.camHeight);		//Gray Image
254
							grayBg.allocate(camera.camWidth, camera.camHeight);		//Background Image
255
							subtractBg.allocate(camera.camWidth, camera.camHeight);   //Background After subtraction
256
							grayDiff.allocate(camera.camWidth, camera.camHeight);		//Difference Image between Background and Source
257
							highpassImg.allocate(camera.camWidth, camera.camHeight);  //Highpass Image
258
							ampImg.allocate(camera.camWidth, camera.camHeight);		//Amplify Image
259
							fiLearn.allocate(camera.camWidth, camera.camHeight);		//ofxFloatImage used for simple dynamic background subtracti
260
							pressureMap.allocate(camera.camWidth, camera.camHeight);	//Pressure Map Image
261

229
							sourceImg.allocate(camWidth, camHeight);    //Source Image
230
							sourceImg.setUseTexture(false);
231
							filter->allocate(camWidth, camHeight);
262 232
							activeInput = true;
263
							bLearnBakground = true;
264 233
							//Turn off the camera button;
265 234
							bool setBool = false;
266 235
							gui->update(sourcePanel_cam, kofxGui_Set_Bool, &setBool, length);
......
268 237
					}
269 238
				}
270 239
				break;
271

272 240
			case sourcePanel_nextCam:
273 241
				if(length == sizeof(bool))
274 242
				{
......
276 244
					{
277 245
						activeInput = false; //this stops the app from doing everything when changing source
278 246

279
						camera.deviceID += 1;
280
						if(camera.deviceID >= camera.vidGrabber.getDeviceCount()) {camera.deviceID = camera.vidGrabber.getDeviceCount();}
247
						deviceID += 1;
248
						if(deviceID >= vidGrabber.getDeviceCount()) {deviceID = vidGrabber.getDeviceCount();}
281 249
						else{
282
							camera.vidGrabber.close();
283
							camera.vidGrabber.setDeviceID(camera.deviceID);
284
							camera.vidGrabber.setVerbose(true);
285
							camera.vidGrabber.initGrabber(camera.camWidth,camera.camHeight);
286
							bLearnBakground = true;
250
							vidGrabber.close();
251
							vidGrabber.setDeviceID(deviceID);
252
							vidGrabber.setVerbose(true);
253
							vidGrabber.initGrabber(camWidth,camHeight);
254
							filter->exposureStartTime = ofGetElapsedTimeMillis();
287 255
						}
288 256
						activeInput = true;
289 257
					}
......
296 264
					{
297 265
						activeInput = false; //this stops the app from doing everything when changing source
298 266

299
						camera.deviceID -= 1;
300
						if(camera.deviceID < 0) camera.deviceID = 0;
267
						deviceID -= 1;
268
						if(deviceID < 0) deviceID = 0;
301 269
						else{
302
							camera.vidGrabber.close();
303
							camera.vidGrabber.setDeviceID(camera.deviceID);
304
							camera.vidGrabber.setVerbose(true);
305
							camera.vidGrabber.initGrabber(camera.camWidth,camera.camHeight);
306
							bLearnBakground = true;
270
							vidGrabber.close();
271
							vidGrabber.setDeviceID(deviceID);
272
							vidGrabber.setVerbose(true);
273
							vidGrabber.initGrabber(camWidth,camHeight);
274
							filter->exposureStartTime = ofGetElapsedTimeMillis();
307 275
						}
308 276
						activeInput = true;
309 277
					}
310 278
				}
311 279
				break;
312

313 280
			case propertiesPanel_settings:
314 281
				if(length == sizeof(bool))
315 282
				{
316
					if(*(bool*)data && camera.bcamera)
283
					if(*(bool*)data && bcamera)
317 284
					{
318
						camera.vidGrabber.videoSettings();
285
						vidGrabber.videoSettings();
319 286
					}
320 287
				}
321 288
				break;
......
347 314
			//Background
348 315
			case backgroundPanel_dynamic:
349 316
				if(length == sizeof(bool))
350
					bDynamicBG = *(bool*)data;
317
					filter->bDynamicBG = *(bool*)data;
351 318
				break;
352 319
			case backgroundPanel_remove:
353 320
				if(length == sizeof(bool))
354
					bLearnBakground = *(bool*)data;
321
					filter->bLearnBakground = *(bool*)data;
355 322
				break;
356 323
			//Highpass
357 324
			case highpassPanel_use:
358 325
				if(length == sizeof(bool))
359
					bHighpass = *(bool*)data;
326
					filter->bHighpass = *(bool*)data;
360 327
				break;
361 328
			case highpassPanel_blur:
362 329
				if(length == sizeof(float))
363
					highpassBlur = *(float*)data;
330
					filter->highpassBlur = *(float*)data;
364 331
				break;
365 332
			case highpassPanel_noise:
366 333
				if(length == sizeof(float))
367
					highpassNoise = *(float*)data;
334
					filter->highpassNoise = *(float*)data;
368 335
				break;
369 336
			//Amplify
370 337
			case amplifyPanel_use:
371 338
				if(length == sizeof(bool))
372
					bAmplify = *(bool*)data;
339
					filter->bAmplify = *(bool*)data;
373 340
				break;
374 341
			case amplifyPanel_amp:
375 342
				if(length == sizeof(float))
376
					highpassAmp = *(float*)data;
343
					filter->highpassAmp = *(float*)data;
377 344
				break;
378 345
			case trackedPanel_threshold:
379 346
				if(length == sizeof(float))
380
					threshold = *(float*)data;
347
					filter->threshold = *(float*)data;
381 348
				break;
382 349
			case trackedPanel_outlines:
383 350
				if(length == sizeof(bool))
......
390 357
			//smooth
391 358
			case smoothPanel_smooth:
392 359
				if(length == sizeof(float))
393
					smooth = *(float*)data;
360
					filter->smooth = *(float*)data;
394 361
				break;
395 362
			case smoothPanel_use:
396 363
				if(length == sizeof(bool))
397
					bSmooth = *(bool*)data;
364
					filter->bSmooth = *(bool*)data;
398 365
				break;
399 366
			//Save Settings
400 367
			case kParameter_SaveXml:
......
407 374
					}
408 375
				}
409 376
				break;
410
			case kParameter_File:
411
				if(length == sizeof(string))
412
				{
413
					string file = *(string*)data;
414
					gui->buildFromXml(file);
415
				}
416
				break;
417

418 377
		}
419 378
	}
420

421 379
}
422

423

424

425

426

427 380
#endif //__GUI_DEFINITION
428 381

trunk/tbeta/Windows/addons/ofxTBeta/TBetaBase.cpp (revision 56)
8 8
 */
9 9

10 10
#include "TBetaBase.h"
11
#include "gui.h"
12

13
void TBetaBase::drawFingerOutlines(){
14

15
    //Find the blobs
16
    for(int i=0; i<contourFinder.nBlobs; i++)
17
    {
18
        //temp blob to rescale and draw on screen
19
        ofxTBetaCvBlob drawBlob;
20
        drawBlob = contourFinder.blobs[i];
21

22
        if(bDrawOutlines)
23
        {
24
            //Get the contour (points) so they can be drawn
25
            for( int j=0; j<contourFinder.blobs[i].nPts; j++ )
26
            {
27
                drawBlob.pts[j].x = (MAIN_WINDOW_WIDTH/camera.camWidth)  * (drawBlob.pts[j].x);
28
                drawBlob.pts[j].y = (MAIN_WINDOW_HEIGHT/camera.camHeight) * (drawBlob.pts[j].y);
29
            }
30

31
            //This adjusts the blob drawing for different cameras
32
            drawBlob.boundingRect.width  *= (MAIN_WINDOW_WIDTH/camera.camWidth);
33
            drawBlob.boundingRect.height *= (MAIN_WINDOW_HEIGHT/camera.camHeight);
34
            drawBlob.boundingRect.x		 *= (MAIN_WINDOW_WIDTH/camera.camWidth);
35
            drawBlob.boundingRect.y		 *= (MAIN_WINDOW_HEIGHT/camera.camHeight);
36

37
            //Draw contours (outlines) on the source image
38
            drawBlob.draw(40, 30);
39

40
			//           ofSetColor(0x0099FF); //Make Plus Sign
41
			//           ofRect((drawBlob.centroid.x * (MAIN_WINDOW_WIDTH/camera.camWidth)) + 40, (drawBlob.centroid.y * (MAIN_WINDOW_HEIGHT/camera.camHeight)) - drawBlob.boundingRect.height + 30, .5, drawBlob.boundingRect.height * 2); //Horizontal Plus
42
			//           ofRect((drawBlob.centroid.x * (MAIN_WINDOW_WIDTH/camera.camWidth)) - drawBlob.boundingRect.width + 40, (drawBlob.centroid.y  * (MAIN_WINDOW_HEIGHT/camera.camHeight)) + 30, drawBlob.boundingRect.width * 2, .5); //Vertical Plus
43
        }
44

45
        if(bShowLabels)  //Show ID label;
46
        {
47
            float xpos = drawBlob.centroid.x * (MAIN_WINDOW_WIDTH/camera.camWidth);
48
            float ypos = drawBlob.centroid.y * (MAIN_WINDOW_HEIGHT/camera.camHeight);
49

50
            ofSetColor(0xCCFFCC);
51
            char idStr[1024];
52
            sprintf(idStr, "id: %i,(%i, %i)",drawBlob.id, drawBlob.lastCentroid.x, drawBlob.lastCentroid.y);
53
            verdana.drawString(idStr, xpos + 365, ypos + drawBlob.boundingRect.height/2 + 45);
54
        }
55
    }
56
    ofSetColor(0xFFFFFF);
11
#include "gui.h"
12

13
/******************************************************************************
14
 * The setup function is run once to perform initializations in the application
15
 *****************************************************************************/
16
void TBetaBase::setup()
17
{
18
    //set the title to 'tbeta'
19
    ofSetWindowTitle("tbeta");
20

21
    //removes the 'x' button on windows which causes a crash due to a GLUT bug
22
#ifdef TARGET_WIN32
23
	HWND hwndConsole = FindWindowA(NULL, "tbeta");
24
	HMENU hMnu = ::GetSystemMenu(hwndConsole, FALSE);
25
	RemoveMenu(hMnu, SC_CLOSE, MF_BYCOMMAND);
26
#endif
27

28
	/********************
29
	 * Initalize Variables
30
	 *********************/
31
	//Intialize FPS variables
32
	frames		= 0;
33
	fps			= 0;
34
	lastFPSlog	= 0;
35
	//Calibration Booleans
36
	bCalibration= false;
37

38
	differenceTime = 0;
39

40
	bDrawVideo = true;
41
	bFullscreen = false;
42
	ofSetBackgroundAuto(false);
43

44
    //create filter
45
    if( filter == NULL ) {
46
        filter = new ofxTouchAdaptiveFilter();
47
    }
48

49
	//Load Settings from config.xml file
50
	loadXMLSettings();
51

52
	//Setup Window Properties
53
	ofSetWindowShape(winWidth,winHeight);
54
	ofSetFrameRate(camRate * 1.4);			//This will be based on camera fps in the future
55
	ofSetVerticalSync(false);	            //Set vertical sync to false for better performance?
56

57
	//Pick the Source - camera or video
58
    if(bcamera)
59
    {
60
        activeInput = true;
61
        vidGrabber.listDevices();
62
        vidGrabber.setDeviceID(deviceID);
63
        vidGrabber.setVerbose(true);
64
        vidGrabber.initGrabber(camWidth,camHeight);
65
        int grabW = vidGrabber.width;
66
        int grabH = vidGrabber.height;
67
        printf("Camera Mode\nAsked for %i by %i - actual size is %i by %i \n\n", camWidth, camHeight, grabW, grabH);
68
    }
69
    else
70
    {
71
        activeInput = true;
72
        vidPlayer.loadMovie("test_videos/" + videoFileName);
73
        vidPlayer.play();
74
        printf("Video Mode\n");
75
        camHeight = vidPlayer.height;
76
        camWidth = vidPlayer.width;
77
    }
78

79
	/*****************************************************************************************************
80
	 * Allocate images (needed for drawing/processing images) ----Most of These won't be needed in the end
81
	 ******************************************************************************************************/
82
	processedImg.allocate(camWidth, camHeight); //main Image that'll be processed.
83
	processedImg.setUseTexture(false);
84
	sourceImg.allocate(camWidth, camHeight);    //Source Image
85
	sourceImg.setUseTexture(false);				//We don't need to draw this so don't create a texture
86
	/******************************************************************************************************/
87

88
	//Fonts - Is there a way to dynamically change font size?
89
	verdana.loadFont("verdana.ttf", 8, true, true);	   //Font used for small images
90
	sidebarTXT.loadFont("verdana.ttf", 8, true, true);
91
	bigvideo.loadFont("verdana.ttf", 13, true, true);  //Font used for big images.
92

93
	//Static Images
94
	background.loadImage("images/background.jpg"); //Main (Temp?) Background
95

96
	gui = ofxGui::Instance(this);
97
	setupGUI();
98

99
    calib.setup(camWidth, camHeight, &tracker);
100

101
    filter->allocate( camWidth, camHeight );
102

103
	printf("Tbeta is setup!\n\n");
57 104
}
105

106
/****************************************************************
107
 *	Load/Save config.xml file Settings
108
 ****************************************************************/
109
void TBetaBase::loadXMLSettings(){
110

111
	// TODO: a seperate XML to map keyboard commands to action
112
	message = "Loading config.xml...";
113
	// Can this load via http?
114
	if( XML.loadFile("config.xml")){
115
		message = "Settings Loaded!";
116
	}else{
117
		//FAIL!
118
		message = "No Settings Found...";
119
	}
120
	//--------------------------------------------------------------
121
	//  START BINDING XML TO VARS
122
	//--------------------------------------------------------------
123
	//frameRate			= XML.getValue("CONFIG:APPLICATION:FRAMERATE",0);
124

125
	winWidth			= XML.getValue("CONFIG:WINDOW:WIDTH",0);
126
	winHeight			= XML.getValue("CONFIG:WINDOW:HEIGHT",0);
127
	minWidth			= XML.getValue("CONFIG:WINDOW:MINX",0);
128
	minHeight			= XML.getValue("CONFIG:WINDOW:MINY",0);
129

130
	bcamera				= XML.getValue("CONFIG:CAMERA_0:USECAMERA",0);
131
	deviceID			= XML.getValue("CONFIG:CAMERA_0:DEVICE",0);
132
	camWidth			= XML.getValue("CONFIG:CAMERA_0:WIDTH",0);
133
	camHeight			= XML.getValue("CONFIG:CAMERA_0:HEIGHT",0);
134
	camRate				= XML.getValue("CONFIG:CAMERA_0:FRAMERATE",0);
135

136
	videoFileName		= XML.getValue("CONFIG:VIDEO:FILENAME", "RearDI.m4v");
137

138
	maxBlobs			= XML.getValue("CONFIG:BLOBS:MAXNUMBER", 20);
139

140
	bShowLabels			= XML.getValue("CONFIG:BOOLEAN:LABELS",0);
141
	bFastMode			= XML.getValue("CONFIG:BOOLEAN:FAST",0);
142
	bDrawOutlines		= XML.getValue("CONFIG:BOOLEAN:OUTLINES",0);
143

144
	filter->bLearnBakground		= XML.getValue("CONFIG:BOOLEAN:LEARNBG",0);
145
	filter->bVerticalMirror		= XML.getValue("CONFIG:BOOLEAN:VMIRROR",0);
146
	filter->bHorizontalMirror	= XML.getValue("CONFIG:BOOLEAN:HMIRROR",0);
147

148
	//Filters
149
	filter->bHighpass			= XML.getValue("CONFIG:BOOLEAN:HIGHPASS",1);
150
	filter->bAmplify			= XML.getValue("CONFIG:BOOLEAN:AMPLIFY", 1);
151
	filter->bSmooth				= XML.getValue("CONFIG:BOOLEAN:SMOOTH", 1);
152
	filter->bDynamicBG			= XML.getValue("CONFIG:BOOLEAN:DYNAMICBG", 1);
153

154
	//GPU
155
	bGPUMode			= XML.getValue("CONFIG:BOOLEAN:GPU", 0);
156

157
	//Filter Settings
158
	filter->threshold			= XML.getValue("CONFIG:INT:THRESHOLD",0);
159
	filter->highpassBlur		= XML.getValue("CONFIG:INT:HIGHPASSBLUR",0);
160
	filter->highpassNoise		= XML.getValue("CONFIG:INT:HIGHPASSNOISE",0);
161
	filter->highpassAmp			= XML.getValue("CONFIG:INT:HIGHPASSAMP",0);
162
	filter->smooth				= XML.getValue("CONFIG:INT:SMOOTH",0);
163

164
	//--------------------------------------------------- TODO XML NETWORK SETTINGS
165
	bTUIOMode			= XML.getValue("CONFIG:BOOLEAN:TUIO",0);
166
	tmpLocalHost		= XML.getValue("CONFIG:NETWORK:LOCALHOST", "localhost");
167
	tmpPort				= XML.getValue("CONFIG:NETWORK:TUIOPORT_OUT", 3333);
168
	myTUIO.setup(tmpLocalHost.c_str(), tmpPort); //have to convert tmpLocalHost to a const char*
169
	//--------------------------------------------------------------
170
	//  END XML SETUP
171
}
172

173
void TBetaBase::saveConfiguration()
174
{
175
	XML.setValue("CONFIG:CAMERA_0:USECAMERA", bcamera);
176
	XML.setValue("CONFIG:CAMERA_0:DEVICE", deviceID);
177
	XML.setValue("CONFIG:CAMERA_0:WIDTH", camWidth);
178
	XML.setValue("CONFIG:CAMERA_0:HEIGHT", camHeight);
179
	XML.setValue("CONFIG:CAMERA_0:FRAMERATE", camRate);
180

181
	XML.setValue("CONFIG:BOOLEAN:PRESSURE",bShowPressure);
182
	XML.setValue("CONFIG:BOOLEAN:LABELS",bShowLabels);
183
	XML.setValue("CONFIG:BOOLEAN:OUTLINES",bDrawOutlines);
184
	XML.setValue("CONFIG:BOOLEAN:LEARNBG", filter->bLearnBakground);
185
	XML.setValue("CONFIG:BOOLEAN:TUIO",bTUIOMode);
186
	XML.setValue("CONFIG:BOOLEAN:VMIRROR", filter->bVerticalMirror);
187
	XML.setValue("CONFIG:BOOLEAN:HMIRROR", filter->bHorizontalMirror);
188

189
	XML.setValue("CONFIG:BOOLEAN:HIGHPASS", filter->bHighpass);
190
	XML.setValue("CONFIG:BOOLEAN:AMPLIFY", filter->bAmplify);
191
	XML.setValue("CONFIG:BOOLEAN:SMOOTH", filter->bSmooth);
192
	XML.setValue("CONFIG:BOOLEAN:DYNAMICBG", filter->bDynamicBG);
193

194
	XML.setValue("CONFIG:BOOLEAN:GPU", bGPUMode);
195

196
	XML.setValue("CONFIG:INT:THRESHOLD", filter->threshold);
197
	XML.setValue("CONFIG:INT:HIGHPASSBLUR", filter->highpassBlur);
198
	XML.setValue("CONFIG:INT:HIGHPASSNOISE", filter->highpassNoise);
199
	XML.setValue("CONFIG:INT:HIGHPASSAMP", filter->highpassAmp);
200
	XML.setValue("CONFIG:INT:SMOOTH", filter->smooth);
201

202
	//	XML.setValue("CONFIG:NETWORK:LOCALHOST", *myTUIO.localHost);
203
	//	XML.setValue("CONFIG:NETWORK:TUIO_PORT_OUT",myTUIO.TUIOPort);
204

205
	XML.saveFile("config.xml");
206
}
207

208
/******************************************************************************
209
 * The update function runs continuously. Use it to update states and variables
210
 *****************************************************************************/
211
void TBetaBase::update()
212
{
213
    bNewFrame = false;
214

215
	if(activeInput){
216

217
		if(bcamera){
218
			vidGrabber.grabFrame();
219
			bNewFrame = vidGrabber.isFrameNew();
220
		}
221
		else{
222
			vidPlayer.idleMovie();
223
			bNewFrame = vidPlayer.isFrameNew();
224
		}
225

226
		if (bNewFrame)
227
		{
228
			ofBackground(0, 0, 0);
229

230
			//Calculate FPS of Camera
231
			frames++;
232
			float time = ofGetElapsedTimeMillis();
233
			if(time > (lastFPSlog + 1000)){
234
				fps = frames;
235
				frames = 0;
236
				lastFPSlog = time;
237
			}//End calculation
238

239
			float beforeTime = ofGetElapsedTimeMillis();
240

241
			if(bGPUMode){
242
				grabFrameToGPU(filter->gpuSourceTex);
243
				filter->applyGPUFilters();
244
				contourFinder.findContours(filter->gpuReadBackImageGS, 1, (camWidth*camHeight)/25, maxBlobs, false);
245
			}
246
			else{
247
				grabFrameToCPU();
248
                filter->applyCPUFilters( processedImg );
249
				contourFinder.findContours(processedImg, 1, (camWidth*camHeight)/25, maxBlobs, false);
250
			}
251

252
			//Track found contours/blobss
253
			tracker.track(&contourFinder);
254
			//get DSP time
255
			differenceTime = ofGetElapsedTimeMillis() - beforeTime;
256

257
            //Dynamic Background subtraction LearRate
258
			if(filter->bDynamicBG){
259
				filter->fLearnRate = 0.01f; //If there are no blobs, add the background faster.
260
				if(contourFinder.nBlobs > 0){ //If there ARE blobs, add the background slower.
261
					filter->fLearnRate = 0.0003f;
262
				}
263
			}//End Background Learning rate
264

265
			if(bTUIOMode){
266
				//We're not using frameseq right now with OSC
267
				//myTUIO.update();
268

269
				//Start sending OSC
270
				myTUIO.sendOSC();
271
			}
272
		}
273
	}
274
}
58 275

59 276
/************************************************
60
 *				FILTERS
277
 *				Frame Grab
61 278
 ************************************************/
62
void TBetaBase::applyGPUImageFilters(){
63 279

64
	if (bLearnBakground == true){
65
		camera.grabFrameToGPU(gpuBGTex);
66
		bLearnBakground = false;
67
	}
68

69
	GLuint processedTex;
70

71
	//tmp = contrastFilter->apply(gpuBGTex);
72
	processedTex = subtractFilter->apply(gpuSourceTex, gpuBGTex);
73

74
	if(bSmooth){//Smooth
75
		gaussHFilter->parameters["kernel_size"]->value = (float)smooth;
76
		gaussVFilter->parameters["kernel_size"]->value = (float)smooth;
77
		processedTex = gaussHFilter->apply(processedTex);
78
		processedTex = gaussVFilter->apply(processedTex);
79
	}
80

81
	if(bHighpass){//Highpass
82
		gaussHFilter2->parameters["kernel_size"]->value = (float)highpassBlur;
83
		gaussVFilter2->parameters["kernel_size"]->value = (float)highpassBlur;
84
		processedTex = gaussHFilter2->apply(processedTex);
85
		processedTex = gaussVFilter2->apply(processedTex);
86
		processedTex = subtractFilter2->apply(gaussVFilter->output_texture, processedTex);
87
	}
88

89
	if(bAmplify){}//amplify
90

91
	threshFilter->parameters["Threshold"]->value = (float)threshold / 255.0; //threshold
92
	threshFilter->apply(processedTex);
93

94
	//until the rest of the pipeline is fixed well just download the preprocessing result from the gpu and use that for the blob detection
95
	//TODO: make this part not super slow ;)
96
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, threshFilter->output_buffer);
97
	//glReadBuffer(gaussVFilter->output_buffer);
98
	glReadPixels(0,0,camera.camWidth, camera.camHeight, GL_RGB, GL_UNSIGNED_BYTE, gpuReadBackBuffer);
99
	gpuReadBackImage.setFromPixels(gpuReadBackBuffer, camera.camWidth, camera.camHeight);
100
	gpuReadBackImageGS = gpuReadBackImage;
101
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
102

280
//Grab frame from CPU
281
void TBetaBase::grabFrameToCPU(){
282
	//Set sourceImg as new camera/video frame
283
	if(bcamera)
284
		sourceImg.setFromPixels(vidGrabber.getPixels(), camWidth, camHeight);
285
	else
286
		sourceImg.setFromPixels(vidPlayer.getPixels(), 	camWidth, camHeight);
287

288
    //convert to grayscale
289
    processedImg = sourceImg;
103 290
}
104 291

105

106
void TBetaBase::applyImageFilters(){
107

108
	processedImg = camera.sourceImg;
109

110

111
	//Set Mirroring Horizontal/Vertical
112
	if(bVerticalMirror || bHorizontalMirror)processedImg.mirror(bVerticalMirror, bHorizontalMirror);
113

114
	if(!bFastMode)grayImg = processedImg; //for drawing
115

116
	//Dynamic background with learn rate...eventually learnrate will have GUI sliders
117
	if(bDynamicBG){
118
		learnBackground( processedImg, grayBg, fiLearn, fLearnRate);
292
//Grab frame from GPU
293
void TBetaBase::grabFrameToGPU(GLuint target){
294
	//grab the frame to a raw openGL texture
295
	if(bcamera)
296
	{
297
		glEnable(GL_TEXTURE_2D);
298
		//glPixelStorei(1);
299
		glBindTexture(GL_TEXTURE_2D, target);
300
		//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, camWidth, camHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, vidGrabber.getPixels());
301
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, camWidth, camHeight, GL_RGB, GL_UNSIGNED_BYTE, vidGrabber.getPixels());
302
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
303
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
304
		glBindTexture(GL_TEXTURE_2D,0);
119 305
	}
120

121
	//Capture full background
122
	if (bLearnBakground == true){
123
		bgCapture( processedImg );
124
		bLearnBakground = false;
306
	else{
307
		glEnable(GL_TEXTURE_2D);
308
		glBindTexture(GL_TEXTURE_2D, target);
309
		//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, camWidth, camHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, vidPlayer.getPixels());
310
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, camWidth, camHeight, GL_RGB, GL_UNSIGNED_BYTE, vidPlayer.getPixels());
311
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
312
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
313
		glBindTexture(GL_TEXTURE_2D,0);
125 314
	}
126

127
	processedImg.absDiff(grayBg, processedImg); //Background Subtraction
128

129
	if(bSmooth){//Smooth
130
		processedImg.blur((smooth * 2) + 1); //needs to be an odd number
131
		if(!bFastMode)subtractBg = processedImg; //for drawing
132
	}
133

134
	if(bHighpass){//HighPass
135
		processedImg.highpass(highpassBlur, highpassNoise);
136
		if(!bFastMode)highpassImg = processedImg; //for drawing
137
	}
138

139
	if(bAmplify){//Amplify
140
		processedImg.amplify(processedImg, highpassAmp);
141
		if(!bFastMode)ampImg = processedImg; //for drawing
142
	}
143

144
	processedImg.threshold(threshold); //Threshold
145
	if(!bFastMode)grayDiff = processedImg; //for drawing
146 315
}
147 316

317

318
/******************************************************************************
319
 * The draw function paints the textures onto the screen. It runs after update.
320
 *****************************************************************************/
321
void TBetaBase::draw(){
322

323
    if(showConfiguration) {
324

325
        //temporary. only auto draw if in fullscreen
326
        if(bNewFrame && bFullscreen == false){drawToScreen();}
327
        else{drawToScreen();}
328

329
        if(!bCalibration)
330
        gui->draw();
331
    }
332
}
148 333

149
void TBetaBase::resetGPUTextures(){
150

151

152
	delete gpuReadBackBuffer;
153
	gpuReadBackBuffer = new unsigned char[camera.camWidth*camera.camHeight*3];
154
	gpuReadBackImage.allocate(camera.camWidth, camera.camHeight);
155
	gpuReadBackImageGS.allocate(camera.camWidth, camera.camHeight);
156

157
	glEnable(GL_TEXTURE_2D);
158
	glBindTexture(GL_TEXTURE_2D, gpuSourceTex);
159
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  camera.camWidth, camera.camHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
160
	glBindTexture(GL_TEXTURE_2D, gpuBGTex);
161
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  camera.camWidth, camera.camHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
162
	glBindTexture(GL_TEXTURE_2D, 0);
163
	glDisable(GL_TEXTURE_2D);
164

165
	subtractFilter = new ImageFilter("filters/absSubtract.xml", camera.camWidth, camera.camHeight);
166
	subtractFilter2 = new ImageFilter("filters/subtract.xml", camera.camWidth, camera.camHeight);
167
	contrastFilter = new ImageFilter("filters/contrast.xml", camera.camWidth, camera.camHeight);
168
	gaussVFilter = new ImageFilter("filters/gaussV.xml", camera.camWidth, camera.camHeight);
169
	gaussHFilter = new ImageFilter("filters/gauss.xml", camera.camWidth, camera.camHeight);
170
	gaussVFilter2 = new ImageFilter("filters/gaussV2.xml", camera.camWidth, camera.camHeight);
171
	gaussHFilter2 = new ImageFilter("filters/gauss2.xml", camera.camWidth, camera.camHeight);
172
	threshFilter = new ImageFilter("filters/threshold.xml", camera.camWidth, camera.camHeight);
173
}
174

175

176

177
void TBetaBase::learnBackground( ofxCvGrayscaleImage & _giLive, ofxCvGrayscaleImage & _grayBg, ofxCvFloatImage & _fiLearn, float _fLearnRate )
178
{
179
	_fiLearn.addWeighted( _giLive, _fLearnRate);
180
    _grayBg = _fiLearn;
181

182
}
183
void TBetaBase::bgCapture( ofxCvGrayscaleImage & _giLive )
184
{
185
	learnBackground( _giLive, grayBg, fiLearn, 1.0f);
186
}
187

188
/******************************************************************************
189
 *							OTHER FUNCTIONS
190
 *****************************************************************************/
191

192
/****************************************************************
193
 *	Load/Save config.xml file Settings
194
 ****************************************************************/
195
void TBetaBase::loadXMLSettings(){
196

197
	// TODO: a seperate XML to map keyboard commands to action
198
	message = "Loading config.xml...";
199
	// Can this load via http?
200
	if( XML.loadFile("config.xml")){
201
		message = "Settings Loaded!";
202
	}else{
203
		//FAIL!
204
		message = "No Settings Found...";
205
	}
206
	//--------------------------------------------------------------
207
	//  START BINDING XML TO VARS
208
	//--------------------------------------------------------------
209
	//frameRate			= XML.getValue("CONFIG:APPLICATION:FRAMERATE",0);
210

211
	winWidth			= XML.getValue("CONFIG:WINDOW:WIDTH",0);
212
	winHeight			= XML.getValue("CONFIG:WINDOW:HEIGHT",0);
213
	minWidth			= XML.getValue("CONFIG:WINDOW:MINX",0);
214
	minHeight			= XML.getValue("CONFIG:WINDOW:MINY",0);
215

216
	camera.bcamera				= XML.getValue("CONFIG:CAMERA_0:USECAMERA",0);
217
	camera.deviceID			= XML.getValue("CONFIG:CAMERA_0:DEVICE",0);
218
	camera.camWidth			= XML.getValue("CONFIG:CAMERA_0:WIDTH",0);
219
	camera.camHeight			= XML.getValue("CONFIG:CAMERA_0:HEIGHT",0);
220
	camera.camRate				= XML.getValue("CONFIG:CAMERA_0:FRAMERATE",0);
221

222
	videoFileName		= XML.getValue("CONFIG:VIDEO:FILENAME", "RearDI.m4v");
223

224
	maxBlobs			= XML.getValue("CONFIG:BLOBS:MAXNUMBER", 20);
225

226
	bShowPressure		= XML.getValue("CONFIG:BOOLEAN:PRESSURE",0);
227

228
	bShowLabels			= XML.getValue("CONFIG:BOOLEAN:LABELS",0);
229
	bFastMode			= XML.getValue("CONFIG:BOOLEAN:FAST",0);
230
	bDrawOutlines		= XML.getValue("CONFIG:BOOLEAN:OUTLINES",0);
231
	bLearnBakground		= XML.getValue("CONFIG:BOOLEAN:LEARNBG",0);
232

233
	bVerticalMirror		= XML.getValue("CONFIG:BOOLEAN:VMIRROR",0);
234
	bHorizontalMirror	= XML.getValue("CONFIG:BOOLEAN:HMIRROR",0);
235

236
	//Filters
237
	bHighpass			= XML.getValue("CONFIG:BOOLEAN:HIGHPASS",1);
238
	bAmplify			= XML.getValue("CONFIG:BOOLEAN:AMPLIFY", 1);
239
	bSmooth				= XML.getValue("CONFIG:BOOLEAN:SMOOTH", 1);
240
	bDynamicBG			= XML.getValue("CONFIG:BOOLEAN:DYNAMICBG", 1);
241

242
	//GPU
243
	bGPUMode			= XML.getValue("CONFIG:BOOLEAN:GPU", 0);
244

245
	//Filter Settings
246
	threshold			= XML.getValue("CONFIG:INT:THRESHOLD",0);
247
	highpassBlur		= XML.getValue("CONFIG:INT:HIGHPASSBLUR",0);
248
	highpassNoise		= XML.getValue("CONFIG:INT:HIGHPASSNOISE",0);
249
	highpassAmp			= XML.getValue("CONFIG:INT:HIGHPASSAMP",0);
250
	smooth				= XML.getValue("CONFIG:INT:SMOOTH",0);
251

252
	//--------------------------------------------------- TODO XML NETWORK SETTINGS
253
	bTUIOMode			= XML.getValue("CONFIG:BOOLEAN:TUIO",0);
254
	tmpLocalHost		= XML.getValue("CONFIG:NETWORK:LOCALHOST", "localhost");
255
	tmpPort				= XML.getValue("CONFIG:NETWORK:TUIOPORT_OUT", 3333);
256
	myTUIO.setup(tmpLocalHost.c_str(), tmpPort); //have to convert tmpLocalHost to a const char*
257
	//--------------------------------------------------------------
258
	//  END XML SETUP
259
}
260

261
void TBetaBase::saveConfiguration()
262
{
263

264
	XML.setValue("CONFIG:CAMERA_0:USECAMERA", camera.bcamera);
265
	XML.setValue("CONFIG:CAMERA_0:DEVICE", camera.deviceID);
266
	XML.setValue("CONFIG:CAMERA_0:WIDTH", camera.camWidth);
267
	XML.setValue("CONFIG:CAMERA_0:HEIGHT", camera.camHeight);
268
	XML.setValue("CONFIG:CAMERA_0:FRAMERATE", camera.camRate);
269

270
	XML.setValue("CONFIG:BOOLEAN:PRESSURE",bShowPressure);
271
	XML.setValue("CONFIG:BOOLEAN:LABELS",bShowLabels);
272
	XML.setValue("CONFIG:BOOLEAN:OUTLINES",bDrawOutlines);
273
	XML.setValue("CONFIG:BOOLEAN:LEARNBG",bLearnBakground);
274
	XML.setValue("CONFIG:BOOLEAN:TUIO",bTUIOMode);
275
	XML.setValue("CONFIG:BOOLEAN:VMIRROR",bVerticalMirror);
276
	XML.setValue("CONFIG:BOOLEAN:HMIRROR",bHorizontalMirror);
277

278
	XML.setValue("CONFIG:BOOLEAN:HIGHPASS", bHighpass);
279
	XML.setValue("CONFIG:BOOLEAN:AMPLIFY", bAmplify);
280
	XML.setValue("CONFIG:BOOLEAN:SMOOTH", bSmooth);
281
	XML.setValue("CONFIG:BOOLEAN:DYNAMICBG", bDynamicBG);
282

283
	XML.setValue("CONFIG:BOOLEAN:GPU", bGPUMode);
284

285
	XML.setValue("CONFIG:INT:THRESHOLD", threshold);
286
	XML.setValue("CONFIG:INT:HIGHPASSBLUR", highpassBlur);
287
	XML.setValue("CONFIG:INT:HIGHPASSNOISE",highpassNoise);
288
	XML.setValue("CONFIG:INT:HIGHPASSAMP",highpassAmp);
289
	XML.setValue("CONFIG:INT:SMOOTH", smooth);
290

291
	//	XML.setValue("CONFIG:NETWORK:LOCALHOST", *myTUIO.localHost);
292
	//	XML.setValue("CONFIG:NETWORK:TUIO_PORT_OUT",myTUIO.TUIOPort);
293

294
	XML.saveFile("config.xml");
295
}
296

297

298
///lets start moving stuff from the testApp.h and testApp.cpp
299

300 334
void TBetaBase::drawToScreen(){
301 335

302 336
    /*********************************
......
310 344
        calib.doCalibration();
311 345
    }
312 346

313

314

315 347
    /********************************
316 348
	 * IF SHOWING MAIN INTERFACE STUFF
317 349
	 ********************************/
......
332 364

333 365
        ofSetColor(0xFFFFFF);
334 366

335
        if(bGPUMode){
336
            drawGLTexture(40, 30, 320, 240, gpuSourceTex);
337
            //subtractFilter->drawOutputTexture(85, 392, 128, 96);
338
            drawGLTexture(85, 392, 128, 96, gpuBGTex);
339
            gaussVFilter->drawOutputTexture(235, 392, 128, 96);
340
            subtractFilter2->drawOutputTexture(385, 392, 128, 96);
341
            threshFilter->drawOutputTexture(535, 392, 128, 96);
342
            gpuReadBackImageGS.draw(385, 30, 320, 240);
343
        }
344
        else
345
        {
346
            if(bShowPressure)
347
                pressureMap.draw(40, 30, 320, 240);
348
            else
349
                grayImg.draw(40, 30, 320, 240);
367
        if(bGPUMode) filter->drawGPU();
368
        else filter->draw();
350 369

351
            grayDiff.draw(385, 30, 320, 240);
352
            fiLearn.draw(85, 392, 128, 96);
353
            subtractBg.draw(235, 392, 128, 96);
354
            highpassImg.draw(385, 392, 128, 96);
355
            ampImg.draw(535, 392, 128, 96);
356
        }
357

358 370
        ofSetColor(0x000000);
359 371
        if(bShowPressure){bigvideo.drawString("Pressure Map", 140, 20);}
360 372
        else             {bigvideo.drawString("Source Image", 140, 20);}
......
367 379
        string str = "DSP Milliseconds: ";
368 380
        str+= ofToString(differenceTime, 0)+"\n\n";
369 381

370
        if(camera.bcamera)
382
        if(bcamera)
371 383
        {
372 384
            string str2 = "Camera Res:     ";
373
            str2+= ofToString(camera.vidGrabber.width, 0) + " x " + ofToString(camera.vidGrabber.height, 0)  + "\n";
385
            str2+= ofToString(vidGrabber.width, 0) + " x " + ofToString(vidGrabber.height, 0)  + "\n";
374 386
            string str4 = "Camera FPS:     ";
375 387
            str4+= ofToString(fps, 0)+"\n\n";
376 388
            string str5 = "Blob Count:       ";
......
381 393
        else
382 394
        {
383 395
            string str2 = "Video Res:       ";
384
            str2+= ofToString(camera.vidPlayer.width, 0) + " x " + ofToString(camera.vidPlayer.height, 0)  + "\n";
396
            str2+= ofToString(vidPlayer.width, 0) + " x " + ofToString(vidPlayer.height, 0)  + "\n";
385 397
            string str4 = "Video FPS:       ";
386 398
            str4+= ofToString(fps, 0)+"\n\n";
387 399
            string str5 = "Blob Count:       ";
......
420 432
        string str = "DSP Milliseconds: ";
421 433
        str+= ofToString(differenceTime, 0)+"\n\n";
422 434

423
        if(camera.bcamera)
435
        if(bcamera)
424 436
        {
425 437
            string str2 = "Camera Res:     ";
426
            str2+= ofToString(camera.vidGrabber.width, 0) + " x " + ofToString(camera.vidGrabber.height, 0)  + "\n";
438
            str2+= ofToString(vidGrabber.width, 0) + " x " + ofToString(vidGrabber.height, 0)  + "\n";
427 439
            string str4 = "Camera FPS:     ";
428 440
            str4+= ofToString(fps, 0)+"\n";
429 441
            ofSetColor(0xFFFFFF);
......
432 444
        else
433 445
        {
434 446
            string str2 = "Video Res:       ";
435
            str2+= ofToString(camera.vidPlayer.width, 0) + " x " + ofToString(camera.vidPlayer.height, 0)  + "\n";
447
            str2+= ofToString(vidPlayer.width, 0) + " x " + ofToString(vidPlayer.height, 0)  + "\n";
436 448
            string str4 = "Video FPS:       ";
437 449
            str4+= ofToString(fps, 0)+"\n";
438 450
            ofSetColor(0xFFFFFF);
......
470 482
    {
471 483
        drawFingerOutlines();
472 484
    }
473
}
485
}
486

487
void TBetaBase::drawFingerOutlines(){
488

489
    //Find the blobs
490
    for(int i=0; i<contourFinder.nBlobs; i++)
491
    {
492
        //temp blob to rescale and draw on screen
493
        ofxTBetaCvBlob drawBlob;
494
        drawBlob = contourFinder.blobs[i];
495

496
        if(bDrawOutlines)
497
        {
498
            //Get the contour (points) so they can be drawn
499
            for( int j=0; j<contourFinder.blobs[i].nPts; j++ )
500
            {
501
                drawBlob.pts[j].x = (MAIN_WINDOW_WIDTH/camWidth)  * (drawBlob.pts[j].x);
502
                drawBlob.pts[j].y = (MAIN_WINDOW_HEIGHT/camHeight) * (drawBlob.pts[j].y);
503
            }
504

505
            //This adjusts the blob drawing for different cameras
506
            drawBlob.boundingRect.width  *= (MAIN_WINDOW_WIDTH/camWidth);
507
            drawBlob.boundingRect.height *= (MAIN_WINDOW_HEIGHT/camHeight);
508
            drawBlob.boundingRect.x		 *= (MAIN_WINDOW_WIDTH/camWidth);
509
            drawBlob.boundingRect.y		 *= (MAIN_WINDOW_HEIGHT/camHeight);
510

511
            //Draw contours (outlines) on the source image
512
            drawBlob.draw(40, 30);
513

514
//			ofSetColor(0x0099FF); //Make Plus Sign
515
//			ofRect((drawBlob.centroid.x * (MAIN_WINDOW_WIDTH/camWidth)) + 40, (drawBlob.centroid.y * (MAIN_WINDOW_HEIGHT/camHeight)) - drawBlob.boundingRect.height + 30, .5, drawBlob.boundingRect.height * 2); //Horizontal Plus
516
//			ofRect((drawBlob.centroid.x * (MAIN_WINDOW_WIDTH/camWidth)) - drawBlob.boundingRect.width + 40, (drawBlob.centroid.y  * (MAIN_WINDOW_HEIGHT/camHeight)) + 30, drawBlob.boundingRect.width * 2, .5); //Vertical Plus
517
        }
518

519
        if(bShowLabels)  //Show ID label;
520
        {
521
            float xpos = drawBlob.centroid.x * (MAIN_WINDOW_WIDTH/camWidth);
522
            float ypos = drawBlob.centroid.y * (MAIN_WINDOW_HEIGHT/camHeight);
523

524
            ofSetColor(0xCCFFCC);
525
            char idStr[1024];
526
            sprintf(idStr, "id: %i,(%i, %i)",drawBlob.id, drawBlob.lastCentroid.x, drawBlob.lastCentroid.y);
527
            verdana.drawString(idStr, xpos + 365, ypos + drawBlob.boundingRect.height/2 + 45);
528
        }
529
    }
530
    ofSetColor(0xFFFFFF);
531
}
474 532

475

476
void TBetaBase::TouchDown( ofxTBetaCvBlob b)
477
{
478
	 if(bTUIOMode)//If sending TUIO, add the blob to the map list
479
	 {
480
         //if blob is not otuside calibration mesh
481
         if(b.centroid.x != 0 && b.centroid.y != 0)
482
         myTUIO.blobs[b.id] = b;
483
	 }
484
}
485

486
void TBetaBase::TouchUp( ofxTBetaCvBlob b)
487
{
488
	 if(bTUIOMode)//If sending TUIO delete Blobs from map list
489
	 {
490
         std::map<int, ofxTBetaCvBlob>::iterator iter;
491
         for(iter = myTUIO.blobs.begin(); iter != myTUIO.blobs.end(); iter++)
492
         {
493
             if(iter->second.id == b.id)
494
             {
495
                myTUIO.blobs.erase(iter);
496
                break;
497
             }
498
         }
499
	 }
500
}
501

502
void TBetaBase::TouchMoved( ofxTBetaCvBlob b)
503
{
504
	//printf("b: %f, %f\n", b.centroid.x, b.centroid.y);
505
	 if(bTUIOMode)//If sending TUIO, add the blob to the map list
506
	 {
507
         //if blob is not otuside calibration mesh
508
         if(b.centroid.x != 0 && b.centroid.y != 0)
509
         myTUIO.blobs[b.id] = b;
510
	 }
511
}
512

513

514

515
/******************************************************************************
516
 * The setup function is run once to perform initializations in the application
517
 *****************************************************************************/
518
void TBetaBase::setup()
519
{
520
    //set the title to 'tbeta'
521
    ofSetWindowTitle("tbeta");
522

523
    //removes the 'x' button on windows which causes a crash due to a GLUT bug
524
#ifdef TARGET_WIN32
525
	HWND hwndConsole = FindWindowA(NULL, "tbeta");
526
	HMENU hMnu = ::GetSystemMenu(hwndConsole, FALSE);
527
	RemoveMenu(hMnu, SC_CLOSE, MF_BYCOMMAND);
528
#endif
529

530

531
	/********************
532
	 * Initalize Variables
533
	 *********************/
534
//	calibrationParticle.loadImage("images/particle.png");
535
//	calibrationParticle.setUseTexture(true);
536

537
	//Background Subtraction Learning Rate
538
	fLearnRate	= 0.0001f;
539
	//Intialize FPS variables
540
	frames		= 0;
541
	fps			= 0;
542
	lastFPSlog	= 0;
543
	//Calibration Booleans
544
	bCalibration= false;
545

546
	differenceTime = 0;
547

548
	bDrawVideo = true;
549
	bFullscreen = false;
550
	ofSetBackgroundAuto(false);
551

552
	//Load Settings from config.xml file
553
	loadXMLSettings();
554

555
	//Setup Window Properties
556
	ofSetWindowShape(winWidth,winHeight);
557
	ofSetFrameRate(camera.camRate * 1.4);			//This will be based on camera fps in the future
558
	ofSetVerticalSync(false);	            //Set vertical sync to false for better performance
559

560
	//Pick the Source - camera or video
561
	if(camera.bcamera)
562
	{
563
        activeInput = true;
564
		camera.vidGrabber.listDevices();
565
		camera.vidGrabber.setDeviceID(camera.deviceID);
566
		camera.vidGrabber.setVerbose(true);
567
        camera.vidGrabber.initGrabber(camera.camWidth,camera.camHeight);
568
		int grabW = camera.vidGrabber.width;
569
		int grabH = camera.vidGrabber.height;
570
		printf("Camera Mode\nAsked for %i by %i - actual size is %i by %i \n\n", camera.camWidth, camera.camHeight, grabW, grabH);
571
	}
572
	else
573
	{
574
		activeInput = true;
575
		camera.vidPlayer.loadMovie("test_videos/" + videoFileName);
576
        camera.vidPlayer.play();
577
		printf("Video Mode\n");
578
		camera.camHeight = camera.vidPlayer.height;
579
		camera.camWidth = camera.vidPlayer.width;
580
	}
581

582
	/*****************************************************************************************************
583
	 * Allocate images (needed for drawing/processing images) ----Most of These won't be needed in the end
584
	 ******************************************************************************************************/
585
	processedImg.allocate(camera.camWidth, camera.camHeight); //main Image that'll be processed.
586
	processedImg.setUseTexture(false);
587
	camera.sourceImg.allocate(camera.camWidth, camera.camHeight);    //Source Image
588
	camera.sourceImg.setUseTexture(false);				//We don't need to draw this so don't create a texture
589

590
	//These images are used for drawing only
591
	grayImg.allocate(camera.camWidth, camera.camHeight);		//Gray Image
592
	grayBg.allocate(camera.camWidth, camera.camHeight);		//Background Image
593
	subtractBg.allocate(camera.camWidth, camera.camHeight);   //Background After subtraction
594
	grayDiff.allocate(camera.camWidth, camera.camHeight);		//Difference Image between Background and Source
595
	highpassImg.allocate(camera.camWidth, camera.camHeight);  //Highpass Image
596
	ampImg.allocate(camera.camWidth, camera.camHeight);		//Amplied Image
597
	fiLearn.allocate(camera.camWidth, camera.camHeight);		//ofxFloatImage used for simple dynamic background subtracti
598
	//	fiLearn.setUseTexture(false);
599
	pressureMap.allocate(camera.camWidth, camera.camHeight);	//Pressure Map Image
600

601
	/********************************************************************************************************/
602

603

604
	/**********************************************************/
605
	//GPU stuff initialization
606
	/**********************************************************/
607
	glGenTextures(1, &gpuSourceTex);
608
	glGenTextures(1, &gpuBGTex);
609

610
	//initialize texture once with glTexImage2D so we can use gltexSubImage2D afetrwards (fastser)
611
	glEnable(GL_TEXTURE_2D);
612
	glBindTexture(GL_TEXTURE_2D, gpuSourceTex);
613
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  camera.camWidth, camera.camHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
614
	glBindTexture(GL_TEXTURE_2D, gpuBGTex);
615
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  camera.camWidth, camera.camHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
616
	glBindTexture(GL_TEXTURE_2D, 0);
617
	glDisable(GL_TEXTURE_2D);
618

619
	camera.grabFrameToGPU(gpuBGTex);
620

621
	//so very inefficient..but only for now..until i fix the gpu blob detection and geoemtry shader for variable length output
622
	gpuReadBackBuffer = new unsigned char[camera.camWidth*camera.camHeight*3];
623
	gpuReadBackImage.allocate(camera.camWidth, camera.camHeight);
624
	gpuReadBackImageGS.allocate(camera.camWidth, camera.camHeight);
625

626
	subtractFilter = new ImageFilter("filters/absSubtract.xml", camera.camWidth, camera.camHeight);
627
	subtractFilter2 = new ImageFilter("filters/subtract.xml", camera.camWidth, camera.camHeight);
628
	contrastFilter = new ImageFilter("filters/contrast.xml", camera.camWidth, camera.camHeight);
629
	gaussVFilter = new ImageFilter("filters/gaussV.xml", camera.camWidth, camera.camHeight);
630
	gaussHFilter = new ImageFilter("filters/gauss.xml", camera.camWidth, camera.camHeight);
631
	gaussVFilter2 = new ImageFilter("filters/gaussV2.xml", camera.camWidth, camera.camHeight);
632
	gaussHFilter2 = new ImageFilter("filters/gauss2.xml", camera.camWidth, camera.camHeight);
633
	threshFilter = new ImageFilter("filters/threshold.xml", camera.camWidth, camera.camHeight);
634

635
	/**********************************************************/
636

637
	//Fonts - Is there a way to dynamically change font size?
638
	verdana.loadFont("verdana.ttf", 8, true, true);	   //Font used for small images
639
	sidebarTXT.loadFont("verdana.ttf", 8, true, true);
640
	bigvideo.loadFont("verdana.ttf", 13, true, true);  //Font used for big images.
641

642
	//Static Images
643
	background.loadImage("images/background.jpg"); //Main (Temp?) Background
644

645
	gui = ofxGui::Instance(this);
646
	setupGUI();
647

648

649

650
    calib.setup(camera.camWidth, camera.camHeight, &tracker);
651

652

653
	printf("Tbeta pplication is setup!\n\n");
654
}
655

656

657
/******************************************************************************
658
 * The update function runs continuously. Use it to update states and variables
659
 *****************************************************************************/
660
void TBetaBase::update()
661
{
662
    bNewFrame = false;
663

664
	if(activeInput){
665

666
		if(camera.bcamera){
667
			camera.vidGrabber.grabFrame();
668
			bNewFrame = camera.vidGrabber.isFrameNew();
669
		}
670
		else{
671
			camera.vidPlayer.idleMovie();
672
			bNewFrame = camera.vidPlayer.isFrameNew();
673
		}
674

675
		if (bNewFrame)
676
		{
677
			ofBackground(0, 0, 0);
678

679
			//Calculate FPS of Camera
680
			frames++;
681
			float time = ofGetElapsedTimeMillis();
682
			if(time > (lastFPSlog + 1000)){
683
				fps = frames;
684
				frames = 0;
685
				lastFPSlog = time;
686
			}//End calculation
687

688

689
			float beforeTime = ofGetElapsedTimeMillis();
690
			if(bGPUMode){
691
				camera.grabFrameToGPU(gpuSourceTex);
692
				applyGPUImageFilters();
693
				contourFinder.findContours(gpuReadBackImageGS, 1, (camera.camWidth*camera.camHeight)/25, maxBlobs, false);
694
			}
695
			else{
696
				camera.grabFrameToCPU();
697
				applyImageFilters();
698
				contourFinder.findContours(processedImg, 1, (camera.camWidth*camera.camHeight)/25, maxBlobs, false);
699
			}
700

701
			//Track found contours/blobss
702
			tracker.track(&contourFinder);
703
			//get DSP time
704
			differenceTime = ofGetElapsedTimeMillis() - beforeTime;
705

706
            //Dynamic Background subtraction LearRate
707
			if(bDynamicBG){
708
				fLearnRate = 0.01f; //If there are no blobs, add the background faster.
709
				if(contourFinder.nBlobs > 0){ //If there ARE blobs, add the background slower.
710
					fLearnRate = 0.0003f;
711
				}
712
			}//End Background Learning rate
713

714
			if(bTUIOMode){
715
				//We're not using frameseq right now with OSC
716
				//myTUIO.update();
717

718
				//Start sending OSC
719
				myTUIO.sendOSC();
720
			}
721
		}
722
	}
723
}
724

725
/******************************************************************************
726
 * The draw function paints the textures onto the screen. It runs after update.
727
 *****************************************************************************/
728
void TBetaBase::draw(){
729

730
    if(showConfiguration) {
731

732
        //temporary. only auto draw if in fullscreen
733
        if(bNewFrame && bFullscreen == false){drawToScreen();}
734
        else{drawToScreen();}
735

736
        if(!bCalibration)
737
        gui->draw();
738
		
739
		ofSetColor(180, 220, 180, 180);
740
		ofFill();
741
		ofRect(ofGetWidth() - 200,ofGetHeight() - 14, 200, 14);
742
		
743
		ofSetColor(0x000000);
744
		ofDrawBitmapString("|  ~  |tbeta.nuigroup.com", ofGetWidth() - 200, ofGetHeight() - 2);
745
		
746
		
747
    }
748
}
749

750 533
/*****************************************************************************
751 534
 * KEY EVENTS
752 535
 *****************************************************************************/
753 536
void TBetaBase::keyPressed(int key) {
754 537
	if(showConfiguration) {
755
		switch(key)
756
		{
757
			case 'b':
758
				bLearnBakground = true;
759
				break;
760
			case 'o':
761
				bDrawOutlines ? bDrawOutlines = false : bDrawOutlines = true;
762
				gui->update(appPtr->trackedPanel_outlines, kofxGui_Set_Bool, &appPtr->bDrawOutlines, sizeof(bool));
763
				break;
764
			case 'h':
765
				bHorizontalMirror ? bHorizontalMirror = false : bHorizontalMirror = true;
766
				gui->update(appPtr->propertiesPanel_flipH, kofxGui_Set_Bool, &appPtr->bHorizontalMirror, sizeof(bool));
767
				break;
768
			case 'j':
769
				bVerticalMirror ? bVerticalMirror = false : bVerticalMirror = true;
770
				gui->update(appPtr->propertiesPanel_flipV, kofxGui_Set_Bool, &appPtr->bVerticalMirror, sizeof(bool));
771
				break;
772
			case 't':
773
				if(!bCalibration && bTUIOMode)
774
				{
775
					bTUIOMode = false;
776
					myTUIO.blobs.clear();
777
					gui->update(appPtr->optionPanel_tuio, kofxGui_Set_Bool, &appPtr->bTUIOMode, sizeof(bool));
778
				}
779
				else
780
				{
781
					bTUIOMode = true;
782
					gui->update(appPtr->optionPanel_tuio, kofxGui_Set_Bool, &appPtr->bTUIOMode, sizeof(bool));
783
				}
784
				break;
785
			case 'g':
786
				bGPUMode ? bGPUMode = false : bGPUMode = true;
787
				gui->update(appPtr->gpuPanel_use, kofxGui_Set_Bool, &appPtr->bGPUMode, sizeof(bool));
788
				bLearnBakground = true;
789
				break;
790
			case 'v':
791
				if(camera.bcamera)
792
					camera.vidGrabber.videoSettings();
793
				break;
794
			case 'l':
795
				bShowLabels ? bShowLabels = false : bShowLabels = true;
796
				gui->update(appPtr->trackedPanel_ids, kofxGui_Set_Bool, &appPtr->bShowLabels, sizeof(bool));
797
				break;
798
			case 'p':
799
				bShowPressure ? bShowPressure = false : bShowPressure = true;
800
				break;
801
			case ' ':
802
				if(bFastMode)
803
				{
804
					bFastMode = false;
805
					ofSetWindowShape(950,600); //default size
806
					//ofSetWindowTitle("Configuration");
807
				}
808
				else
809
				{
810
					bFastMode = true;
811
					ofSetWindowShape(190,155); //minimized size
812
					//ofSetWindowTitle("Mini");
813
				}
814
				break;
815
				/***********************
816
				 * Keys for Calibration
817
				 ***********************/
818
			case 'x': //Begin Calibrating
819
				if(bCalibration){
820
					bCalibration = false;
821
					calib.calibrating = false;
822
					if(bFullscreen == true) ofToggleFullscreen(); bFullscreen = false; ofSetBackgroundAuto(false);
823
				}
824
				break;
538
	switch(key)
539
	{
540
		case 'b':
541
			filter->bLearnBakground = true;
542
			break;
543
		case 'o':
544
			bDrawOutlines ? bDrawOutlines = false : bDrawOutlines = true;
545
			gui->update(appPtr->trackedPanel_outlines, kofxGui_Set_Bool, &appPtr->bDrawOutlines, sizeof(bool));
546
			break;
547
		case 'h':
548
			bHorizontalMirror ? bHorizontalMirror = false : bHorizontalMirror = true;
549
			gui->update(appPtr->propertiesPanel_flipH, kofxGui_Set_Bool, &appPtr->bHorizontalMirror, sizeof(bool));
550
			break;
551
		case 'j':
552
			bVerticalMirror ? bVerticalMirror = false : bVerticalMirror = true;
553
			gui->update(appPtr->propertiesPanel_flipV, kofxGui_Set_Bool, &appPtr->bVerticalMirror, sizeof(bool));
554
			break;
555
		case 't':
556
			if(!bCalibration && bTUIOMode)
557
			{
558
				bTUIOMode = false;
559
				myTUIO.blobs.clear();
560
				gui->update(appPtr->optionPanel_tuio, kofxGui_Set_Bool, &appPtr->bTUIOMode, sizeof(bool));
561
			}
562
			else
563
			{
564
				bTUIOMode = true;
565
				gui->update(appPtr->optionPanel_tuio, kofxGui_Set_Bool, &appPtr->bTUIOMode, sizeof(bool));
566
			}
567
			break;
568
		case 'g':
569
			bGPUMode ? bGPUMode = false : bGPUMode = true;
570
			gui->update(appPtr->gpuPanel_use, kofxGui_Set_Bool, &appPtr->bGPUMode, sizeof(bool));
571
			filter->bLearnBakground = true;
572
			break;
573
		case 'v':
574
			if(bcamera)
575
				vidGrabber.videoSettings();
576
			break;
577
		case 'l':
578
			bShowLabels ? bShowLabels = false : bShowLabels = true;
579
			gui->update(appPtr->trackedPanel_ids, kofxGui_Set_Bool, &appPtr->bShowLabels, sizeof(bool));
580
			break;
581
		case 'p':
582
			bShowPressure ? bShowPressure = false : bShowPressure = true;
583
			break;
584
		case ' ':
585
			if(bFastMode)
586
			{
587
				bFastMode = false;
588
				ofSetWindowShape(950,600); //default size
589
				//ofSetWindowTitle("Configuration");
590
			}
591
			else
592
			{
593
				bFastMode = true;
594
				ofSetWindowShape(190,155); //minimized size
595
				//ofSetWindowTitle("Mini");
596
			}
597
			break;
598
			 /***********************
599
			 * Keys for Calibration
600
			 ***********************/
601
		case 'x': //Begin Calibrating
602
			if(bCalibration){
603
				bCalibration = false;
604
				calib.calibrating = false;
605
				if(bFullscreen == true) ofToggleFullscreen(); bFullscreen = false; ofSetBackgroundAuto(false);
606
			}
607
			break;
825 608
        }
826 609
    }
827 610
}
828 611

829

830 612
void TBetaBase::keyReleased(int key){
831 613

832 614
    if(showConfiguration)
......
840 622
    }
841 623

842 624
	if( key == '~' || key == '`') showConfiguration = !showConfiguration;
843
}
625
}
626

627
/*****************************************************************************
628
 *	Touch EVENTS
629
 *****************************************************************************/
630
void TBetaBase::TouchDown( ofxTBetaCvBlob b)
631
{
632
	 if(bTUIOMode)//If sending TUIO, add the blob to the map list
633
	 {
634
         //if blob is not otuside calibration mesh
635
         if(b.centroid.x != 0 && b.centroid.y != 0)
636
         myTUIO.blobs[b.id] = b;
637
	 }
638
}
639

640
void TBetaBase::TouchUp( ofxTBetaCvBlob b)
641
{
642
	 if(bTUIOMode)//If sending TUIO delete Blobs from map list
643
	 {
644
         std::map<int, ofxTBetaCvBlob>::iterator iter;
645
         for(iter = myTUIO.blobs.begin(); iter != myTUIO.blobs.end(); iter++)
646
         {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff