gpt4 book ai didi

ios - 使用 openCV IPLimage __block 的 dispatch_async 出现 EXC_BAD_ACCESS 问题

转载 作者:太空宇宙 更新时间:2023-11-03 22:34:58 25 4
gpt4 key购买 nike

以下场景。使用 dispatch asnyc 在 ios 上使用 openCV 进行实时相机馈送处理。这是捕获 sampleBufferMethod,它将缓冲区转换为 IplImage,然后使用它。

- (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 会有所不同?我错过了什么?我想摆脱这种说法,因为越快越好。

最佳答案

如果没有您的解决方法,imageBuffer 可能在 block 执行时无效。您是从框架外部获取它的,AFAIK 在您的处理程序完成后没有关于其持续生命周期的 promise 。因此你应该复制它。因此,您的克隆可以使代码正常工作。

另一个问题是访问在方法的栈帧中分配的内存。

您应该从 image 中删除 __block 声明 - 否则 block 将传递一个指向 image指针 struct 指针,而不仅仅是一个副本。由于结构指针是在堆栈上分配的,因此当您的 block 运行时,它之前所在的内存不再有效。

关于ios - 使用 openCV IPLimage __block 的 dispatch_async 出现 EXC_BAD_ACCESS 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9241854/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com