2012-11-27 3 views
3

MonoTouch에서 실시간 비디오 이미지 처리를 시도하고 있습니다. AVCaptureSession을 사용하여 AVCaptureVideoPreviewLayer와 함께 작동하는 카메라의 프레임을 가져옵니다.AVCaptureSession을 사용하여 CMSampleBuffer에서 UIImage를 가져 오는 방법

또한 위임 클래스에서 "DidOutputSampleBuffer"콜백 메서드를 성공적으로 가져 왔습니다. 그러나 모든 방식으로 UIImage 결과 CMSampleBuffer에서 만들려고했는데 실패합니다. CVPixelBuffer은과 같이 샘플 버퍼의 이미지 버퍼에서 주조에서 나는 CGBitmapContext을 만드는 시도

captureSession = new AVCaptureSession(); 
      captureSession.BeginConfiguration(); 
      videoCamera = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Video); 

      if (videoCamera != null) 
      { 
       captureSession.SessionPreset = AVCaptureSession.Preset1280x720; 

       videoInput = AVCaptureDeviceInput.FromDevice (videoCamera); 

       if (videoInput != null) 
        captureSession.AddInput (videoInput); 

       //DispatchQueue queue = new DispatchQueue ("videoFrameQueue"); 

       videoCapDelegate = new videoOutputDelegate (this); 

       DispatchQueue queue = new DispatchQueue("videoFrameQueue"); 
       videoOutput = new AVCaptureVideoDataOutput(); 

       videoOutput.SetSampleBufferDelegateAndQueue (videoCapDelegate, queue); 
       videoOutput.AlwaysDiscardsLateVideoFrames = true; 
       videoOutput.VideoSettings.PixelFormat = CVPixelFormatType.CV24RGB; 

       captureSession.AddOutput (videoOutput); 

       videoOutput.ConnectionFromMediaType(AVMediaType.Video).VideoOrientation = AVCaptureVideoOrientation.Portrait; 

       previewLayer = AVCaptureVideoPreviewLayer.FromSession (captureSession); 
       previewLayer.Frame = UIScreen.MainScreen.Bounds; 
       previewLayer.AffineTransform = CGAffineTransform.MakeRotation (Convert.DegToRad (-90)); 
       //this.View.Layer.AddSublayer (previewLayer); 

       captureSession.CommitConfiguration(); 
       captureSession.StartRunning(); 
      } 

:

public override void DidOutputSampleBuffer (AVCaptureOutput captureOutput, MonoTouch.CoreMedia.CMSampleBuffer sampleBuffer, AVCaptureConnection connection) 
    { 

     CVPixelBuffer pixelBuffer = sampleBuffer.GetImageBuffer() as CVPixelBuffer; 
     CVReturn flag = pixelBuffer.Lock (0); 
     if(flag == CVReturn.Success) 
     { 
      CGBitmapContext context = new CGBitmapContext 
        (
         pixelBuffer.BaseAddress, 
         pixelBuffer.Width, 
         pixelBuffer.Height, 
         8, 
         pixelBuffer.BytesPerRow, 
         CGColorSpace.CreateDeviceRGB(), 
         CGImageAlphaInfo.PremultipliedFirst 
         ); 

      UIImage image = new UIImage(context.ToImage()); 

      ProcessImage (image); 

      pixelBuffer.Unlock(0); 

     }else 
      Debug.Print(flag.ToString() 

     sampleBuffer.Dispose(); 
    } 

이 결과 여기

내 코드는 캡처 세션을 설정하는 것입니다 다음 오류

<Error>: CGBitmapContextCreate: invalid data bytes/row: should be at least 2880 for 8 integer bits/component, 3 components, kCGImageAlphaPremultipliedFirst. 

매개 변수를 약간 조정하더라도 ers 나는 네이티브 objective-c에서 유효하지 않은 Handle 예외 나 segfault를 얻는다.

나는 또한 단순히 CVImageBuffer와 CIImage을 만드는 시도하고과 같이 그에서있는 UIImage를 생성 한

:

public override void DidOutputSampleBuffer (AVCaptureOutput captureOutput, MonoTouch.CoreMedia.CMSampleBuffer sampleBuffer, AVCaptureConnection connection) 
    { 

     CIImage cImage = new CIImage(sampleBuffer.GetImageBuffer()); 
     UIImage image = new UIImage(cImage); 
     ProcessImage (image); 

     sampleBuffer.Dispose(); 
    } 

CIImage 초기화 할 때이 예외가 발생합니다 정직

NSInvalidArgumentException Reason: -[CIImage initWithCVImageBuffer:]: unrecognized selector sent to instance 0xc821d0 

이를 MonoTouch에 어떤 종류의 버그가 있다고 생각하지만, 뭔가를 놓치고 있거나 이상한 방법으로이 작업을하려고하는 경우 몇 가지 대안 솔루션을 알려 주시기 바랍니다.

감사

+0

정확하게 CGBitmapContext 생성자에 대한 호출에 대한 숫자 값은 무엇입니까? 아이폰 5 pixelBuffer를 사용 –

+0

의 값은 다음과 같습니다 폭 : 720 높이 : 행 당 1280 바이트 : 1084 당신은 다른 형식이 A A CVPixelBuffer에 대한 CGBitmapContext을 만들기 위해 노력하고 –

+0

. 행 당 1084 바이트 및 폭 720은 픽셀 당 1.5 바이트 이상의 비트를 제공합니다. 그것은 RGB24가 아닙니다. 아마 평면 포맷 일 것입니다. 그래서 CVPixelBuffer의 픽셀 포맷은 무엇입니까? –

답변

3

이 오류 메시지를 설명한다 : 픽셀 당 1.5 바이트 이상 조금 720 개 픽셀 행 당 1,084 바이트 폭

<Error>: CGBitmapContextCreate: invalid data bytes/row: should be at least 2880 for 8 integer bits/component, 3 components, kCGImageAlphaPremultipliedFirst. 

- (그것은 RGB24 아니다 어느 픽셀 당 3 바이트), 평면 형식입니다.

더 쉽게 사용할 수있는 지원되는 형식이 있는지 알아보기 위해 사용할 수있는 픽셀 형식을 확인하려면 AVCaptureVideoDataOutput.AvailableVideoCVPixelFormatTypes을 확인하십시오.

+0

AvailableVideoCVPixelFormatTypes에 포함 된 픽셀 형식 형식을 설정하더라도 관계없이 CV420YpCbCr8BiPlanarVideoRange로 출력되는 것으로 보입니다. –

+0

저와 같은 다른 AVFoundation 놈의 경우 카메라 캡처 해상도가 kCVPixelBufferWidthKey 및 kCVPixelBufferHeightKeys와 일치하지 않기 때문에이 오류가 발생할 수 있습니다. – user3344977

관련 문제