我正在SwiftUI中研究一个简单的去噪POC,我想在其中进行:
我根据网上找到的数十种源代码进行工作。根据我所读的内容,CoreML模型(至少是我正在使用的模型)接受CVPixelBuffer并输出CVPixelBuffer。所以我的想法是执行以下操作:
((请注意,我已经阅读了使用Vision框架,可以将CGImage直接输入到模型中。一旦我熟悉我想在这里实现的目标,我就会立即尝试这种方法。这是一个很好的练习。)
首先,我想跳过步骤(2),专注于转换问题。我在下面的代码中尝试实现的是:
我不是Swift或Objective-C开发人员,所以我很确定自己至少犯了一些错误。我发现这段代码相当复杂,我想知道是否有更好/更简单的方法来做同样的事情?
func convert(input: UIImage) -> UIImage? {
// Input CGImage
guard let cgInput = input.cgImage else {
return nil
}
// Image size
let width = cgInput.width
let height = cgInput.height
let region = CGRect(x: 0, y: 0, width: width, height: height)
// Attributes needed to create the CVPixelBuffer
let attributes = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,
kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue]
// Create the input CVPixelBuffer
var pbInput:CVPixelBuffer? = nil
let status = CVPixelBufferCreate(kCFAllocatorDefault,
width,
height,
kCVPixelFormatType_32ARGB,
attributes as CFDictionary,
&pbInput)
// Sanity check
if status != kCVReturnSuccess {
return nil
}
// Fill the input CVPixelBuffer with the content of the input CGImage
CVPixelBufferLockBaseAddress(pbInput!, CVPixelBufferLockFlags(rawValue: 0))
guard let context = CGContext(data: CVPixelBufferGetBaseAddress(pbInput!),
width: width,
height: height,
bitsPerComponent: cgInput.bitsPerComponent,
bytesPerRow: cgInput.bytesPerRow,
space: cgInput.colorSpace!,
bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue) else {
return nil
}
context.draw(cgInput, in: region)
CVPixelBufferUnlockBaseAddress(pbInput!, CVPixelBufferLockFlags(rawValue: 0))
// Create the output CGImage
let ciOutput = CIImage(cvPixelBuffer: pbInput!)
let temporaryContext = CIContext(options: nil)
guard let cgOutput = temporaryContext.createCGImage(ciOutput, from: region) else {
return nil
}
// Create and return the output UIImage
return UIImage(cgImage: cgOutput)
}
当我在SwiftUI项目中使用此代码时,输入和输出图像看起来相同,但不完全相同。我认为输入图像具有与之关联的色图(ColorSync配置文件),在转换期间已丢失。我以为我应该在CGContext创建期间使用cgInput.colorSpace
,但似乎使用CGColorSpace(name: CGColorSpace.sRGB)!
的效果更好。有人可以向我解释一下吗?
感谢您的帮助。
CGImage
对象,但是您必须手动创建MLFeatureValue
对象,然后将其放入MLFeatureProvider
中才能提供给模型。但这仅处理模型输入,而不处理输出。