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