【发布时间】:2021-07-25 14:03:33
【问题描述】:
在我的应用程序中,我使用 VNImageRequestHandler 和自定义 MLModel 进行对象检测。
该应用在 14.5 之前的 iOS 版本上运行良好。
当 iOS 14.5 到来时,它打破了一切。
- 每当
try handler.perform([visionRequest])抛出一个错误(Error Domain=com.apple.vis Code=11 "encountered unknown exception" UserInfo={NSLocalizedDescription=encountered unknown exception}),pixelBuffer内存被持有并且永远不会被释放,它使 AVCaptureOutput 的缓冲区已满,然后新帧未到来。 - 我必须更改代码如下,通过将pixelBuffer复制到另一个var,我解决了新帧不来的问题,但仍然发生内存泄漏问题。
由于内存泄漏,应用程序在一段时间后崩溃了。
请注意,在 iOS 14.5 版本之前,检测工作正常,try handler.perform([visionRequest]) 永远不会抛出任何错误。
这是我的代码:
private func predictWithPixelBuffer(sampleBuffer: CMSampleBuffer) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
// Get additional info from the camera.
var options: [VNImageOption : Any] = [:]
if let cameraIntrinsicMatrix = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil) {
options[.cameraIntrinsics] = cameraIntrinsicMatrix
}
autoreleasepool {
// Because of iOS 14.5, there is a bug that when perform vision request failed, pixel buffer memory leaked so the AVCaptureOutput buffers is full, it will not output new frame any more, this is a temporary work around to copy pixel buffer to a new buffer, this currently make the memory increased a lot also. Need to find a better way
var clonePixelBuffer: CVPixelBuffer? = pixelBuffer.copy()
let handler = VNImageRequestHandler(cvPixelBuffer: clonePixelBuffer!, orientation: orientation, options: options)
print("[DEBUG] detecting...")
do {
try handler.perform([visionRequest])
} catch {
delegate?.detector(didOutputBoundingBox: [])
failedCount += 1
print("[DEBUG] detect failed \(failedCount)")
print("Failed to perform Vision request: \(error)")
}
clonePixelBuffer = nil
}
}
有没有人遇到过同样的问题?如果是这样,您是如何解决的?
【问题讨论】:
-
Apple 回复了我的错误报告并要求我提供更多信息。我附上了源代码 + 你的 github 错误报告供他们检查。希望他们能尽快修复它。
-
我有 3 个自定义对象检测模型,转换代码遵循 MachineThink 博客中的@MatthijsHollemans 模板。两个模型可以识别 791 个类别,并且是 SSDLite,使用 MobileNet v2 和 v3L 作为特征提取器,它们都存在上述问题。但是,我有一个基于 SSDLIte+MobileNetv3L 识别单个类的 SSDLite 模型,它工作得很好。如果我从管道中删除 NMS 模型,所有 3 个版本都可以正常工作。问题似乎是多类非最大抑制
-
@James 感谢您提供的信息。请注意,可以将管道中的 NMS 模型替换为包含单个 NMS 层的神经网络模型。我很想知道这是否有效。如果没有,GitHub 上的 CoreMLHelpers 有一个 Swift 版本的 NMS,您可以调整它以使用该模型。
-
@RB's: 我的模型现在有 1 个班级,问题已经解决,也许你可以试试你的情况
-
@MatthijsHollemans 在我看来,我创建的任何 NMS 实现都有不受支持的 CoreML 操作。无论我尝试使用内置的
tf.image.combined_non_max_suppression还是创建自己的 TF 版本。我将测试 CoreMLHelpers 的快速实现(谢谢!),我唯一关心的是速度,但我可以进行基准测试
标签: ios memory-leaks ios14 coreml ios-vision