以下场景。使用dispatch asnyc在ios上使用openCV进行实时相机馈送处理。这是捕获将缓冲区转换为 IplImage 然后使用它的 sampleBufferMethod。
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
__block IplImage *image = 0;
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer, 0);
// get information of the image in the buffer
uint8_t *bufferBaseAddress = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
size_t bufferWidth = CVPixelBufferGetWidth(imageBuffer);
size_t bufferHeight = CVPixelBufferGetHeight(imageBuffer);
// create IplImage
if (bufferBaseAddress)
{
image = cvCreateImage(cvSize(bufferWidth, bufferHeight), IPL_DEPTH_8U, 4);
image->imageData = (char*)bufferBaseAddress;
}
// release memory
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
dispatch_async(dispatch_get_main_queue(), ^{
IplImage *out=cvCreateImage(cvSize(568, 320), IPL_DEPTH_8U, 4);
cvResize(image, out, 0);
...
});
}
非常简单,除了这里:
cvResize(image, out, 0);
给我一个 EXC_BAD_ACCESS。我找到了一个解决方法,我发现它永远在玩它:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
IplImage *_image = 0;
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer, 0);
// get information of the image in the buffer
uint8_t *bufferBaseAddress = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
size_t bufferWidth = CVPixelBufferGetWidth(imageBuffer);
size_t bufferHeight = CVPixelBufferGetHeight(imageBuffer);
// create IplImage
if (bufferBaseAddress)
{
_image = cvCreateImage(cvSize(bufferWidth, bufferHeight), IPL_DEPTH_8U, 4);
_image->imageData = (char*)bufferBaseAddress;
}
// release memory
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
__block IplImage *image=cvCloneImage(_image);
dispatch_async(dispatch_get_main_queue(), ^{
IplImage *out=cvCreateImage(cvSize(568, 320), IPL_DEPTH_8U, 4);
cvResize(image, out, 0);
...
});
}
关键线:
__block IplImage *image=cvCloneImage(_image);
所以我不明白为什么 cvCloneImage 会有所作为?我错过了什么?我想摆脱这种说法,因为越快越好。