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

直接调用CoreML出现图像格式不支持错误,求解决方案

问题

使用基于YOLO且自带NMS输出的检测器,直接调用CoreML时触发错误:

Image is not expected type 32BGRA or 32ARGB, instead is Unsupported (875704422)

即使不对图像做裁剪操作,同样会触发该错误。但用Apple官方的Vision框架处理相同输入却没有问题。由于需要自定义特定区域裁剪,且CoreML代码逻辑更易理解,希望保留CoreML调用方式,求解决办法。

CoreML调用出错代码:

do {
    // 基于CoreMLHelpers封装的自定义工具类
    // 不裁剪直接传图也会报错
    let inSize = CVPixelBuffer.Size(width: 1280, height: 640)
    let crop = CVPixelBuffer.Rect(x: 0, y: 0, width: inSize.width, height: inSize.height)
    if var buffer = self.preparedBuffer, buffer.size == inSize {
        imageBuffer.crop(rect: crop, outPixelBuffer: &buffer)
    } else {
        self.preparedBuffer = imageBuffer.crop(rect: crop, outSize: inSize)
    }
    
    let out = try model.prediction(image: self.preparedBuffer!, iouThreshold: 0.4, confidenceThreshold: 0.25)
    //..
} catch {
    NSLog("Detector error: \(error)")
}

Vision框架无错误调用代码:

let imageRequestHandler = VNImageRequestHandler(cmSampleBuffer: buffer, orientation: vOrientation)
解决方案

核心原因

Vision框架会自动处理像素格式转换,但直接调用CoreML时需要严格匹配模型要求的像素格式(32BGRA或32ARGB),自定义裁剪工具输出的CVPixelBuffer格式不满足要求。

具体修复步骤

  • 强制转换像素格式
    在将CVPixelBuffer传入CoreML模型前,把它转换成32BGRA格式。示例代码如下:

    // 将buffer转换为32BGRA格式的工具方法
    func convertTo32BGRA(from buffer: CVPixelBuffer) -> CVPixelBuffer? {
        let attributes: [CFString: Any] = [
            kCVPixelBufferCGImageCompatibilityKey: true,
            kCVPixelBufferCGBitmapContextCompatibilityKey: true,
            kCVPixelBufferPixelFormatTypeKey: kCVPixelFormatType_32BGRA
        ]
        
        var convertedBuffer: CVPixelBuffer?
        let status = CVPixelBufferCreate(
            nil,
            CVPixelBufferGetWidth(buffer),
            CVPixelBufferGetHeight(buffer),
            kCVPixelFormatType_32BGRA,
            attributes as CFDictionary,
            &convertedBuffer
        )
        
        guard status == kCVReturnSuccess, let destBuffer = convertedBuffer else {
            return nil
        }
        
        CVPixelBufferLockBaseAddress(buffer, .readOnly)
        CVPixelBufferLockBaseAddress(destBuffer, .readWrite)
        
        defer {
            CVPixelBufferUnlockBaseAddress(buffer, .readOnly)
            CVPixelBufferUnlockBaseAddress(destBuffer, .readWrite)
        }
        
        let sourceData = CVPixelBufferGetBaseAddress(buffer)
        let destData = CVPixelBufferGetBaseAddress(destBuffer)
        let bytesPerRow = CVPixelBufferGetBytesPerRow(buffer)
        let height = CVPixelBufferGetHeight(buffer)
        
        memcpy(destData, sourceData, bytesPerRow * height)
        return destBuffer
    }
    

    在调用model.prediction前加入转换逻辑:

    guard let convertedBuffer = convertTo32BGRA(from: self.preparedBuffer!) else {
        // 处理转换失败情况
        return
    }
    let out = try model.prediction(image: convertedBuffer, iouThreshold: 0.4, confidenceThreshold: 0.25)
    
  • 修改裁剪工具的输出格式
    调整自定义crop方法的逻辑,让它直接输出32BGRA格式的CVPixelBuffer,避免额外的格式转换步骤。比如在创建裁剪后的buffer时,指定像素格式为kCVPixelFormatType_32BGRA。

  • 验证模型输入要求
    用Xcode的模型检查器打开CoreML模型,确认输入图像的像素格式要求是否为32BGRA或32ARGB,避免格式匹配偏差。

内容的提问来源于stack exchange,提问作者Gralex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:55:22