root / trunk / tbeta / Windows / addons / ofxTBeta / ofxTouchAdaptiveFilter.h @ 56
View | Annotate | Download (6.9 KB)
| 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
|
