Question

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 ! =)

Was it helpful?

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.

OTHER TIPS

Why do you place the camera image into an NSArray *dayArray? Five lines later you remove it from that array but treat the object as an NSString. An NSString does not have rgbaPixels. The example you copy-pasted has an array of filenames corresponding to pictures taken at different times of the day. It then opens those image files and performs the analysis of luminosity.

In your case, there is no file to read. Both outer for loops, i.e. on day and i will have to go away. You already got access to the Image provided through the UIImagePickerController. Right after adding the subview, you could in principle access pixels as in unsigned char *pixels = [Image rgbaPixels]; where Image is the image you got from UIImagePickerController.

However, this may not be what you want to do. I imagine that your goal is rather to show the UIImagePickerController in capture mode and then to measure luminosity continuously. To this end, you could turn Image into a member variable, and then access its pixels repeatedly from a timer callback.

You can import below class from GIT to resolve this issue.

https://github.com/maxmuermann/pxl

Add UIImage+Pixels.h & .m files into project. Now try to run.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top