2014-01-17 2 views
3

Я разрабатываю приложение iOS и пытаюсь получить снимок неподвижного изображения с камеры, используя сеанс захвата, но я не могу успешно преобразовать его в макет OpenCV.Захват неподвижного изображения с камеры в формате OpenCV Mat

Выходной неподвижное изображение создается с помощью этого кода:

- (void)createStillImageOutput; 
{ 
    // setup still image output with jpeg codec 
    self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
    NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil]; 
    [self.stillImageOutput setOutputSettings:outputSettings]; 
    [self.captureSession addOutput:self.stillImageOutput]; 

    for (AVCaptureConnection *connection in self.stillImageOutput.connections) { 
     for (AVCaptureInputPort *port in [connection inputPorts]) { 
      if ([port.mediaType isEqual:AVMediaTypeVideo]) { 
       self.videoCaptureConnection = connection; 
       break; 
      } 
     } 
     if (self.videoCaptureConnection) { 
      break; 
     } 
    } 
    NSLog(@"[Camera] still image output created"); 
} 

А затем пытается захватить неподвижное изображение, используя этот код:

[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:self.videoCaptureConnection 
                completionHandler: 
^(CMSampleBufferRef imageSampleBuffer, NSError *error) 
{ 
    if (error == nil && imageSampleBuffer != NULL) 
    { 
     NSData *jpegData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; 
    } 

Мне нужен способ создания OpenCV Mat на основе на данные пикселя в буфере. я попытался создать коврик, используя этот код, который я взял из OpenCV видео камеры класса камеры here:

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    void* bufferAddress; 
    size_t width; 
    size_t height; 
    size_t bytesPerRow; 

    CGColorSpaceRef colorSpace; 
    CGContextRef context; 

    int format_opencv; 

    OSType format = CVPixelBufferGetPixelFormatType(imageBuffer); 
    if (format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) { 

     format_opencv = CV_8UC1; 

     bufferAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); 
     width = CVPixelBufferGetWidthOfPlane(imageBuffer, 0); 
     height = CVPixelBufferGetHeightOfPlane(imageBuffer, 0); 
     bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0); 

    } else { // expect kCVPixelFormatType_32BGRA 

     format_opencv = CV_8UC4; 

     bufferAddress = CVPixelBufferGetBaseAddress(imageBuffer); 
     width = CVPixelBufferGetWidth(imageBuffer); 
     height = CVPixelBufferGetHeight(imageBuffer); 
     bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 

    } 

    cv::Mat image(height, width, format_opencv, bufferAddress, bytesPerRow); 

, но не может получить фактическую высоту и ширину изображения на CVPixelBufferGetWidth или CVPixelBufferGetHeight вызова и т.д. создание Mat терпит неудачу.

Я знаю, что я могу создать UIImage на основе данных пикселей, используя этот код:

   UIImage* newImage = [UIImage imageWithData:jpegData]; 

Но я предпочитаю, чтобы построить CvMat непосредственно, как это имеет место в классе OpenCV CvVideoCamera, потому что я Я заинтересован в обращении с изображением только в OpenCV, и я не хочу снова тратить время на преобразование и не рисковать потерять качество или иметь проблемы с ориентацией (в любом случае функция UIImagetoCV преобразования, предоставляемая OpenCV, вызывает у меня утечку памяти и не освобождает память).

Пожалуйста, сообщите, как я могу получить изображение в виде макета OpenCV. Спасибо заранее.

ответ

1

Я нашел решение для своей проблемы.

Решение является:

путем переопределения этого метода в классе камеры OpenCV: "createVideoPreviewLayer"

он должен выглядеть следующим образом:

- (void)createVideoPreviewLayer; 
{ 

    self.parentView.layer.sublayers = nil; 
    if (captureVideoPreviewLayer == nil) { 
     captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] 
     initWithSession:self.captureSession]; 
    } 

    if (self.parentView != nil) { 
     captureVideoPreviewLayer.frame = self.parentView.bounds; 
     captureVideoPreviewLayer.videoGravity = 
     AVLayerVideoGravityResizeAspectFill; 
     [self.parentView.layer addSublayer:captureVideoPreviewLayer]; 
    } 
    NSLog(@"[Camera] created AVCaptureVideoPreviewLayer"); 
} 

вы должны добавить эту строку в " createVideoPreviewLayer "решит проблема:

self.parentView.layer.sublayers = nil; 

и вам необходимо использовать метод паузы вместо метода останова

Смежные вопросы