Xcode集成CoreML图像模型报错:No exact matches in call to instance method 'prediction'
问题解决:CoreML调用
prediction方法时的类型不匹配错误 这个错误的核心原因是:你传入的SwiftUI Image类型和CoreML模型DDAMFN的prediction方法要求的输入类型不兼容。SwiftUI的Image是视图组件,不是原始图像数据,CoreML无法直接处理它。
解决步骤及代码示例
1. 先明确模型输入类型
打开你的.mlmodel文件,查看输入参数的类型——图像类CoreML模型通常要求CVPixelBuffer或CGImage格式,而非SwiftUI的Image。
2. 添加图像格式转换工具
需要把SwiftUI Image转换成CoreML支持的CVPixelBuffer,以下是封装好的转换扩展:
import UIKit import SwiftUI import CoreML // SwiftUI Image转UIImage extension Image { var uiImage: UIImage? { let hostingController = UIHostingController(rootView: self) hostingController.view.frame = CGRect(x: 0, y: 0, width: 1, height: 1) return hostingController.view.asImage() } } // UIView转UIImage extension UIView { func asImage() -> UIImage { let renderer = UIGraphicsImageRenderer(bounds: bounds) return renderer.image { context in layer.render(in: context.cgContext) } } } // UIImage转CVPixelBuffer(适配模型要求的112×112尺寸) extension UIImage { func toPixelBuffer(targetSize: CGSize) -> CVPixelBuffer? { let attributes = [ kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue ] as CFDictionary var pixelBuffer: CVPixelBuffer? let status = CVPixelBufferCreate( kCFAllocatorDefault, Int(targetSize.width), Int(targetSize.height), kCVPixelFormatType_32ARGB, attributes, &pixelBuffer ) guard status == kCVReturnSuccess, let buffer = pixelBuffer else { return nil } CVPixelBufferLockBaseAddress(buffer, []) let pixelData = CVPixelBufferGetBaseAddress(buffer) let rgbSpace = CGColorSpaceCreateDeviceRGB() guard let context = CGContext( data: pixelData, width: Int(targetSize.width), height: Int(targetSize.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(buffer), space: rgbSpace, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue ) else { return nil } context.draw(self.cgImage!, in: CGRect(origin: .zero, size: targetSize)) CVPixelBufferUnlockBaseAddress(buffer, []) return buffer } }
3. 修改预测函数,传入正确格式的图像
let testImage: Image = Image("testHappyImage") func testing(image: Image) -> DDAMFNOutput? { do { let config = MLModelConfiguration() let model = try DDAMFN(configuration: config) // 转换为模型要求的112×112尺寸的CVPixelBuffer guard let pixelBuffer = image.uiImage?.toPixelBuffer(targetSize: CGSize(width: 112, height: 112)) else { return nil } // 注意:参数名要和.mlmodel中定义的输入参数名完全一致(比如模型输入叫"image"就用image:pixelBuffer) let prediction = try model.prediction(image: pixelBuffer) return prediction } catch { print("预测失败:\(error)") } return nil }
关键注意点
- 必须保证转换后的图像尺寸和模型要求的112×112完全一致,否则会触发尺寸不匹配的错误。
- 调用
prediction时的参数名要和.mlmodel里输入参数的名称严格对应,比如模型输入参数名为inputImage,就要改成prediction(inputImage: pixelBuffer)。
内容的提问来源于stack exchange,提问作者BriteKnight
相关产品推荐
相关产品推荐

