Search code examples
objective-cgpuimage

Creating an algorithm to find red intensity of the frames of a video using GPUImage


I need to create an algorithm that will essentially take video input from the rear camera of an iPhone for 30 seconds at 15 frames per second (a total of 450 frames). After the 30 second period is over, no more input should be recorded. Finally, the algorithm should take the average red value or intensity of each of the 450 frames, leaving me with 450 red values. Obviously, I'm using GPUImage to do all of this.

Right now, I have something like this:

GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;

GPUImageAverageColor *averageColor = [[GPUImageAverageColor alloc] init];
[averageColor setColorAverageProcessingFinishedBlock:^(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime)
// retrieve the average color values
 {
     NSLog(@"%f", redComponent); // print the red values
     // [redValues addObject:@(redComponent)]; <-- this is what I would use to put all of the red values in an array
 }];

[videoCamera addTarget:averageColor];
[videoCamera startCameraCapture];

The problem I'm having is that I don't know where to set my desired frames per second of the video (15 frames per second), and I'm also unsure of where to specify how long I want my video sample to be (30 seconds). My biggest problem is that the console isn't printing any red values at all, even though the camera should capture video.

How can I address all of three of these problems? Sample code would be highly appreciated.


Solution

  • Your setup above is correct, and the remainder is simply logic that needs to be implemented within the callback block. That block will be triggered once per frame, passing in the RGBA component values (as 0.0-1.0 floats).

    If you want this to average the red channel values, set up a sum instance variable (initialized at 0.0) and add each new red value to it. You'll also want to set up a counter instance variable to be incremented once per block activation.

    To make this run for 30 seconds, and no longer, take a timestamp before you call -startCameraCapture in the above and compare it to the current timestamp every time your block is called. Once that exceeds 30 seconds, pause or stop camera capture and process your results. To obtain the average red color, simply divide your red channel sum by the number of frames measured during this period.