Permalink
Browse files

Updated the ColorObjectTracking example to use GPU-based averaging, w…

…hich makes it operate at 30 FPS. Improved the precision of the averaging filter in certain cases.
  • Loading branch information...
1 parent f73c5d8 commit b1293a6f1a319af1a2f9e37544a3d39a48c2643d @BradLarson committed Aug 27, 2012
@@ -10,6 +10,7 @@ typedef enum { PASSTHROUGH_VIDEO, SIMPLE_THRESHOLDING, POSITION_THRESHOLDING, OB
GPUImageVideoCamera *videoCamera;
GPUImageFilter *thresholdFilter, *positionFilter;
GPUImageRawDataOutput *positionRawData, *videoRawData;
+ GPUImageAverageColor *positionAverageColor;
GPUImageView *filteredVideoView;
ColorTrackingDisplayMode displayMode;
@@ -70,7 +70,20 @@ - (void)configureVideoFiltering;
__unsafe_unretained ColorTrackingViewController *weakSelf = self;
[positionRawData setNewFrameAvailableBlock:^{
GLubyte *bytesForPositionData = positionRawData.rawBytesForImage;
- CGPoint currentTrackingLocation = [weakSelf centroidFromTexture:bytesForPositionData ofSize:[positionRawData maximumOutputSize]];
+ CGPoint currentTrackingLocation = [weakSelf centroidFromTexture:bytesForPositionData ofSize:[positionRawData maximumOutputSize]];
+// NSLog(@"Centroid from CPU: %f, %f", currentTrackingLocation.x, currentTrackingLocation.y);
+ CGSize currentViewSize = weakSelf.view.bounds.size;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ trackingDot.position = CGPointMake(currentTrackingLocation.x * currentViewSize.width, currentTrackingLocation.y * currentViewSize.height);
+ });
+ }];
+
+ positionAverageColor = [[GPUImageAverageColor alloc] init];
+ [positionAverageColor setColorAverageProcessingFinishedBlock:^(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime) {
+// NSLog(@"GPU Average R: %f, G: %f, A: %f", redComponent, greenComponent, alphaComponent);
+ CGPoint currentTrackingLocation = CGPointMake(1.0 - (greenComponent / alphaComponent), (redComponent / alphaComponent));
+// NSLog(@"Centroid from GPU: %f, %f", currentTrackingLocation.x, currentTrackingLocation.y);
+ // NSLog(@"Average color: %f, %f, %f, %f", redComponent, greenComponent, blueComponent, alphaComponent);
CGSize currentViewSize = weakSelf.view.bounds.size;
dispatch_async(dispatch_get_main_queue(), ^{
trackingDot.position = CGPointMake(currentTrackingLocation.x * currentViewSize.width, currentTrackingLocation.y * currentViewSize.height);
@@ -204,7 +217,8 @@ - (void)handleSwitchOfDisplayMode:(id)sender;
{
[videoCamera addTarget:filteredVideoView];
[videoCamera addTarget:positionFilter];
- [positionFilter addTarget:positionRawData];
+// [positionFilter addTarget:positionRawData]; // Enable this for CPU-based centroid computation
+ [positionFilter addTarget:positionAverageColor]; // Enable this for GPU-based centroid computation
}; break;
}
}
@@ -235,6 +249,8 @@ - (CGPoint)centroidFromTexture:(GLubyte *)pixels ofSize:(CGSize)textureSize;
currentPixelTotal += (CGFloat)pixels[(currentPixel * 4) + 3] / 255.0f;
}
}
+
+// NSLog(@"CPU Average R: %f, G: %f, A: %f", currentXTotal / (textureSize.width * textureSize.height), currentYTotal / (textureSize.width * textureSize.height), currentPixelTotal / (textureSize.width * textureSize.height));
return CGPointMake((1.0 - currentYTotal / currentPixelTotal), currentXTotal / currentPixelTotal);
}
@@ -26,12 +26,10 @@ void main()
NSString *const kGPUImageColorAveragingFragmentShaderString = SHADER_STRING
(
- precision lowp float;
+ precision highp float;
uniform sampler2D inputImageTexture;
- uniform mediump mat3 convolutionMatrix;
-
varying highp vec2 outputTextureCoordinate;
varying highp vec2 upperLeftInputTextureCoordinate;
@@ -41,10 +39,10 @@ void main()
void main()
{
- mediump vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate);
- mediump vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate);
- mediump vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate);
- mediump vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate);
+ highp vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate);
+ highp vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate);
+ highp vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate);
+ highp vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate);
gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor);
}
@@ -104,9 +102,11 @@ - (void)initializeOutputTexture;
{
// CGSize currentStageSize = CGSizeMake(ceil(inputTextureSize.width / pow(4.0, currentReduction + 1.0)), ceil(inputTextureSize.height / pow(4.0, currentReduction + 1.0)));
CGSize currentStageSize = CGSizeMake(floor(inputTextureSize.width / pow(4.0, currentReduction + 1.0)), floor(inputTextureSize.height / pow(4.0, currentReduction + 1.0)));
- if (currentStageSize.height < 2.0)
+ if ( (currentStageSize.height < 2.0) || (currentStageSize.width < 2.0) )
{
- currentStageSize.height = 2.0; // TODO: Rotate the image to account for this case, which causes FBO construction to fail
+ // A really small last stage seems to cause significant errors in the average, so I abort and leave the rest to the CPU at this point
+ break;
+// currentStageSize.height = 2.0; // TODO: Rotate the image to account for this case, which causes FBO construction to fail
}
[stageSizes addObject:[NSValue valueWithCGSize:currentStageSize]];

0 comments on commit b1293a6

Please sign in to comment.