c++iosavfoundationstdopenalpr

How to convert CMSampleBuffer to std::vector<char>?


I have image stream from my AVCaptureVideoDataOutputSampleBufferDelegate method:

- (void)captureOutput:(AVCaptureOutput )captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection )connection;


Then I want to take sampleBuffer and provide it for C++ openalrp library to recognize which takes image bytes or raw pixel data. What function should I use and how to convert sampleBuffer to suitable input type, std::vector<char> or unsigned char* pixelData?

From alpr.h file:

  // Recognize from an image on disk
  AlprResults recognize(std::string filepath);

  // Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc).
  AlprResults recognize(std::vector<char> imageBytes);

  // Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc).
  AlprResults recognize(std::vector<char> imageBytes, std::vector<AlprRegionOfInterest> regionsOfInterest);

  // Recognize from raw pixel data.  
  AlprResults recognize(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector<AlprRegionOfInterest> regionsOfInterest);

Solution

  • Finally, I've found the answer:

    CVPixelBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer, 0);
    unsigned char *tempAddress = (unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
    CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef newContext = CGBitmapContextCreate(tempAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    CGImageRef newImage = CGBitmapContextCreateImage(newContext);
    CGContextRelease(newContext);
    CGColorSpaceRelease(colorSpace);
    UIImage *image = [UIImage imageWithCGImage:newImage];
    
    NSData *data = UIImagePNGRepresentation(image);
    
    if (data) {
        unsigned long int len = data.length;
        std::vector<char> v((char *)data.bytes, (char *)data.bytes + len);
        alpr::AlprResults results = delegate->recognize(v);
    }
    
    CGImageRelease(newImage);