iosobjective-cbrightnessluminance

Luminosity from iOS camera


I'm trying to make an application and i have to calculate the brightness of the camera like this application : http://itunes.apple.com/us/app/megaman-luxmeter/id455660266?mt=8

I found this document : http://b2cloud.com.au/tutorial/obtaining-luminosity-from-an-ios-camera

But i don't know how to adapt it to the camera directly and not an image. Here is my code :

    Image = [[UIImagePickerController alloc] init];
    Image.delegate = self;
    Image.sourceType = UIImagePickerControllerCameraCaptureModeVideo;
    Image.showsCameraControls = NO;
    [Image setWantsFullScreenLayout:YES];
    Image.view.bounds = CGRectMake (0, 0, 320, 480);
    [self.view addSubview:Image.view];

    NSArray* dayArray = [NSArray arrayWithObjects:Image,nil];
    for(NSString* day in dayArray)
    {
        for(int i=1;i<=2;i++)
        {
            UIImage* image = [UIImage imageNamed:[NSString stringWithFormat:@"%@%d.png",day,i]];
            unsigned char* pixels = [image rgbaPixels];
            double totalLuminance = 0.0;
            for(int p=0;p<image.size.width*image.size.height*4;p+=4)
            {
                totalLuminance += pixels[p]*0.299 + pixels[p+1]*0.587 + pixels[p+2]*0.114;
            }
            totalLuminance /= (image.size.width*image.size.height);
            totalLuminance /= 255.0;
            NSLog(@"%@ (%d) = %f",day,i,totalLuminance);
        }
    }

Here are the issues :

"Instance method '-rgbaPixels' not found (return type defaults to 'id')" & "Incompatible pointer types initializing 'unsigned char *' with an expression of type 'id'"

Thanks a lot ! =)


Solution

  • Rather than doing expensive CPU-bound processing of each pixel in an input video frame, let me suggest an alternative approach. My open source GPUImage framework has a luminosity extractor built into it, which uses GPU-based processing to give live luminosity readings from the video camera.

    It's relatively easy to set this up. You simply need to allocate a GPUImageVideoCamera instance to represent the camera, allocate a GPUImageLuminosity filter, and add the latter as a target for the former. If you want to display the camera feed to the screen, create a GPUImageView instance and add that as another target for your GPUImageVideoCamera.

    Your luminosity extractor will use a callback block to return luminosity values as they are calculated. This block is set up using code like the following:

    [(GPUImageLuminosity *)filter setLuminosityProcessingFinishedBlock:^(CGFloat luminosity, CMTime frameTime) {
         // Do something with the luminosity
       }];
    

    I describe the inner workings of this luminosity extraction in this answer, if you're curious. This extractor runs in ~6 ms for a 640x480 frame of video on an iPhone 4.

    One thing you'll quickly find is that the average luminosity from the iPhone camera is almost always around 50% when automatic exposure is enabled. This means that you'll need to supplement your luminosity measurements with exposure values from the camera metadata to obtain any sort of meaningful brightness measurement.