Getting desired data from a CVPixelBuffer Reference
Asked Answered
C

1

12

I have a program that views a camera input in real-time and gets the color value of the middle pixel. I use a captureOutput: method to grab the CMSampleBuffer from an AVCaptureSession output (which happens to be read as a CVPixelBuffer) and then I grab the rgb values of a pixel using the following code:

// Get a CMSampleBuffer's Core Video image buffer for the media data
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer, 0); 

// Get the number of bytes per row for the pixel buffer
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
// Get the pixel buffer width and height
size_t width = CVPixelBufferGetWidth(imageBuffer); 
size_t height = CVPixelBufferGetHeight(imageBuffer); 
unsigned char* pixel = (unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer);

NSLog(@"Middle pixel: %hhu", pixel[((width*height)*4)/2]);
int red = pixel[(((width*height)*4)/2)+2];
int green = pixel[(((width*height)*4)/2)+1];
int blue = pixel[((width*height)*4)/2];
int alpha = 1;

UIColor *color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha)];

I though that formula ((width*height)*4)/2 would get me the middle pixel, but it gives me the top middle pixel of the image. I am wondering what formula I would need to use to access the pixel in the middle of the screen. I'm kind of stuck because I don't really know the internal structure of these pixel buffers.

In the future I would like to grab the 4 middle pixels and average them for a more accurate color reading, but for now I would just like to get an idea how these things work.

Cowper answered 15/4, 2012 at 15:24 Comment(0)
B
6

The main problem with your formula for locating the middle pixel is that it only works for an uneven number of scan lines. If you have an even number, it picks the first pixel on the scan line just below the middle. That's the middle left pixel. Since the iPhone video frames are rotated by 90 degree, this pixel is in reality the top middle pixel.

So a better formula for locating the middle pixel is:

(height / 2) * bytesPerRow + (width / 2) * 4
Breadnut answered 15/4, 2012 at 18:12 Comment(3)
Yes, the default orientations for the two cameras on the iOS devices is landscape, so if you're doing any portrait-mode work you'll need to deal with a rotated frame.Retail
Curious, why is width part being multiplied by 4?Melicent
Each pixel is 4 bytes. Width is given in number of pixels, not number of bytes.Breadnut

© 2022 - 2024 — McMap. All rights reserved.