iPhone video output setting YUV or BGR CVImageBufferRef to IplImage [Code snippet]

  • We are going to publish a series of posts with some useful code snippets for iOS and Android.

Any suggestion or contributions are welcomed ;)

Here we show how to get and IplImage from CVImageBufferRef or CMSampleBufferGetImageBuffer with the output video set to:

kCVPixelFormatType_32BGRA or

kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange or

kCVPixelFormatType_420YpCbCr8BiPlanarFullRange

Here we go:

- (IplImage *)createIplImageFromBuffer:(CVImageBufferRef)imageBuffer 
                                        withChannels:(int)channels {

    IplImage *iplimage = 0;
    if (imageBuffer) {
        // From CMSampleBufferGetImageBuffer:
        // CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        // lock buffer
        CVPixelBufferLockBaseAddress(imageBuffer, 0);
        // get buffer's image information
        uint8_t *bufferBaseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
        size_t bufferWidth = CVPixelBufferGetWidth(imageBuffer);
        size_t bufferHeight = CVPixelBufferGetHeight(imageBuffer);
        size_t bufferBytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
        // create IplImage
        if (bufferBaseAddress) {
            iplimage = cvCreateImage(cvSize(bufferWidth, bufferHeight), IPL_DEPTH_8U, channels);
        }
        // from YUV  - 1 channel (grey image)
        // from BGRA - 4 channels (colourful image)
        if(channels == 4)
        {
            vImage_Buffer src;
            src.width = bufferWidth;
            src.height = bufferHeight;
            src.rowBytes = bufferBytesPerRow;
            src.data = bufferBaseAddress;
            vImage_Buffer dest;
            dest.height = bufferHeight;
            dest.width = bufferWidth;
            dest.rowBytes = bufferBytesPerRow;
            dest.data = iplimage->imageData;
            // swap the pixel channels from BGRA to RGBA.
            const uint8_t map[4] = { 2, 1, 0, 3 };
            vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
        }else
        {
            iplimage->imageData = (char*)bufferBaseAddress;
        }
        // unlock buffer
        CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
    }
    else
        NSLog(@"No sampleBuffer!!");
    return iplimage;
}

Do not forget to check out our AR Browser and Image Matching SDKs.

Tags: , ,
Posted on: No Comments

Leave a Reply