You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中使用Vision框架调用CoreML模型时,如何获取MLMultiArray类型输出

Swift中使用Vision框架调用CoreML模型时,如何获取MLMultiArray类型输出

嘿,兄弟,我刚好碰到过一模一样的问题!你现在的问题出在没有正确识别Vision返回的观测对象类型——普通的VNObservation是个基类,根本装不下你的CoreML模型输出的MLMultiArray,你需要的是它的子类VNCoreMLFeatureValueObservation,这才是真正存储模型特征输出的对象。

直接给你修正核心代码,把你原来的VNCoreMLRequest回调部分换成下面这段:

let request = VNCoreMLRequest(model: model) { finishReq, err in
    // 第一步:把结果转换成正确的VNCoreMLFeatureValueObservation数组
    guard let results = finishReq.results as? [VNCoreMLFeatureValueObservation] else {
        print("无法解析模型输出结果")
        return
    }
    
    // 第二步:取第一个观测结果(如果你的模型只有一个输出的话)
    guard let coreMLResult = results.first else {
        print("模型没有返回任何结果")
        return
    }
    
    // 第三步:从特征值中提取MLMultiArray
    guard let mlMultiArray = coreMLResult.featureValue.multiArrayValue else {
        print("无法将特征值转换为MLMultiArray格式")
        return
    }
    
    // 到这里你就成功拿到MLMultiArray了!接下来把它赋值给你的currentMLArray
    self.currentMLArray = mlMultiArray
    
    // 顺便把你的绘图逻辑移到这里来,确保拿到数据后再执行
    DispatchQueue.main.async { [weak self] in
        guard let self = self, let mlArray = self.currentMLArray else { return }
        let aWidth = CGFloat(mlArray.shape[0].intValue)
        let aHeight = CGFloat(mlArray.shape[1].intValue)
        
        UIGraphicsBeginImageContext(CGSize(width: aWidth, height: aHeight))
        guard let ctx = UIGraphicsGetCurrentContext() else { 
            UIGraphicsEndImageContext()
            return 
        }
        
        ctx.clear(CGRect(x: 0.0, y: 0.0, width: Double(aWidth), height: Double(aHeight)))
        
        for j in 0..<Int(aHeight) {
            for i in 0..<Int(aWidth) {
                let aValue = (mlArray[j * Int(aHeight) + i].floatValue >= 0.5) ? 1.0 : 0.0
                let aRect = CGRect(x: CGFloat(i), y: CGFloat(j), width: 1.0, height: 1.0)
                let aColor = UIColor(displayP3Red: 0.0, green: 0.0, blue: 0.0, alpha: CGFloat(aValue))
                aColor.setFill()
                UIRectFill(aRect)
            }
        }
        
        if let anImage = UIGraphicsGetImageFromCurrentImageContext() {
            self.imageView.image = anImage
        }
        UIGraphicsEndImageContext()
    }
}

给你划几个重点:

  • 类型转换要准确:必须把finishReq.results转换成[VNCoreMLFeatureValueObservation],这样才能访问到featureValue属性
  • 提取MultiArray:通过featureValue.multiArrayValue就能直接拿到你需要的MLMultiArray对象
  • 线程注意:绘图操作一定要放到主队列执行,不然会崩溃
  • 安全校验:每一步都加guard判断,避免因为空值导致程序崩溃

另外,你原来的代码里把绘图逻辑放在了perform方法外面,这会导致currentMLArray还没被赋值就执行,肯定拿不到数据,所以我把绘图逻辑移到了回调里面,确保拿到MLMultiArray后再执行。

这样改完应该就能正常获取并使用MLMultiArray了!

备注:内容来源于stack exchange,提问作者jasoninthecloud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 11:58:04