以OpenCV Mat格式从相机捕捉静止图像
我正在开发一个iOS应用程序,并尝试使用捕获会话从相机获取静态图像快照,但是我无法将其成功转换为OpenCV Mat。
静止图像输出是使用此代码创build的:
- (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]; }
我需要一种基于缓冲区中的像素数据创buildOpenCV Mat的方法。 我已经尝试使用这个代码,我从OpenCVvideo摄像头类摄像头采取创build一个席子在这里 :
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创build失败。
我知道我可以使用这个代码创build一个基于像素数据的UIImage:
UIImage* newImage = [UIImage imageWithData:jpegData];
但我更喜欢直接构build一个CvMat,就像OpenCV CvVideoCamera类中的情况一样,因为我只想处理OpenCV中的图像,而且我不想再花时间转换,也不会冒险丢失质量或者遇到问题方向(无论如何,由OpenCV提供的UIImagetoCV转换function正在导致我的内存泄漏,而不是释放内存)。
请告诉我如何获得作为OpenCV垫的图像。 提前致谢。
我find了我的问题的解决scheme。
解决scheme是:
通过在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;
您需要使用暂停方法而不是停止方法
- AVPlayer失败,AVPlayerItemStatusFailed(OSStatus错误-12983)
- 我们可以使用语音框架而videoplayback进行?
- 如何在使用图像创buildvideo的同时在图像更改上添加animation
- 使用MPMoviePlayerController无法从video获取多个图像。 OSStatus -12433
- AVAssetWriter如何创build没有压缩的movvideo?
- 在uitableview单元格中播放video
- 如何根据框架在video中设置CATextLayer?
- 如何在IOS中做慢动作video
- CMTime和AVFoundation中的单帧移动