Search code examples
iphoneopencvuiimageaugmented-realitybuffering

How to use UIImage with ARToolKitPlus? (UIImage to CVImageBufferRef conversion)


I have two algorithms, that detects AR markers (ARToolKit and Infi). I have them working on iPhone in real time detecting markers. At this stage i would like to compare their speed and accuracy. I would like to prepare a series of images and test recognition on them. I can do that with infi, but i can't manage to use ARToolKit with UIImage.

ARToolKit uses CVImageBuffer to recognize markers:

- (Marker *)detectMarkerInImageBuffer:(CVImageBufferRef)imageBuffer {

    /*We lock the buffer and get the address of the first pixel*/
    CVPixelBufferLockBaseAddress(imageBuffer,0);
    unsigned char *baseAddress = (unsigned char *) CVPixelBufferGetBaseAddress(imageBuffer);
    tracker->calc(baseAddress);

How can I use/convert UIImage to achieve baseAddress, so i can send it to tracker->calc ?

With infi I first create IplImage from buffer or convert UIImage to IplImage and then in both cases:

Buffer* buffer = new Buffer();

buffer->setBuffer( (unsigned char *) iplImg->imageData, iplImg->width, iplImg->height);

Solution

  • I found an answer here: How do I export UIImage array as a movie?

    That is what i was looking for

    - (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
    {
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
            [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
            [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
            nil];
        CVPixelBufferRef pxbuffer = NULL;
        CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width,
            frameSize.height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) options, 
            &pxbuffer);
        NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
    
        CVPixelBufferLockBaseAddress(pxbuffer, 0);
        void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
        NSParameterAssert(pxdata != NULL);
    
        CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
        CGContextRef context = CGBitmapContextCreate(pxdata, frameSize.width,
            frameSize.height, 8, 4*frameSize.width, rgbColorSpace, 
            kCGImageAlphaNoneSkipFirst);
        NSParameterAssert(context);
        CGContextConcatCTM(context, frameTransform);
        CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
            CGImageGetHeight(image)), image);
        CGColorSpaceRelease(rgbColorSpace);
        CGContextRelease(context);
    
        CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
    
        return pxbuffer;
    }