1

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

user1833903
  • 187
  • 3
  • 16

3 Answers3

14

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.

Community
  • 1
  • 1
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • Thank you so much, i'll try to work on your project and answer ! =) – user1833903 Jan 30 '13 at 20:49
  • Just to know, by end, when you say in your "Read me" file : "You'll also need to find the framework headers, so within your project's build settings set the Header Search Paths to the relative path from your application to the framework/ subdirectory within the GPUImage source directory. Make this header search path recursive.", it means that i just have to go to my project build settings and search "Header search path", and add "GPUImage.h" to this no ? Because when i made the next step, #import "GPUImage.h", it said to me that "file was not found", all the previous step are correctly done :/ – user1833903 Jan 30 '13 at 23:21
  • @user1833903 - I took screenshots of this for another open source framework here: http://stackoverflow.com/questions/10260291/installing-core-plot-in-xcode-4-2-for-ios-project/10261140#10261140 , but the same concept applies. You need to add the header search path before you can get the includes to work right. That's all within the build settings, like I show in the linked answer. – Brad Larson Jan 31 '13 at 01:29
  • I try to work for hours on your link, but just have a problem with the header search path. I try a lot of time, but really don't know how to add the framework into header search path. Could you just tell me precisely what i must put into, or mail me ? (i can put my email if you would) – user1833903 Jan 31 '13 at 17:27
  • @user1833903 - I don't know how much more explicit I can get than the screenshots and walkthrough I linked in the above answer. You need to set the relative path from your application project to where you installed the GPUImage framework code. Use ../ to indicate going up one directory level, and then check the box for doing a recursive directory search when you've completely filled out the framework relative path. You need to be precise with this, as even one missing character can cause it to not find the framework headers. – Brad Larson Jan 31 '13 at 23:33
  • That's what i don't understand, because i put .../GPUImage/framework in recursive mode, but don't have any check that appears. I really don't know why and that's the last matter for integrate the framework :/ – user1833903 Feb 01 '13 at 00:18
  • @user1833903 - You probably mean `../GPUImage/framework` there (two dots instead of three at the beginning). Is GPUImage installed in the same directory that contains your project directory, and in a directory named `GPUImage`? That's what this path indicates. You can also look at the sample applications in the `examples` directory to see how I set this up for those test applications. – Brad Larson Feb 01 '13 at 01:31
  • I found how to add the project finally ! An incomprehension because i'm French and didn't really understand the meaning of header paths :s I send you some news, i'll try your framework ! =) – user1833903 Feb 01 '13 at 23:31
0

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.

s.bandara
  • 5,636
  • 1
  • 21
  • 36
  • "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." This is exactly what i want to do, display the luminosity continuously in capture mode. "To this end, you could turn Image into a member variable, and then access its pixels repeatedly from a timer callback." What would you say ? I'm so sorry but i really don'tunderstand how to do this :s – user1833903 Jan 30 '13 at 18:38
  • I think you would be much better off spending some good time learning Cocoa Touch and programming patterns in general. You posted your question after copying and pasting some example code totally out of context. Before moving on, perhaps you should really practice your skills in reading and writing code. Go slowly and make sure you understand every line! – s.bandara Jan 30 '13 at 19:04
  • I don't understand why you say this, i understand cocoa, i have already two apps readies for sale on the apple store, using some stuffs like camera etc, but i have a problem to get the luminance with the camera, like in the example/tutorial that i post behind. I don't know just how to change an image treatement by the camera. That's all... – user1833903 Jan 30 '13 at 20:04
0

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.

Gagan_iOS
  • 3,638
  • 3
  • 32
  • 51