GPUImageMotionDetector.m 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #import "GPUImageMotionDetector.h"
  2. #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
  3. NSString *const kGPUImageMotionComparisonFragmentShaderString = SHADER_STRING
  4. (
  5. varying highp vec2 textureCoordinate;
  6. varying highp vec2 textureCoordinate2;
  7. uniform sampler2D inputImageTexture;
  8. uniform sampler2D inputImageTexture2;
  9. uniform highp float intensity;
  10. void main()
  11. {
  12. lowp vec3 currentImageColor = texture2D(inputImageTexture, textureCoordinate).rgb;
  13. lowp vec3 lowPassImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb;
  14. mediump float colorDistance = distance(currentImageColor, lowPassImageColor); // * 0.57735
  15. lowp float movementThreshold = step(0.2, colorDistance);
  16. gl_FragColor = movementThreshold * vec4(textureCoordinate2.x, textureCoordinate2.y, 1.0, 1.0);
  17. }
  18. );
  19. #else
  20. NSString *const kGPUImageMotionComparisonFragmentShaderString = SHADER_STRING
  21. (
  22. varying vec2 textureCoordinate;
  23. varying vec2 textureCoordinate2;
  24. uniform sampler2D inputImageTexture;
  25. uniform sampler2D inputImageTexture2;
  26. uniform float intensity;
  27. void main()
  28. {
  29. vec3 currentImageColor = texture2D(inputImageTexture, textureCoordinate).rgb;
  30. vec3 lowPassImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb;
  31. float colorDistance = distance(currentImageColor, lowPassImageColor); // * 0.57735
  32. float movementThreshold = step(0.2, colorDistance);
  33. gl_FragColor = movementThreshold * vec4(textureCoordinate2.x, textureCoordinate2.y, 1.0, 1.0);
  34. }
  35. );
  36. #endif
  37. @implementation GPUImageMotionDetector
  38. @synthesize lowPassFilterStrength, motionDetectionBlock;
  39. #pragma mark -
  40. #pragma mark Initialization and teardown
  41. - (id)init;
  42. {
  43. if (!(self = [super init]))
  44. {
  45. return nil;
  46. }
  47. // Start with a low pass filter to define the component to be removed
  48. lowPassFilter = [[GPUImageLowPassFilter alloc] init];
  49. [self addFilter:lowPassFilter];
  50. // Take the difference of the current frame from the low pass filtered result to get the high pass
  51. frameComparisonFilter = [[GPUImageTwoInputFilter alloc] initWithFragmentShaderFromString:kGPUImageMotionComparisonFragmentShaderString];
  52. [self addFilter:frameComparisonFilter];
  53. // Texture location 0 needs to be the original image for the difference blend
  54. [lowPassFilter addTarget:frameComparisonFilter atTextureLocation:1];
  55. // End with the average color for the scene to determine the centroid
  56. averageColor = [[GPUImageAverageColor alloc] init];
  57. __unsafe_unretained GPUImageMotionDetector *weakSelf = self;
  58. [averageColor setColorAverageProcessingFinishedBlock:^(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime) {
  59. if (weakSelf.motionDetectionBlock != NULL)
  60. {
  61. weakSelf.motionDetectionBlock(CGPointMake(redComponent / alphaComponent, greenComponent / alphaComponent), alphaComponent, frameTime);
  62. }
  63. // NSLog(@"Average X: %f, Y: %f total: %f", redComponent / alphaComponent, greenComponent / alphaComponent, alphaComponent);
  64. }];
  65. [frameComparisonFilter addTarget:averageColor];
  66. self.initialFilters = [NSArray arrayWithObjects:lowPassFilter, frameComparisonFilter, nil];
  67. self.terminalFilter = frameComparisonFilter;
  68. self.lowPassFilterStrength = 0.5;
  69. return self;
  70. }
  71. #pragma mark -
  72. #pragma mark Accessors
  73. - (void)setLowPassFilterStrength:(CGFloat)newValue;
  74. {
  75. lowPassFilter.filterStrength = newValue;
  76. }
  77. - (CGFloat)lowPassFilterStrength;
  78. {
  79. return lowPassFilter.filterStrength;
  80. }
  81. @end