【发布时间】:2014-02-06 14:24:12
【问题描述】:
我正在开发一个 iOS 应用程序并尝试使用捕获会话从相机获取静止图像快照,但我无法将其成功转换为 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 获取的此代码创建一个 Mat:
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 中处理图像感兴趣,我不想再次花费时间进行转换,也不想冒丢失质量或有方向问题(无论如何,OpenCV 提供的 UIImagetoCV 转换功能导致我内存泄漏并且没有释放内存)。
请告知如何将图像作为 OpenCV Mat 获取。 提前致谢。
【问题讨论】:
标签: ios opencv avfoundation