Swift Playground无法找到已编译CoreML模型(.mlmodelc)求助
在Swift Playgrounds中集成MobileNetV2 CoreML模型时遇到nil解包错误
我已经调试这个问题超过10小时了,尝试在Swift Playgrounds中集成苹果的MobileNetV2 CoreML模型,执行了以下步骤:
- 在常规Xcode项目中编译CoreML模型
- 将编译后的CoreML模型(MobileNetV2.mlmodelc)移动到Swift Playground的Resources文件夹
- 将模型类(MobileNetV2.swift)复制粘贴到Swift Playground的Sources文件夹
- 使用UIImage扩展来调整图片大小并将UIImage转换为CVBuffer
- 实现运行模型的基础代码
但每次运行都会出现错误:
MobileNetV2.swift:100: Fatal error: Unexpectedly found nil while unwrapping an Optional value
该错误来自自动生成的模型类函数:
/// URL of model assuming it was installed in the same bundle as this class class var urlOfModelInThisBundle : URL { let bundle = Bundle(for: self) return bundle.url(forResource: "MobileNetV2", withExtension:"mlmodelc")! }
模型可以正常构建,我的ContentView代码如下:
import SwiftUI struct ContentView: View { func test() -> String{ // 1. 从Resources文件夹加载图片 let newImage = UIImage(named: "img") // 2. 将图片调整为Core ML模型要求的输入尺寸 // 方法来自UIImage+Extension.swift let newSize = CGSize(width: 224, height: 224) guard let resizedImage = newImage?.resizeImageTo(size: newSize) else { fatalError("⚠️ 图片无法找到或调整大小") } // 3. 将调整后的图片转换为CVPixelBuffer,这是Core ML模型要求的输入类型 // 方法来自UIImage+Extension.swift guard let convertedImage = resizedImage.convertToBuffer() else { fatalError("⚠️ 图片无法转换为CVPixelBugger") } // 1. 从Sources文件夹的模型类创建ML模型实例 let mlModel = MobileNetV2() // 2. 获取预测输出 guard let prediction = try? mlModel.prediction(image: convertedImage) else { fatalError("⚠️ 模型无法返回预测结果") } // 3. 检查预测结果 let mostLikelyImageCategory = prediction.classLabel let probabilityOfEachCategory = prediction.classLabelProbs var highestProbability: Double { let probabilty = probabilityOfEachCategory[mostLikelyImageCategory] ?? 0.0 let roundedProbability = (probabilty * 100).rounded(.toNearestOrEven) return roundedProbability } return("\(mostLikelyImageCategory): \(highestProbability)%") } var body: some View { VStack { let _ = print(test()) Image(systemName: "globe") .imageScale(.large) .foregroundColor(.accentColor) Text("Hello, world!") Image(uiImage: UIImage(named: "img")!) } } }
打印我的bundle内容得到:
["_CodeSignature", "metadata.json", "__PlaceholderAppIcon76x76@2x~ipad.png", "Info.plist", "__PlaceholderAppIcon60x60@2x.png", "coremldata.bin", "{App Name}", "PkgInfo", "Assets.car", "embedded.mobileprovision"]
任何帮助都将不胜感激 🙏
作为额外参考,我的ExtImage.swift中的UIImage扩展如下:
// 感谢github用户@mprecke提供的UIImage扩展方法 import Foundation import UIKit extension UIImage { func resizeImageTo(size: CGSize) -> UIImage? { UIGraphicsBeginImageContextWithOptions(size, false, 0.0) self.draw(in: CGRect(origin: CGPoint.zero, size: size)) let resizedImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return resizedImage } func convertToBuffer() -> CVPixelBuffer? { let attributes = [ kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue ] as CFDictionary var pixelBuffer: CVPixelBuffer? let status = CVPixelBufferCreate( kCFAllocatorDefault, Int(self.size.width), Int(self.size.height), kCVPixelFormatType_32ARGB, attributes, &pixelBuffer) guard (status == kCVReturnSuccess) else { return nil } CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0)) let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer!) let rgbColorSpace = CGColorSpaceCreateDeviceRGB() let context = CGContext( data: pixelData, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue) context?.translateBy(x: 0, y: self.size.height) context?.scaleBy(x: 1.0, y: -1.0) UIGraphicsPushContext(context!) self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)) UIGraphicsPopContext() CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0)) return pixelBuffer } }
内容的提问来源于stack exchange,提问作者ColoredOwl
相关产品推荐
相关产品推荐

