1
以下方案。使用dispatch asnyc在ios上使用openCV实时进行相机馈送处理。这里是捕获sampleBufferMethod将缓冲区转换为IplImage,然后使用它。EXC_BAD_ACCESS问题与dispatch_async使用openCV IPLimage __block
- (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使区别?我错过了什么?自从越快越好,我想摆脱这种说法。
我完全理解你的** __ block **答案,谢谢澄清这一点。问题仍然存在,仍然是同样的错误。任何其他想法? – 2012-02-11 19:38:08
已更新的答案。 – Danra 2012-02-12 07:51:56
是的,这是有道理的,我怀疑这样的事情。所以我想克隆毕竟是一个很好的解决方案。 – 2012-02-12 20:30:58