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