2017-08-17 7 views
0

Nous utilisons AVCaptureDevice sur IOS pour scanner des codes QR. Nous passons la sortie de la caméra en utilisant AVCaptureMetadataOutput au code pour reconnaître le code QR, et actuellement nous affichons également la caméra comme vue séparée sur notre vue Open GL. Cependant, nous voulons maintenant que d'autres graphiques apparaissent sur l'aperçu de la caméra, nous aimerions donc pouvoir charger les données de la caméra sur l'une de nos textures Open GL.Téléchargement de données de caméra IOS brutes à une texture

Alors, est-il un moyen d'obtenir les données RVB brutes de la caméra

Ceci est le code (ci-dessous) nous utilisons pour initialiser le dispositif de capture et des vues. Comment pouvons-nous modifier cela pour accéder aux données RVB afin que nous puissions le charger sur l'une de nos textures GL? Nous utilisons C++/Objective C

Merci

Shaun Southern

self.captureSession = [[AVCaptureSession alloc] init]; 

NSError *error; 
// Set camera capture device to default and the media type to video. 
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
// Set video capture input: If there a problem initialising the camera, it will give am error. 
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error]; 

if (!input) 
{ 
    NSLog(@"Error Getting Camera Input"); 
    return; 
} 
// Adding input souce for capture session. i.e., Camera 
[self.captureSession addInput:input]; 

AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init]; 
// Set output to capture session. Initalising an output object we will use later. 
[self.captureSession addOutput:captureMetadataOutput]; 

// Create a new queue and set delegate for metadata objects scanned. 
dispatch_queue_t dispatchQueue; 
dispatchQueue = dispatch_queue_create("scanQueue", NULL); 
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; 

// Delegate should implement captureOutput:didOutputMetadataObjects:fromConnection: to get callbacks on detected metadata. 
[captureMetadataOutput setMetadataObjectTypes:[captureMetadataOutput availableMetadataObjectTypes]]; 

// Layer that will display what the camera is capturing. 

self.captureLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession]; 
[self.captureLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 

gCameraPreviewView= [[[UIView alloc] initWithFrame:CGRectMake(gCamX1, gCamY1, gCamX2-gCamX1, gCamY2-gCamY1)] retain]; 
[self.captureLayer setFrame:gCameraPreviewView.layer.bounds]; 
[gCameraPreviewView.layer addSublayer:self.captureLayer]; 

UIViewController * lVC = [[[UIApplication sharedApplication] keyWindow] rootViewController]; 
[lVC.view addSubview:gCameraPreviewView]; 

Répondre

1

Vous n'avez pas besoin d'accéder directement à des cadres de la caméra rgb pour le rendre comme une texture parce que IOS prend en charge un cache de texture est plus rapide que toi.

- (void) writeSampleBuffer:(CMSampleBufferRef)sampleBuffer ofType:(NSString *)mediaType pixel:(CVImageBufferRef)cameraFrame time:(CMTime)frameTime; 

dans la méthode de rappel, vous pouvez générer la texture en utilisant les paramètres et les fonctions ci-dessous

CVOpenGLESTextureCacheCreate(...) 
    CVOpenGLESTextureCacheCreateTextureFromImage(...) 
0

En fin de compte, nous avons converti du CMSampleBuffer aux données brutes (afin que nous puissions télécharger une texture GL) comme ça. Cela prend un peu de temps mais était assez rapide pour nos objectifs.

S'il y a des améliorations, je serais heureux de savoir :)

shaun

- (void)captureOutput:(AVCaptureFileOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection; 
{ 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer]; 

    if(!self.context) 
    { 
     self.context = [CIContext contextWithOptions:nil]; //only create this once  
    } 

    int xsize= CVPixelBufferGetWidth(imageBuffer); 
    int ysize= CVPixelBufferGetHeight(imageBuffer); 

    CGImageRef videoImage = [self.context createCGImage:ciImage fromRect:CGRectMake(0, 0, xsize, ysize)];   
    UIImage *image = [[UIImage alloc] initWithCGImage:videoImage]; 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    if(!colorSpace) 
    { 
     return ; 
    } 

    size_t bitsPerPixel = 32; 
    size_t bitsPerComponent = 8; 
    size_t bytesPerPixel = bitsPerPixel/bitsPerComponent; 
    size_t bytesPerRow = xsize * bytesPerPixel; 
    size_t bufferLength = bytesPerRow * ysize; 
    uint32_t * tempbitmapData = (uint32_t *)malloc(bufferLength); 

    if(!tempbitmapData) 
    { 
     CGColorSpaceRelease(colorSpace); 
     return ; 
    } 

    CGContextRef cgcontext = CGBitmapContextCreate(tempbitmapData, xsize, ysize, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);  
    if(!cgcontext) 
    { 
     free(tempbitmapData); 
     return; 
    } 

    CGColorSpaceRelease(colorSpace); 
    CGRect rect = CGRectMake(0, 0, xsize, ysize); 
    CGContextDrawImage(cgcontext, rect, image.CGImage);         
    unsigned char *bitmapData = (unsigned char *)CGBitmapContextGetData(cgcontext);  // Get a pointer to the data  
    CGContextRelease(cgcontext);               
    [image release]; 

    CallbackWithData((unsigned int *)bitmapData,xsize,ysize);    //send data 

    free(bitmapData); 
    CGImageRelease(videoImage); 
}