Swift 关于UIImage的问题->;CVPixelBuffer->;图像转换

Swift 关于UIImage的问题->;CVPixelBuffer->;图像转换,swift,uiimage,coreml,cvpixelbuffer,Swift,Uiimage,Coreml,Cvpixelbuffer,我正在SwiftUI中开发一个简单的去噪POC,我想: 加载输入图像 对输入图像应用CoreML模型(去噪) 显示输出图像 我在网上找到了几十个源代码,我有了一些可以工作的东西。根据我读到的内容,CoreML模型(至少是我正在使用的模型)接受CVPixelBuffer并输出CVPixelBuffer。所以我的想法是做以下几点: 将输入UIImage转换为CVPixelBuffer 将CoreML模型应用于CVPixelBuffer 将新创建的CVPixelBuffer转换为UIImage (请注

我正在SwiftUI中开发一个简单的去噪POC,我想:

  • 加载输入图像
  • 对输入图像应用CoreML模型(去噪)
  • 显示输出图像
  • 我在网上找到了几十个源代码,我有了一些可以工作的东西。根据我读到的内容,CoreML模型(至少是我正在使用的模型)接受CVPixelBuffer并输出CVPixelBuffer。所以我的想法是做以下几点:

  • 将输入UIImage转换为CVPixelBuffer
  • 将CoreML模型应用于CVPixelBuffer
  • 将新创建的CVPixelBuffer转换为UIImage
  • (请注意,我已经读到使用Vision框架,可以将CGImage直接输入模型中。一旦我熟悉我在这里要实现的目标,我将尝试这种方法,因为我认为这是一个很好的练习。)

    首先,我想跳过步骤(2)来关注转换问题。我试图在下面的代码中实现的是:

  • 将输入UIImage转换为CVPixelBuffer
  • 将CVPixelBuffer转换为UIImage
  • 我不是Swift或Objective-C开发人员,所以我很确定我至少犯了一些错误。我发现这段代码相当复杂,我想知道是否有更好/更简单的方法来做同样的事情

    func转换(输入:UIImage)->UIImage?{
    //输入CGImage
    保护让cgInput=input.cgImage else{
    归零
    }
    //图像大小
    let width=cgInput.width
    让高度=cgInput.height
    let region=CGRect(x:0,y:0,width:width,height:height)
    //创建CVPixelBuffer所需的属性
    let attributes=[kCVPixelBufferCGImageCompatibilityKey:kCFBooleanTrue,
    kCVPixelBufferCGBitmapContextCompatibilityKey:kCFBooleanTrue]
    //创建输入像素缓冲区
    变量pbInput:CVPixelBuffer?=nil
    让状态=CVPixelBufferCreate(kCFAllocatorDefault,
    宽度,
    高度,
    kCVPixelFormatType_32ARGB,
    属性作为CFDictionary,
    &(输入)
    //健康检查
    如果状态!=kCVReturnSuccess{
    归零
    }
    //用输入CGImage的内容填充输入CVPixelBuffer
    CVPixelBufferLockBaseAddress(pbInput!,CVPixelBufferLockFlags(rawValue:0))
    guard let context=CGContext(数据:CVPixelBufferGetBaseAddress(pbInput!),
    宽度:宽度,
    高度:高度,,
    bitsPerComponent:cgInput.bitsPerComponent,
    bytesPerRow:cgInput.bytesPerRow,
    空格:cgInput.colorSpace!,
    bitmapInfo:CGImageAlphaInfo.noneSkipFirst.rawValue)其他{
    归零
    }
    绘制(cgInput,in:region)
    CVPixelBufferUnlockBaseAddress(pbInput!,CVPixelBufferLockFlags(rawValue:0))
    //创建输出图像
    让ciOutput=CIImage(cvPixelBuffer:pbInput!)
    让temporaryContext=CIContext(选项:nil)
    guard let cgOutput=temporaryContext.createCGImage(ciOutput,from:region)else{
    归零
    }
    //创建并返回输出UIImage
    返回UIImage(cgImage:cgOutput)
    }
    
    当我在我的SwiftUI项目中使用此代码时,输入和输出图像看起来是一样的,但并不完全相同。我认为输入图像有一个与之关联的colormap(ColorSync配置文件),它在转换过程中丢失了。我假设我应该在CGContext创建期间使用
    cgInput.colorSpace
    ,但似乎使用
    CGColorSpace(名称:CGColorSpace.sRGB)工作得更好。谁能给我解释一下吗


    感谢您的帮助。

    您也可以将
    CGImage
    对象与Core ML一起使用,但您必须手动创建
    MLFeatureValue
    对象,然后将其放入
    MLFeatureProvider
    中,以将其提供给模型。但这只考虑模型输入,而不是输出


    另一种选择是使用my repo中的代码。

    谢谢您的回答。我将尝试一下,因为它可能会简化我的代码,特别是
    CGImage
    CVPixelBuffer
    的转换。但在任何情况下,我都必须处理从CVPixelBuffer到UIImage的转换。这非常简单:
    let image=UIImage(ciImage:ciImage(CVPixelBuffer:pixelBuffer))
    。出于某种原因,
    let image=UIImage(ciImage:ciImage(CVPixelBuffer:pixelBuffer))
    不起作用。我必须使用
    CIContext
    ,然后使用
    createCGImage
    使它工作。但我真的对我的代码没有信心。这就是我写这篇文章的原因。很抱歉不够精确。“不工作”是指我的输出图像是完全白色的。我想我一定是做错了什么。你的意思是你总是得到一个完全白色的图像?在这种情况下,我将尝试从Python运行该模型,以查看得到的结果。